OFFENSIVE SECURITY | FIELD NOTE
By uMercs Research | October 19, 2026
On October 13, 2026, Ivanti shipped patches for CVE-2026-104935 and CISA added the flaw to its Known Exploited Vulnerabilities Catalog the same day. The disclosure carried an uncomfortable detail: the appliance that proved the attack worked was running the latest available software when it was compromised. Volexity traced the breach of a fully patched Ivanti Connect Secure VPN appliance, version 22.8R2.4, to an actor it tracks as UTA0576, who chained three zero-day vulnerabilities into unauthenticated, root-level code execution without deploying a web shell, a backdoor, or, for that matter, much of anything to disk.
The mechanics deserve a close read because they attack assumptions, not just software. The chain welds together a request-routing weakness, a file-upload race condition, and a service-configuration trust issue, and it runs the whole operation inside what looks like ordinary HTTPS traffic to the appliance. Every command and its result travel through the exploit channel itself. After each root-level run, the attacker trimmed the logs and restored the system state. Patching matters here, and fixed builds shipped on October 13. But this case is also a lesson in why patch status alone is a thin answer to the question of whether an edge device is compromised.
The numbers frame the problem. CVE-2026-104935 carries a CVSS v3.1 base score of 8.6 and covers an authentication bypass plus a remote code execution flaw that Ivanti jointly tracks under that identifier. Exploitation began on October 3. Ivanti's advisory landed on October 13, spanning affected builds across the 22.8 and 25.1 release trains. A third vulnerability in the chain, the privilege escalation, had no fix at disclosure time. Ten days separated the first observed exploit from the patch, and the target was current the entire time.
The appliance that did everything right
The victim appliance was running 22.8R2.4, build 19097, the latest version available when UTA0576 started working on it on October 3. Volexity opened the investigation on October 5 after its network security monitoring flagged suspicious activity at a customer, and the initial triage pointed at the VPN appliance as the root cause. That is the part that should bother defenders. Nobody had skipped a patch cycle. Nobody had delayed a maintenance window. The box was as current as the vendor could make it, and it was still the origin of lateral movement into the enterprise.
Volexity assesses with low confidence that UTA0576 has criminal rather than espionage motivations, based on the targeting. The operational infrastructure was modest: a single virtual private server, 108.165.147.64, hosted at Evoxt and observed running an OpenVPN server from September 30 to October 7. Modest infrastructure, three zero-days, and root on a fully managed appliance. The ratio of effort to access is the story of modern edge-device attacks.
The first door: a URL that checks the badge, a header that names the room
The authentication bypass abuses how the appliance routes requests between its front-end and back-end processes. Every Ivanti Connect Secure deployment exposes /dana-na/auth/url_default/welcome.cgi, the public login page. Requests to that script are allowed without authentication, which is the entire point of a login page.
The weakness is that a request can carry a second destination in an HTTP header, X-DSCGI-PATH, and the two are checked against each other in the wrong order of trust. The URL determines whether the request is permitted. The header determines where the back end actually sends it. By setting the header to /home/webserver/htdocs/dana/fb/smb/wu.cgi, the attacker routes an unauthenticated, publicly allowed request to a script that executes in a trusted context on the appliance. The guard checks the door the request knocked on. The request then walks through a different one.
The race: how a fake ZIP becomes code
The remote code execution half of CVE-2026-104935 lives in wu.cgi, the upload handler reached through that bypass. The handler writes uploaded content to /home/runtime/tmp/ under a filename derived from the MD5 hash of the client-supplied name. Only after the file is on disk does the handler validate whether the upload is actually a ZIP archive. If the check fails, the handler deletes the file. There is a window, short but real, between the write and the delete.
UTA0576's upload was a Perl script wearing a .zip extension. The handler wrote it to disk, then queued it for deletion as an invalid archive. Before the deletion landed, the attacker sent parallel requests through the same authentication bypass, each with X-DSCGI-PATH pointing at the temp file's predictable MD5-derived path. If an execution request reaches the file before the delete does, the script runs. Sending several requests in quick succession stacks the odds. The upload handler validating the archive after writing it is a bit like stamping the passport after the flight has already landed.
The executed Perl script launches a Bash script, which launches a Python payload delivered base64-encoded and zlib-compressed and executed through exec(). The raw payload exists only in memory. Nothing in that sequence requires a persistent file, and none was left behind.
From cgi-server to root by trusting the task list
Code execution as the cgi-server user is not the end of the chain. Ivanti Connect Secure runs a privileged background service, dsinvoked, that performs maintenance tasks as root on demand. When a task runs, dsinvoked looks up which program it should execute in DSCache, a shared configuration store on the appliance.
The privilege escalation corrupts that lookup. UTA0576 patched the cgi-server process's in-memory copy of an Ivanti library, /home/lib/libdsplibs.so, which let the attacker modify DSCache and reconfigure an existing maintenance task so it launched the Perl interpreter instead of its legitimate script. The attacker then asked dsinvoked to run that task, passing a malicious Perl script as the argument. dsinvoked, doing exactly what the configuration told it to do, executed the script as root.
The exploit confirms the promotion by checking whether /etc/shadow is readable, an honest way to verify the raise. Then it cleans up: the DSCache entry is restored to its legitimate script, the patched library is restored in memory, and the log entries generated by the exploitation are removed from the appliance's debug log and the Linux audit log. At disclosure time this third zero-day had no patch of its own; Ivanti said a fix would follow in a future release. Until it ships, the escalation half of the chain remains live code.
What root was for: credentials, captured traffic, and the directory itself
UTA0576 used the access the way a burglar uses a master key ring, methodically and one door at a time. The appliance stores domain credentials used for LDAP lookups, and those were extracted first. A custom LDAPv3 tool, written to /tmp, authenticated to an internal domain controller using the appliance's own Active Directory service account and searched the directory for high-value attributes: LAPS local administrator passwords, BitLocker recovery keys, userPassword and unixUserPassword values, and logon script paths. Results were written as zlib-compressed, base64-encoded JSON files and exfiltrated through the exploit channel.
The attacker also went after traffic. A renamed tcpdump binary, masquerading as dsstatmond, ran from a hidden directory with eight rotating capture files, using packet filters aimed at plaintext protocols: LDAP, HTTP, FTP, and telnet. A Python tool parsed those captures to harvest plaintext LDAP credentials, HTTP Basic authentication headers, and NTLM challenge-response hashes. UTA0576 first tried to parse an existing capture file on the appliance, filtering for TCP port 389, then attempted to exfiltrate the first 8 kilobytes of it. Volexity notes the same capture-file technique was recently used by another actor, UTA0533, against SonicWall SMA appliances.
Then came the directory itself. A custom Python implementation of Kerberos, with unused Kerberoast functionality built in, tested credentials. A password-spray helper, sp_run.py, hammered Active Directory accounts and logged hits to spray_hits.json. Authentication logs were grepped for valid usernames, and the appliance's configuration, including its authentication methods, was collected wholesale. This was not a smash-and-grab. It was reconnaissance with root privileges, aimed at everything that trusts the appliance.
Why nothing on disk saw it
The operational discipline is the distinguishing feature of this chain. There was no web shell, no first-stage malware, and no separate command-and-control channel. To run each command, UTA0576 re-executed the entire exploit chain, and the command's output came back in the HTTP response. From the network's perspective, the appliance was having a very long, very one-sided conversation with itself over TLS.
The anti-forensics were equally deliberate. The payload read the appliance's debug log and the Linux audit log, filtered out entries from the exploitation window, truncated both files, and rewrote them with the remaining records, preserving old history while erasing recent history. It deleted its own temporary files, removed helper scripts with rm -f, redirected its standard streams to /dev/null, and let the rotating capture buffers overwrite older traffic as they filled.
Ivanti publishes an Integrity Checker Tool that looks for unexpected file modifications on disk. This chain modified a library in memory only and restored the configuration store afterward, so the tool reported a healthy appliance. Volexity recovered the truth the only place it still existed: memory. Core dumps generated during exploitation and system memory collections, analyzed with Volexity's Volcano tool, were what reconstructed the full chain. The appliance passed every patch check and every integrity scan. The one thing it could not fake was its own memory.
What to do this week
If you run Ivanti Connect Secure, patch now to the fixed builds in Ivanti's advisory, 22.8R2.5 on the 22.8 train and the fixed 25.1.x builds, and verify the version actually running. CVE-2026-104935 is in CISA's Known Exploited Vulnerabilities Catalog, and the catalog's deadlines are a floor, not a suggestion.
Treat the VPN appliance as what it has become: an identity-tier asset holding directory credentials, seeing LDAP traffic, and terminating the remote workforce's connection. Its logs belong on a different machine, forwarded off-box in real time, because a root user on the appliance can rewrite local history. Volexity published indicators of compromise alongside its research, including the masquerading process name, the hidden directory, and the temp paths, and those belong in your hunt queries today.
The deeper lesson outlives this advisory. The question after any edge-device compromise is no longer whether the box was patched. This one was. The question is whether anything outside the box, off-box logs, memory forensics, monitoring for lateral movement from the appliance, was in a position to notice. For a lot of environments, this week is a good time to find out. For everyone else, October 13 was a good time to find out, and the calendar has not gotten kinder since.
Sources
Volexity, A Series of Unauthenticated Events: Chained Exploitation of Ivanti Connect Secure Zero-Days, Oct 13 2026: https://www.volexity.com/blog/2026/10/13/a-series-of-unauthenticated-events-chained-exploitation-of-ivanti-connect-secure-zero-days/
Ivanti, Security Advisory 104935, Ivanti Connect Secure, Oct 13 2026: https://hub.ivanti.com/s/article/Security-Advisory-Ivanti-Connect-Secure-CVE-2026-104935
CISA, CISA Urges Patching Newly Exploited Vulnerability in Ivanti Connect Secure, Oct 13 2026: https://www.cisa.gov/news-events/alerts/2026/10/13/cisa-urges-patching-newly-exploited-vulnerability-ivanti-connect-secure
HIPAA Journal, Ivanti Connect Secure Zero Day Exploited in Attacks, Oct 14 2026: https://www.hipaajournal.com/ivanti-connect-secure-zero-day-2026/

