Threat Overview
Confirmed researcher findings (Volexity, October 13, 2026): UTA0576 exploited an Ivanti Connect Secure (ICS) VPN appliance that was fully patched at the time (22.8R2.4, build 19097), starting October 3. A public welcome.cgi request with a conflicting X-DSCGI-PATH header routed unauthenticated traffic to protected wu.cgi; a temporary upload/race allowed code execution as cgi-server. A separate privilege escalation abused dsinvoked/DSCache to execute as root. Volexity recovered evidence of LDAP credential extraction, AD/LAPS/BitLocker reconnaissance, Kerberos tooling, password spraying, packet capture and log tampering. The actor returned command output through HTTPS exploit requests rather than maintaining a web shell or persistent backdoor.
Vendor statement: Ivanti acknowledged limited exploitation and released fixes for the authentication bypass and RCE tracked as CVE-2026-104935 on October 13. The separate privilege escalation fix was still pending at publication. Researcher assessment: the attacker may have used LLM-assisted tooling; this attribution/assessment is not a confirmed mechanism of compromise.
MSSP relevance: A compromised VPN edge device can expose domain service-account credentials and provide a route into identity infrastructure; appliance endpoint events may not be ingested into Sentinel. Behavioral pivots into DC logons, LDAP flows and firewall/WAF requests are therefore essential.
References
- Volexity original investigation — 2026-10-13
- Ivanti advisory — 2026-10-13
- The Hacker News technical summary — 2026-10-13
- CISA KEV catalog — added 2026-10-13
Impacted Systems
- Product/role: Ivanti Connect Secure VPN appliance, self-managed/on-premises or virtual Internet-facing remote-access gateway. Relevant public HTTPS interface and CGI routing.
- Affected: Volexity demonstrated exploitation of 22.8R2.4 build 19097; Volexity advises upgrading 25.1.1 and prior, 25.1.2, and 22.8R2.4. The published CVE range also identifies versions before 25.1.3.0 with branch-specific exceptions; do not infer every older branch is vulnerable.
- Vendor/CVE record exclusions: 22.7R2.14 or prior, 22.8R2.5, 25.1.3.0, and 25.1.3.1 are listed as unaffected by CVE-2026-104935 in the referenced CVE summary; verify current branch-specific Ivanti guidance.
- Fixed: October 13 vendor patches for authentication bypass/RCE; separate root escalation fix not yet released at disclosure.
- Prerequisites: reachable ICS HTTPS login path; attacker need not authenticate for the demonstrated chain.
Why this matters
New confirmed zero-day exploitation of an enterprise VPN edge device with demonstrated credential theft and AD follow-on activity; immediate MSSP triage is warranted.
Exploitation Status
Confirmed active exploitation beginning at least October 3, 2026 in Volexity’s investigated incident; Ivanti independently acknowledges limited exploitation. One reported attacker IP: 108.165.147.64 (single-incident IOC, not comprehensive). Reported paths/header: /dana-na/auth/url_default/welcome.cgi, X-DSCGI-PATH, wu.cgi, /data/.icscap/.
What this hunt looks for
Proposed review of ICS-related WAF/firewall requests, anomalous request-header routing, known incident infrastructure, burst patterns, LDAP/Kerberos traffic from identified ICS IPs, DC authentication events, and appliance artifact strings where ingested into Microsoft Sentinel. No customer workspace was queried during preparation.
Required logs
Microsoft Sentinel data sources referenced by these hunts: CommonSecurityLog, SecurityEvent, Syslog. Availability must be validated per workspace; unsupported tables cannot provide visibility.
KQL Hunting Content
Hunt 1: First pass — ICS welcome.cgi requests
Sentinel table: CommonSecurityLog. Find perimeter HTTP URL visibility for the public CGI path exploited by UTA0576. An ordinary login-page request is not proof of exploitation.
CommonSecurityLog
| where TimeGenerated >= ago(14d)
| extend Url = tostring(column_ifexists('RequestURL','')), Detail = tostring(column_ifexists('Message',''))
| where Url has 'welcome.cgi' or Detail has '/dana-na/auth/url_default/welcome.cgi'
| where Url has '/dana-na/auth/url_default/' or Detail has '/dana-na/auth/url_default/'
| project TimeGenerated, DeviceVendor, DeviceProduct, SourceIP, DestinationIP, DestinationPort, DeviceAction, Url, Detail
| order by TimeGenerated desc
Hunt 2: Header-routing mismatch and upload handler strings
Sentinel table: Syslog. Highest signal if reverse proxy or ICS Syslog preserves request headers. Look for the header/path mismatch and privileged CGI handler. Absence of header data defeats this hunt.
Syslog
| where TimeGenerated >= ago(14d)
| where SyslogMessage has_any ('X-DSCGI-PATH','wu.cgi','/home/runtime/tmp/')
| where SyslogMessage has_any ('welcome.cgi','X-DSCGI-PATH','/home/webserver/htdocs/dana/fb/smb/wu.cgi')
| project TimeGenerated, Computer, ProcessName, SeverityLevel, SyslogMessage
| order by TimeGenerated desc
Hunt 3: Reported attacker infrastructure — corroboration only
Sentinel table: CommonSecurityLog. Exact host observed in one Volexity incident, not a complete campaign IOC set.
CommonSecurityLog
| where TimeGenerated >= ago(30d)
| where SourceIP == '108.165.147.64' or DestinationIP == '108.165.147.64'
| project TimeGenerated, DeviceVendor, DeviceProduct, SourceIP, DestinationIP, DestinationPort, DeviceAction, RequestURL, Message
| order by TimeGenerated desc
Hunt 4: Burst of ICS welcome.cgi requests
Sentinel table: CommonSecurityLog. Detect repeated exploit-channel calls or race attempts; use URL-bearing firewall/WAF data only.
CommonSecurityLog
| where TimeGenerated >= ago(14d)
| extend Url=tostring(column_ifexists('RequestURL','')), Detail=tostring(column_ifexists('Message',''))
| where Url has 'welcome.cgi' or Detail has '/dana-na/auth/url_default/welcome.cgi'
| summarize Requests=count(), Destinations=dcount(DestinationIP), Actions=make_set(DeviceAction,5), SampleUrls=make_set(Url,3) by SourceIP, bin(TimeGenerated,5m)
| where Requests >= 20
| order by Requests desc
Hunt 5: ICS-to-domain-controller LDAP connections
Sentinel table: CommonSecurityLog. Populate the known appliance addresses. Hunt for internal LDAP/LDAPS/Kerberos traffic following exploitation; expected authentication traffic is common.
let ICS_IPs = dynamic(['REPLACE_WITH_ICS_IP']);
CommonSecurityLog
| where TimeGenerated >= ago(14d)
| where SourceIP in (ICS_IPs) and DestinationPort in (88,389,636,3268,3269)
| summarize Connections=count(), Destinations=make_set(DestinationIP,30), Actions=make_set(DeviceAction,5) by SourceIP, DestinationPort, bin(TimeGenerated,1h)
| order by TimeGenerated desc
Hunt 6: Windows authentication failures originating at ICS
Sentinel table: SecurityEvent. Correlate domain-controller 4625/4771/4776 events with appliance IPs when recorded. Some DC events omit client IP.
let ICS_IPs = dynamic(['REPLACE_WITH_ICS_IP']);
SecurityEvent
| where TimeGenerated >= ago(14d) and EventID in (4625,4771,4776)
| extend ClientIP=tostring(column_ifexists('IpAddress','')), AccountName=tostring(column_ifexists('TargetUserName',''))
| where ClientIP in (ICS_IPs)
| summarize Failures=count(), Accounts=dcount(AccountName), Samples=make_set(AccountName,15) by Computer, ClientIP, EventID, bin(TimeGenerated,15m)
| order by Failures desc
Hunt 7: Network logon successes originating at ICS
Sentinel table: SecurityEvent. Correlate Windows 4624 type-3 network logons from appliance addresses; distinguish expected VPN authentication and service accounts.
let ICS_IPs = dynamic(['REPLACE_WITH_ICS_IP']);
SecurityEvent
| where TimeGenerated >= ago(14d) and EventID == 4624
| extend ClientIP=tostring(column_ifexists('IpAddress','')), LogonTypeValue=toint(column_ifexists('LogonType',-1))
| where ClientIP in (ICS_IPs) and LogonTypeValue == 3
| project TimeGenerated, Computer, ClientIP, Account, Activity, LogonTypeValue
| order by TimeGenerated desc
Hunt 8: Appliance artifact and anti-forensics strings
Sentinel table: Syslog. Search only ingested Linux/ICS logs for reported file paths and utilities. The actor deleted some appliance logs; no hit is weak negative evidence.
Syslog
| where TimeGenerated >= ago(14d)
| where SyslogMessage has_any ('/.icscap/','dsstatmond','/tmp/ml.py','/tmp/rq5.py','/tmp/mk.py','/tmp/rr.py','sp_run.py','/home/runtime/dlogs/debuglog','/var/log/audit/audit.log')
| project TimeGenerated, Computer, ProcessName, SyslogMessage
| order by TimeGenerated desc
Detection Notes
Highest signal: WAF/reverse-proxy X-DSCGI-PATH mismatch with the public welcome path, or correlated LDAP/AD activity from an identified ICS IP. Noise: welcome.cgi is a legitimate login endpoint; LDAP and 4624/4625 may be expected VPN behavior. Limitations: CommonSecurityLog often lacks HTTP headers; Syslog may omit request bodies; MDE typically does not instrument the ICS appliance. Actor removed log entries and changed code in memory, so an Ivanti Integrity Checker result is not sufficient to rule out compromise. Replace REPLACE_WITH_ICS_IP before executing IP-scoped hunts. This is not a guaranteed exploit-detection signature.