Insufficient Upload Filtering in ampache/ampache
Reported on
Dec 5th 2022
Description
The upload filter in Ampache 5.5.5 is insufficient and does not prevent authenticated users from uploading files with malicious extensions, which can lead to remote code execution (RCE) depending on the local server configuration.
This vulnerability assumes several things (which has been taken into account for the CVSS score):
1 - A default configuration of Ampache
2 - A dummy user test
with normal user permissions (every account with the ability to change the profile picture for example will work)
3 - A non default configuration value: album_art_store_disk = "true"
(default = "false"
) in ampache.cfg.php
4 - A non default configuration value: locate_metadata_dir = "/var/www/html"
(default = none
) in ampache.cfg.php
The mentioned configuration values allow the vendor to store images and songs (etc.) on disk instead of in the database. The administrator may choose any location accessible by the web-user for the storage directory, but should that path also be accessible via the browser any authenticated user may trigger remote code execution, see PoC.
Proof of Concept
Prepare a malicious profile picture by hiding a payload in the PLTE chunk: (the technique is described here)
<?php
$_payload="<?php phpinfo()?> ";
$_pay_len=strlen($_payload);
$width=$_pay_len/3;
$height=20;
$im = imagecreate($width, $height);
$_hex=unpack('H*',$_payload);
$_chunks=str_split($_hex[1], 6);
for($i=0; $i < count($_chunks); $i++){
$_color_chunks=str_split($_chunks[$i], 2);
$color=imagecolorallocate($im,hexdec($_color_chunks[0]),hexdec($_color_chunks[1]),hexdec($_color_chunks[2]));
imagesetpixel($im,$i,1,$color);
}
imagepng($im,"profile.php");
Login as the dummy user, go to the profile settings and upload the malicious profile picture. Upon saving the profile, the image should render as weird blob.
The default location for the stored image will now be <HOST>/user/<user-id>/default/art-original.php
where the <user-id>
is an integer (admin = 1, next user created = 2, etc.). Upon requesting the uploaded file in the browser, the php code is executed.
Details
In src/Repository/Model/User.php
line 1443, update_avatar()
is called with the uploaded file and no sanitization checks on the extension. The file is then later processed in src/Repository/Model/Art.php
where in line 351 it is checked whether it is a valid image. However, the extension is ignored at all times up to the point where the file is written in line 445 (write_to_dir()
).
To mitigate the root issue (any extension is allowed) I would advise to implement an extension whitelist, possibly in the insert()
function in Art.php
.
Impact
This vulnerability may lead to remote code execution. However, this is rather unlikely due to the fact that a vendor would probably be aware of the potential danger when an upload directory is exposed to the user. Still, there should at least be a warning in the configuration about the possible implications for this setting. At the very least any authenticated user can upload files with dangerous extensions.
Using CVSS v3.1 the following vector was determined: AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N. Marking the AC as high to compensate for the necessary preconditions for successful exploitation.
I'm 50/50 on this one, it does require a bad admin but also allows a regular user to execute things they shouldn't if they've made a bad choice regardless or permissions.
I think i'll put a check on the upload_avatar function for image extensions that we allow