A trusted janitor who will run any errand slip left in his mailbox — even the one that says 'hand me the master keys'
CVE-2026-111357 is a local privilege escalation in Ivanti Connect Secure's dsinvoked background service, which runs maintenance tasks as root. The service looks up each task's program path in DSCache, a shared configuration store, and executes it without verifying whether the entry was modified by an authorized process. An attacker with code execution as the cgi-server user can patch the in-memory copy of /home/lib/libdsplibs.so to unlock DSCache writes, redirect an existing maintenance task to a malicious Perl script, and trigger dsinvoked to run it as root. The attack was used in the wild by UTA0576 beginning October 3, 2026 — twelve days before a CVE was even assigned — as the final link in a chain that began with unauthenticated access via CVE-2026-104935. Affected versions include 22.8R2.4 (Build 19097) and earlier in the 22.8 line; the 22.7 line and below are not affected. A patch was released on October 29, 2026 per Volexity's blog update, though Ivanti has not published the specific fixed version string at time of writing.
The vendor rates this HIGH at CVSS 7.0 with an AV:L/AC:H/PR:L vector, and in isolation that is technically defensible — you need local code execution, and the in-memory patching requires build-specific offsets. But calling this a 7.0 ignores the deployment reality. Ivanti Connect Secure is a perimeter VPN appliance: ≥95% of installs are internet-facing by design. 'Local access' on a sealed appliance means 'you exploited a separate RCE first' — and the ICS attack surface has delivered exactly that with clockwork regularity (CVE-2024-21887, CVE-2025-0282, CVE-2026-104935). Once root is reached, the appliance hands over LDAP bind credentials, LAPS passwords, BitLocker recovery keys, and a Kerberoasting launchpad into Active Directory. Volexity documented this full chain from unauthenticated HTTP to domain credential theft. The vendor's 7.0 reflects a paper CVSS exercise, not the real-world blast radius of losing root on the box that guards your perimeter.
5 steps from start to impact.
Gain code execution on the appliance
welcome.cgi endpoint with a spoofed X-DSCGI-PATH header routing it to the protected wu.cgi handler (CVE-2026-104935, CVSS 8.6). A malicious Perl script disguised as a .zip is uploaded and executed during a race window before the server deletes it, yielding code execution as the cgi-server user. UTA0576 delivered the full exploit as Base64-encoded, zlib-compressed Python executed in memory.- Appliance is internet-facing (standard for ICS)
- CVE-2026-104935 is unpatched (fixed in 22.8R2.5, released Oct 13)
- CVE-2026-104935 has been patched for 17 days; orgs with rapid patching have closed this entry point
- Race condition requires precise timing, though the exploit was demonstrated reliably in the wild
X-DSCGI-PATH header anomalies on welcome.cgi; Volexity Snort/Suricata signatures on GitHubPatch in-memory libdsplibs.so to unlock DSCache writes
/home/lib/libdsplibs.so in the cgi-server process and patches specific instruction bytes to remove write restrictions on the DSCache configuration store. No on-disk modifications are made — the library file on the filesystem remains untouched, which is why Ivanti's Integrity Checker Tool (ICT) does not detect this step.- Code execution as cgi-server user (Step 1)
- Knowledge of memory layout and instruction offsets for the specific ICS build
- Build-specific offsets are required — a generic exploit would break on different builds
- No public PoC provides these offsets; UTA0576 may have reverse-engineered them per-target or per-build-range
Hijack a dsinvoked maintenance task via DSCache
/home/runtime/tmp/ics-root-run-inband-*.pl). The dsinvoked broker reads this entry and trusts it unconditionally — the core flaw described by CWE-829 (Inclusion of Functionality from Untrusted Control Sphere).- In-memory library patch successful (Step 2)
- Understanding of DSCache task schema and dsinvoked trigger mechanism
- Undocumented internal ICS architecture; requires reverse engineering of the appliance
- DSCache task format may change between major versions
Trigger root execution via dsinvoked
dsinvoked to execute the hijacked maintenance task. Because dsinvoked runs as root and performs no integrity check on the DSCache-sourced program path, the malicious Perl script runs with full root privileges. The attacker confirms success by reading /etc/shadow. Afterward, the original DSCache entry and the patched library byte are restored to their original values, erasing evidence of the privilege escalation.- Modified DSCache entry (Step 3)
- dsinvoked daemon is running (always running on ICS)
- None once Step 3 succeeds — dsinvoked is a persistent system service
/home/runtime/dlogs/debuglog and /var/log/audit/audit.logHarvest credentials and pivot to Active Directory
tcpdump (dsstatmond) to capture cleartext LDAP traffic on port 389, queries Active Directory for LAPS local admin passwords and BitLocker recovery keys, and performs Kerberoasting to crack service account tickets offline. Credential spray results are written to /tmp/spray_hits.json. The attacker now holds domain-level credentials sufficient for lateral movement across the enterprise.- Root access on the appliance (Step 4)
- ICS is integrated with Active Directory/LDAP (standard enterprise config)
- LDAP channel binding and signing reduce cleartext credential capture
- LAPS/BitLocker access depends on the ICS service account's AD permissions — least-privilege configs limit this
- MFA on downstream systems limits credential reuse
/tmp/, /data/.icscap/)/tmp/ (ml.py, rq5.py, mk.py, rr.py, pu.txt, sp_out.txt, spray_hits.json); /data/.icscap/ directory and contents; process dsstatmond (renamed tcpdump); X-DSCGI-PATH header anomalies in web server logs pointing to /home/webserver/htdocs/dana/fb/smb/wu.cgi or /home/runtime/tmp/ paths; temp files matching /home/runtime/tmp/ics-root-run-inband-*.pl. Full IOC list on Volexity's GitHub threat-intel repo. This does not prevent exploitation but identifies compromise that ICT would miss./home/runtime/dlogs/debuglog and /var/log/audit/audit.log on the appliance. If logs are only stored locally, forensic evidence is destroyed. Configure remote syslog forwarding to your SIEM (Splunk, Elastic, Sentinel) so that log deletion on the appliance does not eliminate your detection trail. Deploy within 3 days.- Ivanti Integrity Checker Tool (ICT): The exploit operates entirely in memory and restores all modified state. ICT checks on-disk file hashes and will report the appliance as clean even when actively compromised. Do not rely on ICT to rule out exploitation.
- Standard appliance log review without external forwarding: The attacker deletes debuglog and audit.log entries. If logs are not forwarded to a SIEM before deletion, the evidence is gone.
- WAF/IPS rules targeting the privilege escalation itself: CVE-2026-111357 is a local privilege escalation — it occurs entirely within the appliance's process space. Network-level controls cannot observe or block the in-memory library patching or DSCache modification. WAF rules are only useful for blocking Step 1 (the CVE-2026-104935 entry point).
- Network segmentation behind the appliance: The ICS appliance itself is the target. Segmenting the network behind it limits lateral movement after credential theft, but does not prevent root access on the appliance or the initial credential harvesting from the appliance's own configuration and LDAP traffic.
The supporting signals.
| In-the-wild exploitation | Confirmed. The CNA (MITRE) description states 'exploited in the wild in October 2026.' Volexity documented UTA0576 exploiting this as part of a zero-day chain beginning October 3, 2026. Canadian Cyber Centre AV26-1035 confirms open-source reporting of active exploitation. VulnCheck KEV lists this CVE; CISA KEV does not (CISA added only the chain entry point, CVE-2026-104935). CISA SSVC paradoxically marks exploitation as 'none' — treat this as a lag in SSVC enrichment, not as a refutation of the CNA's own statement. |
|---|---|
| Proof-of-concept | No public PoC. No repositories found on GitHub matching CVE-2026-111357. Not indexed on pocindex.io or cve-dev.imfht.com aggregators. The exploit requires build-specific memory offsets for libdsplibs.so which have not been published. UTA0576's tooling is private. Low short-term risk of mass commoditization, but the Volexity writeup provides a detailed roadmap for reproduction. |
| Threat actor | UTA0576 (Volexity designation). Assessed as criminally motivated (low confidence). Medium-confidence indicators of LLM-assisted exploit development based on chain complexity and coding style. Infrastructure: leased VPS with OpenVPN (active Sep 30–Oct 7), exfil destination 108.165.147[.]64 (Evoxt hosting). |
| EPSS | 0.00247 (0.25% probability of exploitation in next 30 days), ~15th percentile. EPSS significantly lags chained and APT-exploited vulnerabilities — the model underweights local privilege escalations that serve as chain amplifiers. Do not use EPSS as a priority signal here. |
| CVSS vector | CVSS:3.1/AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H — 7.0 HIGH. Local access vector + high complexity + low privileges = exploitability sub-score of only 1.0. Impact sub-score is 5.9 (full CIA). The low exploitability score masks the real-world risk because 'local' on a sealed appliance conflates with 'post-RCE,' and the ICS attack surface reliably delivers RCE vulns. |
| Affected versions | Ivanti Connect Secure 22.8R2.4 (Build 19097) and earlier in the 22.8 release line. The 22.7 line and below are not affected. Versions 25.1.x may also be affected per the expanded advisory scope (25.1.1.1 and prior, 25.1.2.2 and prior for the chain entry point), but the CVE record specifically names only 22.8R2.4. |
| Fixed versions | Patch released October 29, 2026 per Volexity blog update. Exact version string not yet confirmed by Ivanti's public advisory. The chain entry point (CVE-2026-104935) is fixed in 22.8R2.5, 25.1.1.2, 25.1.3.0, 25.1.3.1 (released Oct 13). The 22.8/22.7 line reaches end-of-life January 31, 2027 — migrate to 25.x. |
| Exposure surface | Censys reported ~33,500 internet-facing ICS instances globally as of January 2025. Shadowserver found ~2,850 vulnerable instances for a February 2025 CVE. Current 2026 exposure is likely in the same order of magnitude. ICS appliances are internet-facing by design (VPN gateway role). No GreyNoise or Shodan tags specific to CVE-2026-111357 exist yet. |
| Disclosure timeline | Oct 3 — exploitation begins (UTA0576) · Oct 5 — Volexity investigation opens · Oct 10 — IOCs shared with Volexity TI subscribers · Oct 13 — Volexity blog + CVE-2026-104935 patches + CISA KEV · Oct 15 — CVE-2026-111357 reserved and published · Oct 29 — dsinvoked patch released |
| Detection evasion | Ivanti's Integrity Checker Tool (ICT) does not detect this exploitation. The attack operates entirely in memory, restores the patched library bytes and DSCache entries, and clears entries from debuglog and audit.log. CISA's advisory guidance recommends forensic triage specifically because ICT is insufficient. |
Sources.
- Volexity — Chained Exploitation of Ivanti Connect Secure Zero-Days (UTA0576)
- CVE Record — CVE-2026-111357 (MITRE/NVD)
- Rapid7 — ETR: Ivanti Connect Secure Zero-Day CVE-2026-104935
- BleepingComputer — Ivanti Connect Secure Zero-Day Exploited in Attacks
- Canadian Centre for Cyber Security — AV26-1035 (Ivanti Advisory)
- OpenCVE — CVE-2026-111357 Detail
- Censys — Mass Exploitation of Ivanti Connect Secure (exposure baseline)
- Ivanti Security Advisory (CVE-2026-104935, covers chain)
Why this verdict
- Active zero-day exploitation confirmed: UTA0576 weaponized this exact privilege escalation as part of a chain beginning October 3, 2026 — twelve days before a CVE was assigned and twenty-six days before a patch existed. The CNA description, Volexity investigation, VulnCheck KEV, and Canadian Cyber Centre all confirm real-world exploitation. This is not theoretical.
- Role multiplier — network edge appliance (canonical, ≥95% high-value): Ivanti Connect Secure is deployed as an internet-facing VPN gateway in virtually all installations. This is a canonical network-edge component per the high-value-role catalog. Root access on the appliance yields LDAP bind credentials, enables LDAP traffic interception, provides access to LAPS passwords and BitLocker recovery keys, and supports Kerberoasting — a documented path from single-appliance root to domain compromise. The blast radius is domain-scale, demonstrated by UTA0576's post-exploitation activity. The chain succeeds in this role and ≥95% of the installed base occupies it — the verdict floor is CRITICAL.
- Zero patch adoption for this CVE: The dsinvoked fix was released October 29 (yesterday). Adoption is effectively 0%. The chain entry point (CVE-2026-104935) was patched October 13, but historical Ivanti patching velocity suggests a substantial unpatched population remains 17 days later — Shadowserver data from prior ICS campaigns consistently shows thousands of unpatched instances weeks post-patch.
- Detection evasion defeats standard forensics: The exploit operates entirely in memory, restores all modified state (library bytes, DSCache entries, instruction patches), and clears both
debuglogandaudit.log. Ivanti's own ICT does not detect exploitation. Defenders who rely on ICT have a false sense of security — compromised appliances appear clean. - Friction acknowledged but insufficient to break the CRITICAL floor: The vendor's AV:L/AC:H vector is technically accurate for the isolated CVE. However, 'local access' on a sealed appliance means 'prior code execution via a separate vulnerability,' and the ICS attack surface has delivered exactly that with regularity (CVE-2024-21887, CVE-2025-0282, CVE-2026-104935). High complexity is real — build-specific memory offsets are required — but UTA0576 demonstrated reliable exploitation against production appliances. No standalone public PoC exists, which limits near-term commoditization, but the Volexity writeup provides a detailed reproduction roadmap. These frictions moderate *mass* exploitation risk but do not reduce the blast radius when the chain lands.
Why not higher?
CRITICAL at 9.0 is already the top severity bucket. The score is not 10.0 because the CVE itself requires local access (AV:L) and high complexity (AC:H), meaning it cannot be exploited remotely in isolation. There is no public standalone PoC, and the EPSS of 0.25% reflects genuine difficulty in independent exploitation without the chain entry point. The attack is not wormable or automatable (CISA SSVC confirms automatable: no).
Why not lower?
Ivanti Connect Secure is a canonical network edge appliance — the bug is IN the perimeter gateway, not on a workstation behind it. The proven chain from unauthenticated HTTP to root with domain-level credential theft was exploited in the wild as a zero-day. The dsinvoked patch has near-zero adoption (released yesterday), the chain entry point patch is only 17 days old with historically slow ICS patching rates across the fleet, and the exploit evades Ivanti's own integrity checking. Downgrading below CRITICAL would require evidence that <1% of the installed base occupies the high-value network-edge role — but ICS is deployed as a VPN gateway in effectively all installations.
Crowdsourced verification payload.
Run this script on the Ivanti Connect Secure appliance via SSH or serial console as any user with read access to the build info. Usage: bash cve-2026-111357-check.sh. No special privileges required — the script only reads version metadata. Exit code 1 = VULNERABLE, 0 = PATCHED, 2 = UNKNOWN.
#!/bin/bash
# CVE-2026-111357 — Ivanti Connect Secure dsinvoked DSCache privilege escalation
# Checks whether the running ICS build is in the affected range.
# Run on the appliance. Exit 1=VULNERABLE, 0=PATCHED, 2=UNKNOWN.
set -uo pipefail
VULN_BUILD=19097 # 22.8R2.4 Build 19097 — last confirmed vulnerable build
VERSION=""
# --- Attempt to read version from known file locations ---
for vfile in \
/home/runtime/etc/build_info \
/home/runtime/etc/appliance-branding/ivanti/version \
/data/etc/build_info \
/home/webserver/htdocs/dana-na/auth/welcome.cgi; do
if [[ -r "$vfile" ]]; then
VERSION=$(head -5 "$vfile" 2>/dev/null || true)
if [[ -n "$VERSION" ]]; then
break
fi
fi
done
# --- Try dsversion command ---
if [[ -z "$VERSION" ]] && command -v dsversion &>/dev/null; then
VERSION=$(dsversion 2>/dev/null || true)
fi
if [[ -z "$VERSION" ]]; then
echo "UNKNOWN — Could not read ICS version. Check Admin UI > System > Overview."
exit 2
fi
echo "[*] Detected version info: $VERSION"
# --- Check for 22.7 and below (not affected) ---
if echo "$VERSION" | grep -qiE '22\.[0-7]R[0-9]'; then
echo "PATCHED — Version 22.7.x and below are not affected by CVE-2026-111357."
exit 0
fi
# --- Check for vulnerable 22.8R2.0 through 22.8R2.4 ---
if echo "$VERSION" | grep -qiE '22\.8R2\.[0-4]([^0-9]|$)'; then
echo "VULNERABLE — Version matches affected range (22.8R2.0–22.8R2.4)."
echo "ACTION: Apply the CVE-2026-111357 patch released 2026-10-29 immediately."
echo " Also verify CVE-2026-104935 is patched (22.8R2.5+)."
exit 1
fi
# --- Check build number if extractable ---
BUILD=""
if [[ "$VERSION" =~ [Bb]uild[[:space:]]*([0-9]+) ]]; then
BUILD="${BASH_REMATCH[1]}"
elif [[ "$VERSION" =~ \.([0-9]{4,6})$ ]]; then
BUILD="${BASH_REMATCH[1]}"
fi
if [[ -n "$BUILD" ]]; then
if (( BUILD <= VULN_BUILD )); then
echo "VULNERABLE — Build $BUILD <= $VULN_BUILD (22.8R2.4)."
echo "ACTION: Apply the CVE-2026-111357 patch released 2026-10-29 immediately."
exit 1
else
echo "PATCHED — Build $BUILD is above the last known vulnerable build ($VULN_BUILD)."
exit 0
fi
fi
# --- Check for 22.8R2.5+ or 25.x (likely patched) ---
if echo "$VERSION" | grep -qiE '22\.8R2\.[5-9]|22\.8R2\.[1-9][0-9]|25\.[0-9]'; then
echo "PATCHED — Version appears to include the fix (22.8R2.5+ or 25.x)."
echo "NOTE: Confirm against Ivanti advisory at hub.ivanti.com."
exit 0
fi
echo "UNKNOWN — Could not conclusively determine status for: $VERSION"
echo "Verify at: https://hub.ivanti.com/s/article/Security-Advisory-Ivanti-Connect-Secure-CVE-2026-104935"
exit 2