
Table of contents
21
Read this in 30 seconds: CVE-2026-104935 is an authentication bypass in Ivanti Connect Secure that lets a remote, unauthenticated attacker run commands on the VPN appliance, and it was exploited before most branches had a fix. Ivanti published its advisory on October 13, 2026, and CISA added it to the Known Exploited Vulnerabilities catalog the same day, with a deadline of October 16 and a forensic-triage flag.
- Patching is not the whole job. Volexity found a three-bug chain, and the privilege-escalation link is still unpatched, with Ivanti promising a fix “in the coming weeks.”
- A clean integrity scan does not clear you. Volexity says Ivanti’s Integrity Checker “may not be able to identify device compromise,” and CISA says the attacker’s commands execute in memory.
- Exploitation beat most of the patches. Volexity saw it starting October 3, 2026. The fix for the 25.1.1.x train, 25.1.1.2, shipped October 5, and the 22.8 fix, 22.8R2.5, shipped October 12.
- The affected builds are 25.1.1.1, 25.1.2.2 and 22.8R2.4 and below. The fixes are 25.1.1.2, 25.1.3.0 or 25.1.3.1, and 22.8R2.5. Version 22.7R2.14 and earlier is not affected.
- The attacker went after Active Directory. Volexity saw stored LDAP credentials extracted, LAPS and BitLocker data targeted, and password spraying against Active Directory accounts.
A VPN gateway has one job, being reachable from the internet and trusted from the inside, and that combination is exactly what makes a bug in it so expensive.
Ivanti Connect Secure has been here before. Our pull of the CISA catalog shows 14 entries across the Connect Secure and Pulse Secure family, and 8 of them carry a known-ransomware flag. This one is the first Connect Secure addition since April 2025, and Ivanti’s own advisory says exploitation was “affecting a limited number of customers at the time of disclosure.”
This article covers what the advisory and the research say about CVE-2026-104935, which builds are affected, how the chain works at the level that has been published, what the attacker did, which indicators you can hunt for today (with commands we tested), and the order to fix things in. It also says plainly what nobody has published yet.
Ivanti Connect Secure, formerly Pulse Connect Secure, is a VPN appliance. Remote staff connect to it from the internet, and it hands them a path into the internal network. That means it sits on the one boundary an attacker most wants to cross.
It also holds the keys. Volexity found domain credentials stored on the appliance, and CISA’s recovery steps tell you to rotate certificates, API keys and license server credentials. A compromise there is not a single compromised server, and Volexity’s account of this attack shows why.
Ivanti’s advisory (article 000109571, created October 13, 2026) describes it in one sentence: “Authentication bypass by spoofing in ICS before version 25.1.3.0 allows a remote unauthenticated attacker to execute arbitrary commands.” It adds that this does not impact version 22.7R2.14 or prior.
The record carries these facts:
CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:L. NVD lists the same metrics under 3.1, scored by a secondary source.The advisory for CVE-2026-104935 also admits something unusual. Ivanti says it “initially discovered a portion of this vulnerability as part of our product security program and patched it in the July release 25.1.3.0,” and was backporting the fix when exploitation began. That is the whole story of the timeline, so keep it in mind.
Ivanti lists three affected trains, and the fixed build for each is different. This is where estates trip up, because 25.1.2.x does not have a simple point release to move to.
| Train and platform | Affected | Fixed | Catch |
|---|---|---|---|
| 25.1.1.x (ISA6000, ISA8000 physical; ISA4000, ISA6000, ISA8000 virtual) | 25.1.1.1 and prior | 25.1.1.2 (released Oct 5) | The simplest path |
| 25.1.2.x | 25.1.2.2 and prior | 25.1.3.0 (July) or 25.1.3.1 | New platform required: ISA4500, ISA6500 or ISA8500, or a new virtual build from the 25.1.3.0 template |
| 22.8.x | 22.8R2.4 and prior | 22.8R2.5 (released Oct 12) | Ivanti prefers moving to 25.1.1.2 or later; 22.8 is end of life on January 31, 2027 |
| 22.7.x | Not affected (22.7R2.14 and earlier) | Not needed | End of life on January 31, 2027 |

