GCVE-1988-2026-0507
Vulnerability from gna-1988 – Published: 2026-11-02 07:30 – Updated: 2026-11-02 07:30{
"containers": {
"cna": {
"affected": [
{
"product": "Rax120",
"vendor": "Netgear",
"versions": [
{
"status": "affected",
"version": "unknown"
}
]
}
],
"credits": [
{
"lang": "en",
"type": "finder",
"value": "disclosure via Fulldisclosure"
}
],
"descriptions": [
{
"lang": "en",
"value": "0day Rubbish Research Team is publicly disclosing a vulnerability in NETGEAR\nRAX120 (Nighthawk AX12) firmware V1.2.5.18, the WiFi 6 consumer router from\nNETGEAR (United States), built on the Qualcomm IPQ8074 platform. The\nadministrative web plane of this firmware generation is a lighttpd server\nfronting the vendor\u0027s DNI-framework CGI handler /usr/sbin/net-cgi (an\naarch64, musl, stripped image; the handler binary measures 1,042,120 bytes\nand its recorded image digest begins d7035dd3), and the SOAP control plane\ndispatches every action through /soap/server_XMLresp.cgi. Among those\nactions is the app-installation control InstallApp of the service\nurn:NETGEAR-ROUTER:service:AppSystem:1, which requires the router\nadministrator\u0027s session.\n\nType and root cause. OS command injection (CWE-78 primary, with CWE-20\nco-equal for the blocklist-style improper input validation, and CWE-426\nrecorded as contributing without raising any metric). The operation takes a\nNewAppName argument and passes it through a blocklist validator whose\n\"apname\" mode (the routine at fcn.000407d8 in the stripped image, mode\nstring at 0xc3058) rejects six characters chosen with shell injection in\nmind: the at-sign, the backtick, the semicolon, the double quote, the\nsingle quote and the backslash. That set covers the classic\nstatement-separator and quote-context breakouts. It does not reject the\ndollar sign or either parenthesis, which are the entire grammar of command\nsubstitution. The handler then embeds the validated name, unquoted, into two\nworking paths (/tmp/\u003cname\u003e_tmp and /sw-apps/\u003cname\u003e, both built by direct\nsnprintf interpolation) and then into three shell command lines:\n\n system(\"rm -rf /sw-apps/\u003cname\u003e/version.txt \u003e /dev/console\")\n system(\"rm -rf /sw-apps/\u003cname\u003e \u003e /dev/console\")\n popen(\"rm -rf /tmp/\u003cname\u003e_tmp; mkdir /tmp/\u003cname\u003e_tmp;\n tar -zxf /tmp/\u003ctarball\u003e -C /tmp/\u003cname\u003e_tmp\", \"r\")\n\nEach sink executes through /bin/sh -c, so a second parse happens inside a\nshell the validator never modeled. A name of the shape x$(cmd) substitutes\nattacker-chosen command text before the rm words ever run, and the shell\u0027s\nparser walks the whole command line with a substitution pass before\nexecuting any word of it, so the injected command fires whether or not the\nsurrounding rm errors out. An intermediate string processor in the handler\nwalk (recorded at fcn.00079060) rewrites carriage returns and line feeds to\nspaces and performs no other transformation, so no downstream mitigation\nexists: the dollar sign, pipe, ampersand and every other metacharacter pass\nuntouched. Two gates sit ahead of the validator, a 255-character length cap\non the name and a value gate on the companion NewUpdate element, and both\nare compatible with the payload, which is under 30 characters.\n\nExecution identity. system() and popen() children inherit the identity of\nthe web stack that calls them, and the research record identifies, from the\nfirmware image\u0027s own lighttpd configuration, the server\u0027s configured\nruntime user as root, so command text supplied through this handler\ninherits device-root authority by product configuration. The dynamic\nverification measured exactly that identity in a sink-level replication:\nmarkers carrying uid=0(root) gid=0(root) groups=0(root) from all three\nvectors, and none from a benign control name.\n\nAuthentication, credited plainly. This is not an unauthenticated finding\nand no unauthenticated variant of it is claimed. The gate is identified from\nthe artifacts as the administrative SOAP login bound to the requesting\nstation\u0027s MAC address, failing closed; the chain consumes a legitimate\nadministrator session and neither bypasses nor forges it. It is also not a\ndefault-credential finding: the same request succeeds whatever the\nadministrator password is. No second web-account tier with reach into this\nservice exists in any artifact examined, which is what fixes Privileges\nRequired at High. The product gets the gate right and the argument\nconstruction wrong; this is a CWE-78/CWE-20 defect, not CWE-306 and not\nCWE-862.\n\nWhy this handler and not a hundred others. The DNI framework also contains\nan exec helper (recorded at fcn.000779f0) that runs commands through\nvfork() plus execve() with an argument vector, architecturally immune to\nshell injection, and large parts of the firmware use it. A census of the\nshell-mediated remainder classified on the order of 150+ system() sites,\nalmost all of them fixed string constants loaded by address arithmetic with\nno substitution, and about 54 popen() sites. The app-installation handler\nis the single family in the analysed image that interpolates an\nattacker-controlled SOAP argument into a shell command line, so the defect\nis one handler rather than a platform-wide sloppy pattern.\n\nThe sibling platform. The same root cause was confirmed on the NETGEAR\nR7800 (Nighthawk X4S), firmware V1.0.2.68: a different SoC generation\n(Broadcom BCM4709), a different instruction set (32-bit ARM), a different\nhandler binary (recorded digest beginning c5a9f2b3) and a different\nvalidator function whose reject set is only the double quote, the single\nquote and the backslash, which is strictly more permissive than the main\nmodel\u0027s six. The identical x$(cmd) payload passed that validator and\nexecuted through the same handler family in that platform\u0027s own sink-level\nreplication, with three root markers of its own and a clean control. The\nmerge is argued at the level of root cause, not build identity, and the\nplatform differences are stated rather than smoothed over. Other models\nshipping this framework\u0027s app-system code were not audited, and the vendor\u0027s\nolder R6700/R7000/R8000 generation runs a different self-built httpd lineage\nthat does not contain this handler, so no claim is made about it.\n\nVerification boundary, stated in full, because it defines what is and is not\nbeing claimed. No physical router was driven during verification and no\nlive SOAP request was fired at device hardware, at any point, in any phase\nof this work. The request path, the session gate and the parameter\nextraction are established at disassembly level from the shipped image. The\ninjection behaviour at the sink is established by a sink-level replication:\non an isolated cloud-hosted sandbox, a natively compiled C program\nre-implemented the disassembled validator logic, the CRLF-normalising string\nprocessor and all three command constructions, run with the root privilege\nmodel the image\u0027s lighttpd configuration records for the web stack. Three\nvectors, one per sink, each carrying x$(id\u003e/tmp/\u003cmarker\u003e) through the\nreplicated validator and construction, each produced a marker containing\nuid=0(root) gid=0(root) groups=0(root); a benign control name traversing\nthe identical code path produced none. The control is the load-bearing\nnegative: it makes the marker creation attributable to the substitution\ncontent alone, not to the surrounding construction or the harness. Not\nperformed and not claimed: any end-to-end HTTP round trip against device\nhardware, any cross-station or cross-network detonation, any persistence\nmechanism, any radio-firmware or hardware-adjacent effect, and any memory\ncorruption. There is none in the chain, which is metacharacter-class gap\nand nothing else. The landing-identity mapping rests on the image\u0027s own\nconfiguration artifact read as text, not on a live-device observation.\n\nScoring. One score is published: 6.8 Medium,\nCVSS:3.1/AV:A/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H. The arithmetic is printed so\nany reader can reproduce it under the CVSS 3.1 base algorithm and its\nround-up-to-the-tenth rule: ISS = 1 - (0.44 x 0.44 x 0.44) = 0.914816;\nImpact for Scope Unchanged = 6.42 x 0.914816 = 5.873119; Exploitability =\n8.22 x 0.62 (adjacent) x 0.77 x 0.27 x 0.85 = 0.900610; sum = 6.773729;\nRoundup = 6.8. Attack Vector is Adjacent because the SOAP control plane\nbelongs to the router\u0027s local administrative service and no shipped\nartifact examined establishes that the action answers on the wide-area side\nof an unmodified deployment; the reading is argued from the product\u0027s\ntransport and the recovered session model, not demonstrated between two\nhosts.\n\nTwo alternative readings are published, each labelled. A conditional\nreading at 7.2 High (CVSS:3.1/AV:N/AC:L/PR:H/UI:N/S:U/C:H/I:H/A:H, from\nExploitability 1.234708 and sum 7.107827) applies where the management\nplane is deliberately exposed beyond the adjacent network, by enabled\nremote administration, by a port forward directed at the SOAP responder, or\nby a management relay; it is conditional on a deployment choice this\nresearch did not measure, and it is not the headline. Two further readings\nare published as rejected with their arithmetic: a hypothetical\nlower-privilege web tier at PR:L computes to 8.8 with AV:N (Exploitability\n2.835255, sum 8.708374) and to 8.0 with AV:A, and both are rejected because\nthe app-installation control plane is administrator-only on this firmware\nand no artifact documents a secondary account class with web access to this\nservice, so no principal exists to justify Low privileges.\n\nOne correction to the researchers\u0027 own record is published rather than\nquietly made. The internal research ledger behind this advisory carried 8.8\nfor this chain. Recomputation rejects it: 8.8 is the arithmetic of the same\nimpact profile read at Low privilege, and the documented chain requires the\ndevice administrator, so no vector supported by this evidence computes to\nthe recorded figure. The published score is 6.8, computed from the vector,\nwith the discrepancy recorded in the advisory rather than silently\noverwritten, because a number that was quietly changed is a number nobody\ndownstream can audit. Correcting it lowered the published figure.\n\nImpact. Command execution as the root-configured web stack, from a position\nof an administrator credential the holder was never meant to convert into an\noperating-system shell. Concretely: the complete configuration store\nincluding credentials retained by the firmware; creation or modification of\naccounts, startup scripts and scheduled tasks within the writable\nfilesystem; reconfiguration of interfaces, routes and the DNS resolver the\nLAN depends on; redirection or observation of LAN traffic according to the\nplatform\u0027s own capabilities, turning the network\u0027s chokepoint device into an\ninterior attack position; and degradation of service at will, including\nthrough the very rm -rf constructions this chain lives in. The chain is\nsilent in product terms: one authenticated POST inside a legitimate\nmanagement action, with no log-relevant traffic pattern beyond ordinary\napp-management use. Persistence was not tested and is not claimed; what\nsurvives a factory reset or reflash was not tested and is not claimed.\n\nMitigation summary: replace the blocklist with an allowlist for the\napplication name, [A-Za-z0-9][A-Za-z0-9._-]* with the existing length cap;\nstop interpolating the name into shell command lines at all, implementing\ncleanup, directory creation and extraction with unlink(), mkdir() and\nargument-array execve()-family calls or the framework\u0027s own exec helper,\nwhich closes the class for every caller pattern rather than enumerating\ntoday\u0027s metacharacters; if a shell-based implementation must survive one\nrelease cycle, single-quote every interpolated value with literal\nsingle-quote escaping and assert post-construction that the compiled\ncommand contains no dollar sign, failing the request otherwise; drop\nweb-stack privileges so lighttpd and its CGI handlers run as a dedicated\nnon-root identity; patch the sibling model in the same pass, its validator\nbeing strictly more permissive, with one cross-model regression test\nsubmitting $(true) as an application name and asserting no shell-out; adopt\na build rule failing the release on any system() or popen() site that\ninterpolates request data, rather than another manual audit of on the order\nof 54 popen() sites in one binary; and for operators until a patch ships,\nkeep the manag"
}
],
"problemTypes": [
{
"descriptions": [
{
"cweId": "CWE-20",
"description": "CWE-20",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-306",
"description": "CWE-306",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-426",
"description": "CWE-426",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-78",
"description": "CWE-78",
"lang": "en",
"type": "CWE"
},
{
"cweId": "CWE-862",
"description": "CWE-862",
"lang": "en",
"type": "CWE"
}
]
}
],
"providerMetadata": {
"dateUpdated": "2026-11-02T07:30:04Z",
"orgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"shortName": "VULNARCHIVE"
},
"references": [
{
"tags": [
"technical-description",
"exploit"
],
"url": "https://vuln.freearchive.org/archive/full-disclosure/2026/Oct/57"
},
{
"tags": [
"technical-description"
],
"url": "https://seclists.org/fulldisclosure/2026/Oct/57"
},
{
"url": "https://0day-rubbish.com"
},
{
"url": "https://0day-rubbish.com/blog/soap-installapp-apname-command-injection-root-rce"
},
{
"url": "https://github.com/Exploit-Garbage/0day-Rubbish"
},
{
"url": "https://nmap.org/mailman/listinfo/fulldisclosure"
},
{
"url": "https://seclists.org/fulldisclosure/"
}
],
"source": {
"defect": [
"https://seclists.org/fulldisclosure/2026/Oct/57"
],
"discovery": "EXTERNAL"
},
"title": "[0day-rubbish] NETGEAR RAX120 V1.2.5.18 authenticated SOAP InstallApp OS command injection to root-configured web-stack execution (6.8 Medium; conditionally 7.2 High with management exposure)",
"x_gcve": [
{
"recordType": "advisory",
"relationships": [],
"vulnId": "GCVE-1988-2026-0507",
"x_vulnarchive": {
"archiveUrl": "https://vuln.freearchive.org/archive/full-disclosure/2026/Oct/57",
"automated": true,
"contentSha256": "3775d80dede37755e77055c1feaf401d4676226713e2707af3c2b8df6e4b3b6d",
"evidenceScore": 11,
"messageId": "",
"originalUrl": "https://seclists.org/fulldisclosure/2026/Oct/57",
"policy": "vulnarchive-1",
"sourceFormat": "text/html",
"sourcePublishedAt": "2026-10-27T16:39:59Z"
}
}
]
}
},
"cveMetadata": {
"assignerOrgId": "4e2abfbf-4a2a-4b76-a4e0-d77c18ba156c",
"assignerShortName": "VULNARCHIVE",
"datePublished": "2026-11-02T07:30:04Z",
"dateUpdated": "2026-11-02T07:30:04Z",
"state": "PUBLISHED",
"vulnId": "GCVE-1988-2026-0507"
},
"dataType": "CVE_RECORD",
"dataVersion": "5.2"
}
Drag nodes to arrange them. Double-click a related vulnerability to open it, or a source to visit its link. The Physics button on the left tunes the layout and the simulation; the legend at the bottom left hides or shows nodes by kind and by sighting type.
Sightings
| Author | Source | Type | Date | Other |
|---|
Nomenclature
- Seen: The vulnerability was mentioned, discussed, or observed by the user.
- Confirmed: The vulnerability has been validated from an analyst's perspective.
- Published Proof of Concept: A public proof of concept is available for this vulnerability.
- Exploited: The vulnerability was observed as exploited by the user who reported the sighting.
- Patched: The vulnerability was observed as successfully patched by the user who reported the sighting.
- Not exploited: The vulnerability was not observed as exploited by the user who reported the sighting.
- Not confirmed: The user expressed doubt about the validity of the vulnerability.
- Not patched: The vulnerability was not observed as successfully patched by the user who reported the sighting.
Vulnerability timeline
Sightings and recorded dates, grouped by day · UTC
How durations are calculated
Following the VTEM framework (Black Hat USA 2015), time to patch starts when the vendor or a coordinator was informed, total time to patch at discovery, and disclosure to patch at public disclosure; vendor response time runs from the report to its acknowledgement. Time to exploit and time unpatched start at the earliest discovery or report, falling back to public disclosure. Unpatched time ends at the first recorded patch, or the calculation time when no patch is recorded. Exploitation to patch shows the interval between those two events; a published proof of concept is a public exploit, not exploitation.
Each result shows its source dates. A negative interval means the end event came first; when date-only inputs leave the order open, the result says so. Date-only inputs are approximate. The earliest evidence wins: KEV report dates and sightings are labelled as such. Records describing another vulnerability are listed but never calculated from, and a PoC alone does not establish exploitation. Missing patch evidence does not prove that no patch exists. Filters below change the event list only.
Loading timeline…
The approach is described in our paper Mapping CVEs to MITRE ATT&CK Techniques: A Curated Gold-Set Classifier and the Limits of LLM-Assisted Label Expansion.
Browse all ATT&CK techniques and the vulnerabilities related to each.
Related by attack behaviour
Vulnerabilities whose description is nearest to this one in the vector space of the CIRCL/vulnerability-attack-technique-biencoder model. This is a similarity search over the bi-encoder space (plain cosine), not a classification, and it has no measured accuracy.