Back to the blog
Security

Three Ivanti Zero-Days Rooted a Fully Patched VPN. The Vendor's Integrity Checker Misses It.

October 19, 2026 7 min read

On Tuesday, October 13, 2026, Volexity published its analysis of an intrusion that started at an Ivanti Connect Secure VPN appliance. An actor it had never seen before, now tracked as UTA0576, chained three zero-day vulnerabilities to run code as root without logging in. The appliance was fully patched at the time, on version 22.8R2.4, Build 19097. The attacker deployed no malware and no web shell.

The same day, Ivanti released fixes for two of the three flaws, an authentication bypass and a remote code execution bug, tracked together as CVE-2026-104935 and rated 8.6 on the CVSS scale. CISA added CVE-2026-104935 to its Known Exploited Vulnerabilities catalog on October 13 and gave federal civilian agencies until October 16. The third flaw, a privilege escalation, had no patch: Volexity wrote that Ivanti would fix it in a future release "in the coming weeks." On October 15, it received its own identifier, CVE-2026-111357, rated 7.0, assigned by MITRE rather than by Ivanti. As of October 19, Ivanti's security advisory feed listed no fix for it, and CISA's catalog did not include it.

Volexity described one victim. Ivanti said it was aware of exploitation "affecting a limited number of customers" at the time of disclosure. On October 14, The Hacker News reported that Previdian, which runs honeypot sensors, had logged 105 exploitation attempts from 50 IP addresses; its CEO said the payloads were mostly testing for code execution. BleepingComputer reported that Shadowserver tracks over 5,500 Connect Secure instances exposed online, with no information on how many are already patched.

I do not administer a Connect Secure appliance. I read the report as a CTO who sells software to businesses and as an indie developer who ships his own apps, because it breaks three assumptions most of us lean on: patched means safe, the vendor's checker would notice, and the patch closes the incident.

The chain, in plain terms

Volexity had to rebuild the attack from memory images, disk images and core dumps, because the attacker had deleted evidence from the logs.

Step one: welcome.cgi, the public login page, accepts requests without authentication. The appliance used the URL to decide whether a request was allowed, and a header, X-DSCGI-PATH, to decide where it went. Point the header at a protected script and the login page forwards you there.

Step two: wu.cgi, an upload handler, writes the uploaded file to disk before checking that it is a valid ZIP. The attacker uploaded a Perl script with a .zip extension and fired parallel requests to execute it in the short window before the handler deleted it.

Step three: a root service called dsinvoked runs maintenance tasks and reads which program each task runs from a shared configuration store. The attacker patched a library in the memory of its own process, pointed one task at the Perl interpreter, had dsinvoked run it as root, then put the entry and the library back.

The whole chain ran again for every command, and each result came back in the HTTPS response. No backdoor waited on the box. Volexity documents exploitation from October 3. Defused, another threat intelligence firm, told Cybersecurity Dive it saw the first activity on October 1, on its honeypots and on customer instances.

"Fully patched" depended on the branch

The detail I would underline is in Ivanti's advisory, as reported by The Register, Rapid7 and Dark Reading: Ivanti had found "a portion of this vulnerability" through its own security program and fixed it in 25.1.3.0, released in July. "We had been working to backport the fix to the remaining supported versions when exploitation occurred," Ivanti said, as quoted by Dark Reading.

The affected versions are 22.8R2.4 and earlier, 25.1.2.2 and earlier, and 25.1.1.1 and earlier, each within its own code line; Ivanti's CVE record says 22.7R2.14 and earlier are not affected. The fixed versions are 22.8R2.5, 25.1.1.2, 25.1.3.0 and 25.1.3.1. So the victim was current on its branch, while Ivanti's CVE record lists 25.1.3.0, the July release of the newest line, as not affected by CVE-2026-104935: about three months of head start that the older branches did not get. CISA's alert adds that version 22.8 reaches end of life on January 31, 2027.

That is worth knowing for any product with several supported lines. An older line still gets security fixes, but later. The branch you run is a security decision, not only a compatibility one.

The checker the vendor recommends is the one it beat