Ivanti calls 22.8 “only meant to be a temporary bridge from 22.7 to 25.1.” Read that as a warning: if you are on 22.8 today, the interim fix buys you time, not a destination.
If you manage more than a handful of appliances, do not eyeball version strings when you triage CVE-2026-104935. This script, which we wrote and tested against every build in the advisory, classifies a version against the table above.
import re, sys
def parse(v):
v = v.strip().upper().replace(" ", "")
m = re.fullmatch(r"(\d+)\.(\d+)R(\d+)\.(\d+)", v) # 22.8R2.4
if m:
return ("R", int(m[1]), int(m[2]), int(m[3]), int(m[4]))
m = re.fullmatch(r"(\d+)\.(\d+)\.(\d+)\.(\d+)", v) # 25.1.1.1
if m:
return ("N", *map(int, m.groups()))
raise ValueError(f"unrecognised version: {v!r}")
def verdict(version):
kind, *n = parse(version)
if kind == "R":
major, minor, rel, patch = n
if (major, minor) <= (22, 7):
return "not affected (22.7 and earlier)"
if (major, minor) == (22, 8):
return ("AFFECTED, update to 22.8R2.5 or move to 25.1.1.2+"
if (rel, patch) <= (2, 4) else "fixed (22.8R2.5 or later)")
else:
a, b, c, d = n
if (a, b) == (25, 1):
if (c, d) <= (1, 1):
return "AFFECTED, update to 25.1.1.2"
if c == 1:
return "fixed (25.1.1.2 or later)"
if (c, d) <= (2, 2):
return "AFFECTED, move to 25.1.3.0 or 25.1.3.1 (new platform)"
return "fixed (25.1.3.0 or later)"
return "unknown branch: check Ivanti's advisory"
for v in sys.argv[1:]:
print(f"{v:>10} {verdict(v)}")
Run it against a list and you get an answer per appliance:
python3 ics_check.py 22.7R2.14 22.8R2.4 22.8R2.5 25.1.1.1 25.1.2.2 25.1.3.1
# 22.7R2.14 not affected (22.7 and earlier)
# 22.8R2.4 AFFECTED, update to 22.8R2.5 or move to 25.1.1.2+
# 22.8R2.5 fixed (22.8R2.5 or later)
# 25.1.1.1 AFFECTED, update to 25.1.1.2
# 25.1.2.2 AFFECTED, move to 25.1.3.0 or 25.1.3.1 (new platform)
# 25.1.3.1 fixed (25.1.3.0 or later)
This is our illustration of Ivanti’s table, not an Ivanti tool. Treat the advisory as the authority, and treat any version string you did not read from the appliance itself as a guess.
Here is the part that most coverage flattens. Ivanti’s advisory lists one CVE, CVE-2026-104935, and calls it “one high severity vulnerability.” Volexity describes a chain of three.
Per Volexity, the attacker combined three things: “An authentication bypass in ICS welcome.cgi allowing requests to be routed to arbitrary CGI files,” “A file write vulnerability in wu.cgi” with a race condition between execution and deletion, and “A privilege escalation vulnerability in how the ICS dsinvoked broker trusts DSCache configuration data.” Volexity maps the bypass and the code execution to CVE-2026-104935. It gives no CVE for the privilege escalation.
We will not describe the requests, because the vendor and the researchers have not published a working recipe and we are not going to reconstruct one. What matters for a defender is the shape.

Our reading, and it is an inference: closing the first two links removes the way in, and the unpatched privilege escalation is only reachable once an attacker already runs code. That makes patching urgent and still not sufficient on its own, which is why the recovery steps below matter.
The dates are the argument for CVE-2026-104935. Exploitation began before the fix existed for the 25.1.1.x and 22.8 trains.
| Date | Event | Source |
|---|---|---|
| July 2026 | Ivanti ships 25.1.3.0 with a partial fix | Ivanti advisory |
| Oct 3 | UTA0576 starts repeatedly exploiting the chain | Volexity |
| Oct 5 | Volexity begins an investigation at a monitoring customer; 25.1.1.2 released | Volexity; Ivanti |
| Oct 12 | 22.8R2.5 released | Ivanti |
| Oct 13 | Advisory, Volexity blog, CISA alert, KEV entry | Ivanti; Volexity; CISA |
| Oct 16 | KEV due date | CISA KEV catalog |
| “Coming weeks” | Privilege escalation fix | Volexity |
| Jan 31, 2027 | 22.7 and 22.8 end of life | Ivanti |
Two days passed between the first exploitation Volexity saw and 25.1.1.2, the first fix for the 25.1.1.x train, and nine days passed before 22.8R2.5. The July build 25.1.3.0 was already free of the bug, but it needs new hardware or a new virtual build, so for most estates there was nothing quick to apply.

