-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 NEFARIOUSPLAN-CANONICAL-V1 {"body_md":"## The scanner sends one hundred and thirty requests. The first three reach the alarm.\n\nThe script's core is a doubly nested loop:\n\n```python\nsensitive_paths = [\n \"/+CSCOE+/portal.html\",\n \"/+CSCOE+/logon.html\",\n \"/+CSCOE+/sessions.html\", # Active sessions (very sensitive)\n \"/+CSCOE+/files/file_list.html\", # File listing\n \"/+CSCOE+/files/file_action.html\",\n \"/+CSCOE+/custom.html\",\n \"/+CSCOE+/file.php\",\n \"/+CSCOT+/session.html\",\n # Configuration / dump related (common in exploitation)\n \"/+CSCOE+/config\",\n \"/+CSCOE+/running-config\", # Sometimes exposed\n \"/+CSCOE+/showrunning\",\n \"/+CSCOE+/download\",\n \"/+CSCOE+/backup\",\n]\n\nbypass_patterns = [\n \"\",\n \"/..\",\n \"/../\",\n \"/+CSCOE+/../+CSCOE+/\",\n \"/%2bCSCOE%2b/../%2bCSCOE%2b/\",\n \"/+CSCOE+/..;/\",\n \"/+CSCOE+/%2e%2e/\",\n \"/+CSCOE+/%2e%2e%2f\",\n \"/..%2f+CSCOE+/\",\n \"/+CSCOU+/\",\n]\n```\n\nThirteen base paths, ten bypass patterns, one hundred and thirty constructed URLs per target. For each request the script reads `status_code` and `len(text)` and applies one test:\n\n```python\nif status == 200 and length > 800:\n lower_text = r.text.lower()\n if any(kw in lower_text for kw in [\"session\", \"webvpn\", \"config\", \"username\", \"password\", \"cscoe\", \"anyconnect\", \"running-config\"]):\n print(f\" ⚠️ SENSITIVE CONTENT DETECTED!\")\n vulnerable_count += 1\n sensitive_hits.append((test_url, status, length))\n```\n\nTwo responses meeting the test produce the final verdict:\n\n```python\nif vulnerable_count >= 2:\n print(\"\\n🚨 HIGH RISK: Target appears VULNERABLE to CVE-2025-20362\")\n print(\" Sensitive files / configuration data are accessible without authentication!\")\n print(\" Immediate action required: Patch + investigate compromise.\")\n```\n\nThe first entry in the bypass list is the empty string. With `bypass = \"\"`, the constructed URL is `base_url + base_path` with nothing appended. No path traversal is attempted. The request is a direct fetch of the base path. The outer loop's first thirteen iterations are unmodified requests for the thirteen restricted paths the script considers sensitive.\n\nCisco's WebVPN ships `/+CSCOE+/logon.html` as the public-facing SSL VPN logon page. That page exists to be reached without authentication; the entire point of the URL is to render a form that AnyConnect or browser clients submit credentials through. The HTML body is several kilobytes. The body contains the strings `webvpn`, `CSCOE`, and `AnyConnect` because Cisco's portal references its own product names in form actions, JavaScript paths, and language-pack URLs. The script's keyword list, lowercased, matches each of those.\n\n`requests.get(..., allow_redirects=True)` follows the redirects that ASA returns for authenticated-only paths. A request to `/+CSCOE+/portal.html` from an unauthenticated client lands on `/+CSCOE+/logon.html`. A request to `/+CSCOE+/sessions.html` from an unauthenticated client lands on `/+CSCOE+/logon.html`. The terminal body the script reads, in those redirect cases, is the logon page. The terminal status is 200. The terminal body length is above 800. The terminal text contains `webvpn`.\n\nThe first iteration of the outer loop that produces a 200 with the logon page in its body increments `vulnerable_count` to one. The second produces the threshold. The script prints the HIGH RISK banner. The next one hundred and twenty-eight requests are decoration; the verdict was set before any of the bypass patterns the README calls \"the core of CVE-2025-20362\" were exercised.\n\n## The detection signal is the product\n\nThe script flags every Cisco WebVPN appliance that serves its logon page as HIGH RISK for CVE-2025-20362, regardless of software version. A 9.20.4.7 box patched against the September 2025 advisory and current with the November 2025 follow-on fixes serves `/+CSCOE+/logon.html` for the same reason a 9.16.2 box does: because WebVPN is the SSL VPN portal product, and the logon page is the portal's entry point. The script cannot tell those two boxes apart. Its positive signal is reachability of the public portal, which is the precondition for using the product, not the consequence of the bug.\n\nThe keyword list does not narrow the test. `webvpn`, `cscoe`, `anyconnect`, `session`, `config`, `username`, `password`, `running-config`. These are the words Cisco's portal HTML contains by design. A patched appliance does not stop referencing its own product names in its public-facing pages. The script's threshold could in principle be set so that only bypassed responses (a successful traversal returning content from an authenticated endpoint with words like `running-config` in a configuration dump) would trigger. The threshold is not set that way. The threshold is two or more responses containing `webvpn`. Every WebVPN deployment meets it.\n\nA defender running this scanner against a fleet of Cisco ASA appliances sees HIGH RISK on every appliance with WebVPN enabled. A defender running the scanner against a freshly-patched appliance to verify their work sees HIGH RISK. The verdict the script returns does not depend on whether the bypass succeeded. The verdict depends on whether the appliance answered the door.\n\n## What CVE-2025-20362 actually is\n\nCisco's advisory describes the bug as improper validation of user-supplied input in HTTP(S) requests against the WebVPN web server, leading to access of restricted URL endpoints that should be gated behind authentication. The CWE assignment on NVD is CWE-862, missing authorization. The CVSS vector is `AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:L/A:N`: network-reachable, no privileges required, low confidentiality and integrity impact, no availability impact under the original vector.\n\nThe 5 November 2025 advisory update adds a separate exploitation primitive against the same input-validation gap: the gap can be coerced into crashing the device, escalating the impact past the original CVSS vector. The KEV entry's federal civilian remediation deadline lapsed in October 2025. The in-wild campaign chains CVE-2025-20362's missing-authorization with CVE-2025-20333's input-validation flaw in the same web server to reach root execution on the appliance. Cisco's continued-attacks resource documents the variant timeline; CISA, the UK NCSC, and Australian and Canadian government partners have published joint advisories about the cluster.\n\nThe mechanism the in-wild exploit uses is documented in those advisories at a level of detail Cisco's product disclosure deliberately stops short of reproducing in the CVE record itself. That mechanism is not what the curtishoughton scanner is testing. The ten bypass patterns the script ships, `/..`, `/../`, URL-encoded `%2e%2e` variants, `..;/`, `/+CSCOU+/`, are the standard list of web-server path-traversal probes that appears in every introductory exploitation tutorial. Whether any of them maps to the specific normalization fault Cisco's patch closed is not asked; the script's HIGH RISK verdict has already fired on the logon page by the time the loop reaches them.\n\n## A third shape of CVE-shaped wrapper\n\nWe named the Placeholder PoC shape in the InSAT MasterSCADA case earlier this week: a script published under a CVE the publisher did not discover, structured as a working exploit, with the critical parameter explicitly admitted in a comment to be a guess. The publisher had no field name, so they wrote `command` and added `# placeholder field` next to it. The same week, the [Cisco SD-WAN Bitcoin paywall](/posts/cisco-cve-2026-20182-the-exploit-is-a-bitcoin-address) case landed a sibling defect: a CVE-named repository that contained no exploit code at all, only a README pointing at a 0.00693 BTC SatoshiDisk listing. Different authors, different products, identical effect on the public exploit-availability surface: a CVE-shaped wrapper without the primitive inside.\n\nThe curtishoughton CVE-2025-20362 scanner is a third shape under the same Placeholder PoC name. The repository is not behind a paywall. The author's GitHub profile does not attempt portfolio inflation. The script is, in its README's framing, \"a safe, non-destructive Python scanner\" offered to defenders \"to assess exposure on systems they are authorized to test.\" The defect is not a placeholder field admitted in a comment or an exploit hidden behind a payment link. The defect is in the detection threshold: the test that decides whether to print HIGH RISK is a test the product passes by existing.\n\nThe Placeholder PoC catalogue grows because the underlying incentive structure is stable. A CVE under remediation pressure (KEV listing, government joint advisory, recurring vendor updates) generates inbound search traffic on GitHub. Any repository whose name matches the CVE number receives that traffic. The repository's value to its author, whether the author is selling Bitcoin paywalls, building a personal brand, or sincerely trying to help defenders, depends only on the name matching. A scanner pipeline that registers \"PoC available\" on the existence of a CVE-named repository registers all three shapes identically. The InSAT script lacks a field. The Cisco SD-WAN repository lacks code. The curtishoughton scanner lacks a primitive the threshold could distinguish from the product. None of the three contain what a defender treating \"PoC available\" as actionable would assume they contain.\n\n## What the scanner promotes itself to do\n\nThe script's README closes with a section called \"Vulnerability Details\" that lists CVE-2025-20362's severity, type, affected products, and the chained CVE-2025-20333 RCE. The same README markets the artifact as a tool to assess WebVPN exposure on authorized systems. The script's terminal output, when run against any Cisco WebVPN appliance, is the eleven-line block beginning with `🚨 HIGH RISK: Target appears VULNERABLE to CVE-2025-20362` and ending with `Immediate action required: Patch + investigate compromise.`\n\nA defender pasting that block into a ticketing system, a compliance report, or an executive summary is passing along an authority the script does not have. The script has the authority to confirm that the target appliance responded to HTTP requests with content that mentions `webvpn`. It does not have the authority to claim that the target is vulnerable to a specific CWE-862 normalization fault. The block conflates the two. Defenders working a CISA-deadline-driven patch queue without time to read the source of every CVE-named scanner they download from GitHub are exactly the audience that this output is most actionable against, and least useful for.\n\nThe two-hundred-thirty-three days between Cisco's advisory and this script's publication contain three vendor updates, an in-wild attack-variant disclosure, KEV inclusion, and joint government attribution to a specific threat actor cluster. None of that work is reproduced inside the script. What is inside the script is a list of paths every Cisco WebVPN appliance serves and a keyword list every Cisco WebVPN appliance's HTML contains.\n\nPoC: [curtishoughton/CVE-2025-20362-Cisco-Scanner](https://github.com/curtishoughton/CVE-2025-20362-Cisco-Scanner)","closing_line":"The threshold is the product. The product is not the bug.","hook_md":"CVE-2025-20362 was published by Cisco on 25 September 2025 as advisory `cisco-sa-asaftd-webvpn-YROOTUW`. The bug is a missing-authorization fault in the VPN web server of Cisco Secure Firewall ASA and Cisco Secure Firewall Threat Defense; an unauthenticated remote attacker reaches restricted URL endpoints that the WebVPN handler should gate behind login. CISA added the entry to the Known Exploited Vulnerabilities Catalog the same week. On 5 November 2025 Cisco updated the advisory with a new in-the-wild attack variant that crashes unpatched devices, escalating the bug from credential exposure to denial of service. Two-hundred-thirty-three days after the advisory, the most recent public GitHub repository carrying the CVE number was created. It calls itself a `safe scanner`. The detection threshold for its `HIGH RISK` verdict fires on every Cisco WebVPN appliance that answers the door, patched or not.","post_id":313,"slug":"cisco-asa-cve-2025-20362-scanner-detects-the-logon-page","title":"CVE-2025-20362: The Scanner Flags Every Cisco WebVPN That Serves Its Logon Page","type":"initial","unreadable_sentence":"The threshold is the product. The product is not the bug."} -----BEGIN PGP SIGNATURE----- iHUEARYIAB0WIQRf0htP5+SjynlxywneZjl4jgkQJgUCahSXTgAKCRDeZjl4jgkQ Jgv5AQD3NP3Ggpk7XsofPp88yBSjU6qQ/pL10T/UsgGx1RGikgEAvhhFfoQiaVrv Qq2LRJQMdUmOOdc7hCjka/joboCCzAk= =fHbg -----END PGP SIGNATURE-----