Ivanti's October security update tells customers to upgrade and to "run the Integrity Checker Tool regularly." Volexity's report says this chain leaves that tool nothing to find: the library patch lived in memory only, the configuration entry was restored, and the library on disk was never modified. CISA's alert repeats the warning: the tool "may not detect evidence of exploitation" because the commands execute in memory.

The cleanup went further. The payload removed recent entries from the appliance's debug log and the Linux audit log, deleted its own scripts and temporary results, and ran a renamed tcpdump, called dsstatmond, from a hidden directory with eight rotating capture files. Volexity says it has not fully established how far each cleanup step succeeded on the victim's device. The intent is clear anyway.

A green integrity check is a statement about files on disk. This attack was built to leave those files untouched.

Patching can erase the evidence

This is where I would slow down. CISA's implementation guidance for Binding Operational Directive 26-04, dated June 10, tells federal agencies to collect evidence before the patching step, because "patching may jeopardize the availability of artifacts." Its evidence step starts with "immediate acquisition of volatile data," which includes memory. The KEV entry for CVE-2026-104935 carries the flag "Forensic triage required per BOD 26-04: Yes." The directive binds only federal civilian agencies. The reasoning applies to anyone.

When the attack lives in memory, order matters. If the upgrade restarts the appliance before anyone has captured its memory, the best evidence is gone, and what remains are logs the attacker edited. Patch fast, yes. But if there is any sign the box was used, capture first.

The real target was the directory

What UTA0576 did with root says what a VPN is worth to an attacker. It extracted domain credentials stored on the appliance. It used the appliance's Active Directory service account to search for LAPS local administrator passwords, BitLocker recovery keys and attributes holding passwords. It deployed a custom Kerberos tool, sprayed passwords, and tried to pull credentials out of captured LDAP traffic. Volexity assesses with high confidence that this was preparation for lateral movement, and with low confidence that the motive is criminal rather than espionage.

The sign that gave it away was mundane. Sean Koessel, Volexity's vice president of professional services, told Cybersecurity Dive the team noticed "authentication failures that originated from the internal interface" of the VPN appliance. A VPN has no business trying passwords against your own directory.

Volexity also assesses, with medium confidence, that the actor used large language models for exploit development and post-exploitation, citing "highly specific scripts using hardcoded credentials" rather than generic tools. I orchestrate my own work with Claude Code, so that part did not surprise me: a script written for one network now costs little, and a one-off script matches no known signature. The defenders use the same tools. Dark Reading reported that an Ivanti spokesperson said the July discovery came from Ivanti's own LLM project, which uses several AI models to find and fix flaws in its products. Volexity thanked OpenAI's Trusted Access for Cyber program, saying its cyber models drastically reduce analysis time. The vendor found part of the bug first; the fix still did not reach every branch in time.

What I would check now

If you run a Connect Secure appliance, or inherit one through a client or an IT provider:

  1. Compare the exact version to the fixed list above, and plan the move off 22.8 before January 31, 2027.
  2. If your logs capture request headers, look for bursts of requests to /dana-na/auth/url_default/welcome.cgi carrying an X-DSCGI-PATH header, and for any mismatch between the URL path and that header, as Volexity recommends. It expects attackers to find other paths.
  3. Look for authentication attempts that come from the appliance's internal interface, and for leftovers in /tmp/.
  4. If anything looks wrong, capture memory and disk before upgrading. Then follow CISA's recovery list: back up the configuration, factory-reset or rebuild on the latest version, restore the configuration, reset every domain, administrator and local password, revoke and reissue stored certificates, and reset stored API keys and license server credentials.
  5. Ask what the VPN's directory service account can read. If it can read LAPS passwords or BitLocker recovery keys, the VPN holds a key to every machine those secrets protect.
  6. Watch Ivanti's advisory for the privilege escalation fix, the flaw MITRE now tracks as CVE-2026-111357. Until it ships, the patched entry points are what stand between the internet and that root step.

If you buy software or IT services, the question changes too. Not "are you patched?" but "which branch, how fast do backports reach it, and how would you know if a patched box had already been used?"

The appliance in this story did what the checklist asked. The checklist was measuring the wrong thing.

Sources

A project like this one?

I design and deploy products like this. Let's talk.

Let's talk