Volexity says the chain was “exploited by a previously unknown threat actor that Volexity tracks as UTA0576.” Its account of the post-exploitation is the best reason to treat this as more than “patch and move on.”
The actor “Extracted credentials stored on the ICS VPN appliance, such as domain credentials used with LDAP.” It also went after Windows Local Administrator Password Solution (LAPS) credentials and BitLocker recovery information.
It deployed “a custom Kerberos tool capable of Kerberoast attacks and credential testing,” ran password-spraying attacks against Active Directory accounts, and used a renamed tcpdump executable at /data/.icscap/dsstatmond. Volexity also lists the appliance’s debug and audit logs among the paths the actor touched.
Volexity states that it “assesses with medium confidence that UTA0576 makes use of large language models (LLMs) for exploit development and post-exploitation activity.” That is a medium-confidence assessment from one vendor, and we cannot verify it. It is still the detail that explains the speed: the time between a fix and a working attack keeps shrinking.
The operation was detected and disrupted, so the final goal is unknown. Volexity assesses “with high confidence that UTA0576’s actions signaled preparation for lateral movement.”
Ivanti says “limited indicators of compromise” are available and points to Volexity’s blog and repository. Volexity keeps the full set in its threat-intel repository, and the post lists these inline:
108.165.147[.]64dsstatmond (PID 5012), running from /data/.icscap//data/.icscap/h.py, /tmp/ml.py, /tmp/rq5.py, /tmp/mk.py, /tmp/rr.py, /tmp/pu.txt, /tmp/sp_run.py, /tmp/sp_out.txt, /tmp/spray_hits.json/home/bin/updateOpswatSDK.pl, /home/lib/libdsplibs.so, /home/runtime/tmp/ics-root-run-inband-.pl, /home/runtime/tmp/ics-root-result-inband-/home/runtime/dlogs/debuglog and /var/log/audit/audit.logRun this on a forensic copy of the appliance, never on the live device. It checks a mounted image for the paths above, which is the fastest first pass for any CVE-2026-104935 case:
#!/usr/bin/env bash
ROOT="${1:?path to mounted image}"
hits=0
for p in data/.icscap \
tmp/ml.py tmp/rq5.py tmp/mk.py tmp/rr.py tmp/pu.txt tmp/sp_run.py \
tmp/sp_out.txt tmp/spray_hits.json \
'home/runtime/tmp/ics-root-run-inband-*' \
'home/runtime/tmp/ics-root-result-inband-*'
do
for f in $ROOT/$p; do
[ -e "$f" ] && { echo "FOUND $f"; hits=$((hits+1)); }
done
done
echo "$hits indicator path(s) present"
[ "$hits" -eq 0 ] || exit 1
Volexity’s detection advice for CVE-2026-104935 is simple: “Monitor for large numbers of network requests for /dana-na/auth/url_default/welcome.cgi.” If you keep web or proxy logs in front of the appliance, a per-source count is a start. This is our example, and it will produce false positives on busy login pages:
awk '/\/dana-na\/auth\/url_default\/welcome\.cgi/ {n[$1]++}
END {for (ip in n) print n[ip], ip}' access.log | sort -rn
Volexity also says monitoring for mismatches between the URL path and the X-DSCGI-PATH header is “advisable.” We are not publishing a rule for that, because the matching logic is not public and a guess would bury you in noise.
CISA flags CVE-2026-104935 for forensic triage, and the reasoning is stark. CISA’s alert says the Integrity Checker may miss exploitation “because threat actor commands execute in memory.” Volexity says the Ivanti Integrity Checker “may not be able to identify device compromise.”
So do not treat a clean Integrity Checker result as a finish line. Before you patch or reboot anything:
Work through these in order, and note where CISA’s guidance goes beyond the CVE-2026-104935 patch.
We found no interim mitigation in the sources we read. CISA’s alert names none beyond patching and the recovery steps.
We counted this from the catalog file itself, and you can check the entry for CVE-2026-104935 the same way:
curl -s https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json \
| jq '.vulnerabilities[] | select(.cveID=="CVE-2026-104935")
| {cveID, dateAdded, dueDate, forensicTriage, knownRansomwareCampaignUse}'
# {
# "cveID": "CVE-2026-104935",
# "dateAdded": "2026-10-13",
# "dueDate": "2026-10-16",
# "forensicTriage": "Yes",
# "knownRansomwareCampaignUse": "Unknown"
# }
The numbers above come from the same file. Of 14 entries for the Connect Secure and Pulse Secure family, 8 carry CISA’s known-ransomware flag. The flag on CVE-2026-104935 is “Unknown,” which means it has not been linked to ransomware yet, not that it never will be.
Before this addition, the most recent Connect Secure entry was CVE-2025-22457, added April 4, 2025. The catalog does not say why the gap closed now, and neither do we.
| Point | Source A | Source B | What we used |
|---|---|---|---|
| CVSS version label | Ivanti: CVSS:3.0 vector, 8.6 | NVD: same metrics under 3.1, secondary source | Ivanti’s 3.0 label, noted NVD |
| Unaffected 22.7 build | Ivanti description: “22.7R2.14 or prior” | Ivanti solution text: “22.7.14 and lower” | 22.7R2.14 and earlier |
| Due date | CISA KEV file: October 16 | CISA alert: “immediately,” no formal date | October 16, from the KEV file |
| How many bugs | Ivanti: one CVE | Volexity: three bugs, one without a CVE | Both, labeled |
| Exploitation start | Volexity: October 3 | One secondary report: October 1, unsourced | October 3 |
So yeah, this is where we mention our own work. Handling a VPN bug like CVE-2026-104935 starts with inventory, not a clever exploit. Knowing which appliances exist, which are exposed and which version each runs is most of the job.
Our AI VAPT services combine automated and human-led testing against exposed infrastructure, and the exposure review above is part of that kind of work. On infrastructure you own, XHack AI’s autonomous pentesting covers reconnaissance, port scanning and service enumeration, and the agent streams its work to a live terminal so you can watch what it runs. A pentest report documents what was tested. It does not certify that a gateway is patched or clean, and it does not replace the update or the forensic work. XHack does not store your data, and your session data stays on your own computer.
CVE-2026-104935 is an authentication bypass by spoofing (CWE-290) in Ivanti Connect Secure that lets a remote, unauthenticated attacker execute arbitrary commands. Ivanti rates it 8.6 (High) and says it has been exploited. Volexity describes it as part of a three-bug chain.
Yes. Ivanti says it is “aware of exploitation affecting a limited number of customers,” and CISA added it to the Known Exploited Vulnerabilities catalog on October 13, 2026. Volexity saw the actor UTA0576 exploiting it from October 3.
Ivanti Connect Secure 25.1.1.1 and prior, 25.1.2.2 and prior, and 22.8R2.4 and prior. Version 22.7R2.14 and earlier, and 25.1.3.0 and later, are not affected.
Update to 25.1.1.2, 25.1.3.0 or 25.1.3.1, or 22.8R2.5, depending on your train. If you suspect compromise, follow CISA’s recovery steps: factory reset and upgrade, restore the configuration, and reset passwords, certificates and API keys.
Not reliably. Volexity says the Integrity Checker “may not be able to identify device compromise,” and CISA says the attacker’s commands execute in memory. Treat a clean result as incomplete evidence, and use memory and network forensics.
Not yet. Volexity says Ivanti is working on a fix that will ship in a future release in the coming weeks, and Ivanti’s advisory does not cover it.
CVE-2026-104935 is an exploited Ivanti Connect Secure authentication bypass, part of a three-bug chain whose last link is still unpatched. Exploitation started two days before the first fixed build, and the integrity tool may not see it.
Inventory your appliances, preserve the evidence, then patch to the right build and recover if there is any doubt. The fix is available now. The expensive part is finding every gateway you forgot you had.
Categories
Related articles