# A Series of Unauthenticated Events: Chained Exploitation of Ivanti Connect Secure Zero-Days

UTA0576 chained an ICS welcome.cgi auth bypass, a wu.cgi upload race RCE, and a dsinvoked DSCache privesc to gain unauthenticated root on Ivanti VPN appliances.

- Payout: Real-world hack
- Severity: critical
- Program: Ivanti
- Analysis by: Steven Adair
- Disclosed: 2026-10-13
- CVE: CVE-2026-104935
- Write-up quality: 9/10
- Original: https://www.volexity.com/blog/2026/10/13/a-series-of-unauthenticated-events-chained-exploitation-of-ivanti-connect-secure-zero-days/
- Library page: https://bugbountylibrary.com/r/blog%3Avolexity-com-blog-2026-10-13-a-series-of-unauthenticated-events-chained-exploitation-of-ivanti-connect-secure-zero-days
- Tags: area:devices domain:network impact:data-leak impact:privesc impact:rce kind:incident platform:threat-intel sev:critical technique:chained technique:race-window vuln:auth-bypass vuln:path-traversal vuln:privilege-escalation vuln:race-condition vuln:rce

**Target:** Ivanti Connect Secure VPN appliance CGI handlers (welcome.cgi, wu.cgi) and dsinvoked service
**Root cause:** welcome.cgi authorizes on the URL path but routes on the X-DSCGI-PATH header, letting unauthenticated requests reach protected CGI. wu.cgi writes uploads to disk before ZIP validation, creating an execute-before-delete race; dsinvoked trusts in-memory DSCache task config for root execution.
**Steps:**
1. Send request to `/dana-na/auth/url_default/welcome.cgi` with header `X-DSCGI-PATH: /home/webserver/htdocs/dana/fb/smb/wu.cgi` to reach protected wu.cgi unauthenticated
2. Upload a Perl script named with a `.zip` extension; handler writes to `/home/runtime/tmp/<MD5(filename)>` before ZIP validation deletes it
3. In parallel, send requests with `X-DSCGI-PATH: /home/runtime/tmp/<MD5(filename)>` to execute the script during the write-delete race window
4. From cgi-server context, patch in-memory `/home/lib/libdsplibs.so` to modify DSCache and repoint a maintenance task to the Perl interpreter
5. Invoke dsinvoked to run the task with a malicious Perl script argument, executing as root; verify by reading `/etc/shadow`
6. Restore DSCache entry and libdsplibs.so, then truncate `/home/runtime/dlogs/debuglog` and `/var/log/audit/audit.log` to remove evidence
**How found:** Volexity investigated suspected malicious activity at an NSM customer, traced root cause to a fully patched ICS appliance, and reconstructed the chain from core dumps and memory images after the actor deleted debug and audit logs.
**Exploitation:** Each command re-runs the full chain: auth bypass via header/URL mismatch, race-condition upload+execute of a Perl->Bash->base64/zlib Python stager held only in memory, then DSCache privesc to root. Commands and results pass through the exploit's HTTPS requests, no web shell. Post-exploitation: LDAP queries for LAPS/BitLocker/userPassword attributes, Kerberoast tooling, LDAP pcap parsing for plaintext creds and NTLM hashes, password spraying, config/log exfiltration.
**Escalation:** Chained three distinct bugs (auth bypass -> RCE as cgi-server -> root privesc) and used root to harvest AD credentials, enabling lateral movement; anti-forensics defeated the vendor Integrity Checker since patches were memory-only and restored.
**Insight:** When a front-end authorizes on URL but a back-end routes on a header (X-DSCGI-PATH), look for path/header mismatch to reach protected CGI. Also: upload handlers that write before validating create a race window where parallel execute requests beat deletion.
