A public report on an Ivanti Connect Secure zero-day chain carried exactly one network indicator, and by the time it was published that IP had already gone dark. What was still live was the proxy that, according to the operator's own notes, replaced it, and Etugen had crawled it: an open directory on port 9999 with roughly 9 GB of files, the full in-band root exploit framework, 168 exploit run logs, stolen data, and the operator's own notes.
Those notes are what close the gap. A canonical memory file written in Russian for an AI coding agent names the retired IP as the predecessor proxy and spells out the whole rotation. The address the report published, dead to any scanner, was documented by role and by date inside the live host Etugen crawled.
At a glance
- The report's only network indicator,
108.165.147[.]64, was a short-lived rented Evoxt VPS, retired before the hunt and no longer live for any scanner. Etugen recovered it a different way, named and dated inside the live successor host. - A content search for the published YARA strings surfaced an open directory on
208.85.17[.]99, a Vultr host in AS20473, The Constant Company, LLC, Spain. Etugen gives it a medium score of 51 and tags itHTTPTunnel. - The directory on port 9999 holds 7,175 files, including the in-band root exploit
framework
/ivanti/exp2.pyand 168report.jsonexploit run logs under/run/. - The most significant finding is
OPERATION_MEMORY.md, a Russian canonical memory file written for an AI agent named "kimi-code". It names108.165.147[.]64as the prior proxy and marks208.85.17[.]99as the sole attack proxy since October 14, 2026. - The same notes lay out the VPS rotation:
70.34.215[.]12,139.84.235[.]230,108.165.147[.]64, then208.85.17[.]99, plus the operator's own box185.130.227[.]232and its egress62.212.70[.]235. The four addresses known only from the notes have no record in Etugen and appear in no public report, so they rest on the notes alone. - The link between the report's indicator and this host is strong. Attributing the host itself to UTA0576 is supported only with moderate confidence: most of its exploit runs follow the public report, and the notes describe a broader criminal operation.
- Hunting the exploit header surfaced other actors abusing the same CVE on
64.94.84[.]170and38.60.227[.]210, neither of which links back to UTA0576. One more, a CobaltStrike host sharing a/24with the report's retired IP, was dropped as a false positive. - Ten new indicators, seven IPs and three file hashes, were recorded in three tiers: the UTA0576 operation, the operator's notes, and separate actors on the same CVE. None of them appears in any public reporting online.
Background
Ivanti updated its advisory on October 29, 2026 to add two Connect Secure vulnerabilities,
CVE-2026-111357, a local authenticated privilege escalation, and CVE-2026-118527, an
authenticated file upload to a known path, both added to CISA's KEV on October 30. Public
reporting attributes to UTA0576 the chaining of these two with CVE-2026-104935, an
authentication bypass by spoofing, to gain unauthenticated root on an appliance running
22.8R2.4 beginning October 3, 2026. The same reporting described credential theft and Active
Directory queries for Windows LAPS passwords and BitLocker recovery keys, activity that evades
Ivanti's Integrity Checker Tool. The public IOC list is a single IP, 108.165.147[.]64, and a
set of appliance-side artefact paths.
Discovery
The report's two indicators were, by their nature, a dead end for any live-infrastructure
lookup: one a retired rented IP, the other an appliance-side payload hash,
25b95f47359c327e3a5ae5ac5cd147f8d9afd98092faf136822ee287e25e3dc8. Neither is a host anyone
can scan. Public reporting online lists 108.165.147[.]64 across
nine reports as an Evoxt VPS, which confirms the address and that it was long past live.
The appliance-side artefacts were the way in. The public advisory published YARA rules, and the strings
from them were searched across Etugen's crawled open-directory files. The string
dsinvoked broker is busy returned six files, PATCH_LOCATOR arch= returned 48, and both
Python combinators returned six each. Every hit sat on one host: 208.85.17[.]99.
| Address | Role | Open ports | Verification |
|---|---|---|---|
208.85.17[.]99 |
Attack proxy vps4, exploit staging | 22, 80, 443, 1143, 4443, 9998, 9999, 18081 | Confirmed by direct scan; open dir on 9999 via Etugen crawl |
108.165.147[.]64 |
Prior proxy vps3 | not seen | Public reporting; named in operator notes |
139.84.235[.]230 |
Earlier attack VPS vps2 | not seen | Inferred from operator notes |
70.34.215[.]12 |
Oldest attack VPS | not seen | Inferred from operator notes |
208.85.17[.]99 sits in AS20473, The Constant Company, LLC, the autonomous system behind
Vultr. Etugen tracks 563 malicious hosts in that ASN, the bulk of them command and control:
262 Supershell installs, 23 Cobalt Strike, plus Sliver, Mythic, AdaptixC2, and several Mustang
Panda hosts. That density is consistent with a provider used heavily for disposable offensive
infrastructure, which fits an operator that rents a fresh VPS roughly every week.
Etugen first saw the open directory on October 19, 2026 and last on October 20. The host record lists eight open ports: 22, 80, 443, 1143, 4443, 9998, 9999, 18081.
![Etugen trashpile view of the ivanti framework directory on 208.85.17[.]99](/assets/ivanti-directory.png)
Etugen's crawl indexed 7,175 artefacts across the two exposed ports, almost all under
port 9999. The top level is a working directory: ivanti/ holds the exploit framework, 196
files, next to the operator's harvested-data and tooling folders fb_loot/, glpi_intel/,
isp_lab/ and others, each tagged malware with MITRE technique labels.
The exploit framework and the chain
The /ivanti/ directory holds the operator's exploit framework: exp, exp2.py with
SHA-256 7aa9f64e71d7d6dde8a6c0db200dc73a7064ac4adf65bb0f9affd9236351ba0c, and compiled
.pyc variants. Its distinctive strings line up with the report's chain: an auth-bypass stage
using the X-DSCGI-PATH header, a race against /home/runtime/tmp/<MD5>, and a
privilege-escalation stage that talks to the dsinvoked broker over a .invoke socket. The
framework was not read in full; only the identifying strings and hashes were recorded.
![Etugen file view of exp2.py on 208.85.17[.]99](/assets/ivanti-exp2.png)
The chain the files describe matches the three CVEs named in public reporting.
AUTH BYPASS X-DSCGI-PATH to wu.cgi → unauthenticated reach past welcome.cgi
FILE UPLOAD CVE-2026-118527 → Perl written to /home/runtime/tmp/<MD5>
RACE EXECUTION ics-root-run-inband-*.pl → command execution on the appliance
PRIVILEGE ESCALATION CVE-2026-111357 dsinvoked → root via /home/runtime/tmp/.invoke
Under /run/ are 168 timestamped directories of the form
<UTCts>-<target>-<pid>-https-inband/, each with a report.json. These are the exact
artefacts the report tells defenders to hunt for on the appliance:
ics-root-run-inband-*.pl and ics-root-result-inband-*. A content search for
ics-root-result-inband returned 252 files, all on this one host and none anywhere else. The
run logs point at ICS targets in several countries across government and private sector; those
victim records exist in Etugen but are not reproduced here as indicators.
The same host was not Ivanti-only. The /iw/ directory carries IceWarp tooling,
wild_e14500.py with the out-of-band host set to 208.85.17[.]99, alongside MLflow,
MinIO, and CyberPanel target lists. The operator ran multi-vector mass exploitation and
harvested targets with FOFA.
The operator's memory file
The clearest artefact is OPERATION_MEMORY.md, SHA-256
afc3f9b853243c88bfb5678fd86c4a2985fceffa8554a119fabb793eea2a8bd7, a 391 KB canonical memory
file written in Russian for an AI coding agent. Its own header describes it as the file the
agent must reread first when its context is compressed. It opens with a block of OPSEC
invariants.
Работать тихо и профессионально, как APT/NSA. Не торопиться, не ошибаться, взвешивать варианты.
In English: "Work quietly and professionally, like APT/NSA. Don't rush, don't make mistakes, weigh the options." The notes read like a standing brief handed to an autonomous operator.
The first invariant is what resolves the report's missing IP. All attacks must run only through
the VPS proxy 208.85.17[.]99, ssh alias vps4, and as of October 14, 2026 the older
70.34.215[.]12 and 139.84.235[.]230 are marked dead and replaced. A separate note sets up
108.165.147[.]64 as vps3, the proxy stood up on October 7. The retired address from the
public IOC list is named, dated, and placed in sequence inside the live host. The link
between the report's indicator and this infrastructure is direct, and confidence in it is high.
Whether the host belongs to UTA0576 is a separate question, covered below.
The file also names the operator's local box 185.130.227[.]232 with an egress of
62.212.70[.]235, both flagged do-not-burn, and working directories /root/opsh on the VPS
and /root/operationshell locally. It warns the agent to stay out of other sessions on the
same VPS (tmux bubl4444, beacon*, phoenixd), so the host is shared with other operations.
Not every artefact on 208.85.17[.]99 can be attributed to UTA0576 with confidence.
The memory file also contained FOFA API keys and the VPS root password in the clear. Those are
not reproduced here. The FOFA key does not appear on any other crawled host. Alongside the
stolen appliance data 4770.eml and a 1.2 GB pack48.7z, and a credential watcher at
/home/runtime/tmp/.svc/authwatch.log, Etugen's loot extraction pulled SendGrid, Stripe, and
three AWS access keys from the directory, all masked. These most likely belong to victims and
should be routed to the affected organizations.
How far the attribution goes
Two claims need to be kept apart. The first is that 208.85.17[.]99 ran the exploit chain the
report describes. The run logs carry the report's evidence names, the published YARA strings match
only on this host, and the report's own indicator appears in Etugen only inside this host's
memory file. That link is strong. The second claim is that the host belongs to UTA0576, and the
evidence supports it only with moderate confidence.
The timeline is the first reason. Public reporting published 108.165.147[.]64 and the evidence file
names on October 13. In a sample of 100 of the 168 run logs, 14 have their earliest timestamp on
October 12 and 12 on October 13, while 51 start on October 14, the day the notes say the
operator moved to vps4. The other 23 carry no usable timestamp. Most of the activity on this
host follows the public report, so reuse of published details can't be ruled out from the logs
alone.
The second reason is a mismatch in dates. According to public reporting, 108.165.147[.]64 ran an
OpenVPN server from September 30 to October 7. The memory file records the same address being
stood up as a new proxy on October 7. That fits an operator repurposing a VPS it already held,
but it would also fit a reassigned address, and the files don't settle which.
The third reason is the shape of the operation. The memory file runs from September 16 to October 14 and documents a broad, financially motivated campaign: data theft and ransomware across several sectors and countries. Ivanti appears in it once, inside a long list of products the operator surveyed. Public reporting assessed criminal motivation for UTA0576 only with low confidence. A criminal operator running the Ivanti chain as one line of work among several is consistent with the report, but it isn't proof that this is the group the reporting tracks. This analysis worked from the first 60,000 characters of the 391,111-byte file plus targeted search across the rest, so parts of the October record were sampled through snippets rather than read end to end.
Hunting for more
The strings that only exist on this one host are the strongest pattern. The exploit framework
strings, the ics-root-*-inband artefact names, and the memory file header were each turned
into an Etugen content search.
| Pattern | Evidence | Etugen query | Matches | Confidence |
|---|---|---|---|---|
| Exploit framework magic string | exp2.py, run reports |
search_files content="dsinvoked broker is busy" |
6 | high |
| PATCH_LOCATOR output | exp2.py, report.json |
content="PATCH_LOCATOR arch=" |
48 | high |
| In-band run artefacts | report evidence paths | content="ics-root-result-inband" |
252 | high |
| CVE-2026-104935 header | exploit and shell tooling | content="X-DSCGI-PATH" |
18 (8 new) | medium |
| wu.cgi upload, non-nuclei | custom tooling | content="/dana/fb/smb/wu.cgi" (exclude nuclei) |
10 (3 new) | medium |
| Operator memory file | OPERATION_MEMORY.md |
fileName="OPERATION_MEMORY" |
2 (1 new) | high |
The ics-root-run-inband and ics-root-result-inband artefacts returned zero hits on any host
other than 208.85.17[.]99, which makes that query a clean tripwire: a second hit would be the
operator's next proxy. The OPERATION_MEMORY filename search returns one other file, an
unrelated 75-byte test log on a different host, so the exact filename alone is specific enough
to hunt on.
The X-DSCGI-PATH searches, by contrast, surfaced other actors. Two separate hosts abuse the
same CVE-2026-104935 chain without matching the UTA0576 artefacts: a Chinese-language
poc.py with a .invoke LPE and frpc push on 64.94.84[.]170, and an upload-test script
with post-exploitation tooling VShell, Mimikatz and Garble on 38.60.227[.]210. Both are real
malicious hosts, but the only tie to this case is the shared CVE, so neither is attributed to
UTA0576. A third host, 206.189.66[.]142, carried an ivanti_dscgi Perl-shell client
shell_console.py, but the box otherwise looks like a generic credential-cracking and webshell
server with rockyou, hashcat and an unrelated Linux kernel exploit, first seen on the day of
the hunt. Its one tie is the X-DSCGI-PATH header, which is now in public nuclei templates,
so it is kept only as unconfirmed. A fourth candidate, a CobaltStrike host on the same /24 as
the report's retired IP, was dropped as a false positive: different tooling, a different month,
and no artefact overlap, on what is a shared VPS range.
Six YARA rules from this hunt run in Etugen's YARA scanner over crawled open-directory files. The highest-signal one keys on the artefact names the report itself lists.
rule UTA0576_ICS_Inband_Run_Report {
strings:
$p1 = "ics-root-run-inband-" ascii
$p2 = "ics-root-result-inband-" ascii
$p3 = "ICS_INBAND_ROOT_" ascii
$j1 = "\"transport\": \"https-inband\"" ascii
condition:
2 of ($p*) or ($j1 and 1 of ($p*))
}
Tactics and techniques
The chain was mapped against MITRE ATT&CK from the files on 208.85.17[.]99 and the report's
hunting guidance. The techniques observed directly in Etugen data (the exploit framework, the
run logs, the LDAP dump, the staged archive, and the proxy rotation) are marked confirmed. The
log deletion, Integrity Checker evasion, and AD credential queries come only from the public
write-up, not from files Etugen read, so they are marked confirmed: false.
Reconnaissance
- T1595.002Vulnerability Scanning FOFA-driven mass scanning for ICS, IceWarp, MLflow, MinIO
Initial Access
- T1190Exploit Public-Facing Application CVE-2026-104935 X-DSCGI-PATH auth bypass to wu.cgi
Execution
- T1059.004Unix Shell ics-root-run-inband-*.pl via /home/runtime/tmp race
Privilege Escalation
- T1068Exploitation for Privilege Escalation CVE-2026-111357 dsinvoked .invoke socket, exp2.py
Defense Evasion
Credential Access
Discovery
- T1087.002Domain Account LDAP dump (--extract-ldap)
Collection
- T1560Archive Collected Data pack48.7z staged on the open directory
Command and Control
- T1090Proxy rotating rented VPS as the sole attack proxy (vps2 to vps4)
Confirmed from analysisSuspected, not confirmed
Detection and defense
| Layer | Recommendation |
|---|---|
| Network | Review requests to /dana-na/auth/url_default/welcome.cgi, especially URL and header mismatches involving X-DSCGI-PATH, including values pointing at /home/webserver/htdocs/dana/fb/smb/wu.cgi |
| Network | Block and alert on the operator proxies 208.85.17[.]99, 108.165.147[.]64, 139.84.235[.]230, and 70.34.215[.]12, and treat the whole Evoxt 108.165.147[.]0/24 as suspect |
| Endpoint | Hunt the appliance for /home/runtime/tmp/ics-root-run-inband-*.pl and ics-root-result-inband-*, plus /tmp/ml.py, rq5.py, spray_hits.json, and /data/.icscap/ as listed in public reporting |
| Endpoint | Watch for the .svc/authwatch.log credential watcher and for selective gaps in debuglog and audit.log |
| Identity | Rotate AD credentials, Windows LAPS passwords, and BitLocker recovery keys exposed through a compromised appliance; a clean Integrity Checker result does not rule out compromise |
| General | Apply the fixed releases 25.1.1[.]3 or 22.8R2.6 on an emergency basis, preserve memory and logs before resetting, and rotate the SendGrid, Stripe, and AWS keys seen staged on the open directory |
| General | In Etugen, set an actor watch on UTA0576, a saved search for ics-root-run-inband and OPERATION_MEMORY outside 208.85.17[.]99, and the six YARA rules from this hunt |
Takeaways
The most instructive part of this case is that a dead indicator can still be chased. The one IP the report published had already been retired and was invisible to internet-wide scanning. What made it recoverable was the operator's habit of rotating proxies while leaving the previous ones documented. The live host's notes gave the names and dates of its predecessors. What they don't do is prove who the operator is: the tie to UTA0576 stays at moderate confidence until the original researchers can compare it with their own data.
The second point is about operator discipline against operator mistakes. The memory file reads like a careful brief: route everything through the VPS, never burn the local box, stay out of other sessions. Yet the same host left an open directory on port 9999 with the exploit framework, 168 run logs, stolen mail and archives, FOFA keys, and the brief itself. The notes insist on working like an APT; the exposure is the opposite.
The third point is that the shared search space is noisy. The X-DSCGI-PATH header is now in
public nuclei templates and in at least three unrelated tool sets. Hunting the CVE finds many
hands. Hunting the operator's unique artefact names (ics-root-run-inband, the memory file
header) finds only this one, which is what makes those the queries worth saving.
For defenders, the action is unchanged from the public guidance: patch to the fixed releases 25.1.1[.]3 or 22.8R2.6, assume the Integrity Checker can be evaded, preserve evidence before resetting, and rotate every credential an exposed appliance could have reached, including LAPS and BitLocker material.
IOC list (defanged)
| Type | Value | Tier and note |
|---|---|---|
| IPv4 | 208.85.17[.]99 |
New: UTA0576 attack proxy and exploit staging |
| IPv4 | 139.84.235[.]230 |
Operator notes only, retired VPS |
| IPv4 | 70.34.215[.]12 |
Operator notes only, retired VPS |
| IPv4 | 185.130.227[.]232 |
Operator notes only, operator box |
| IPv4 | 62.212.70[.]235 |
Operator notes only, operator egress |
| IPv4 | 64.94.84[.]170 |
Separate actor on the same CVE, not UTA0576 |
| IPv4 | 38.60.227[.]210 |
Separate actor on the same CVE, not UTA0576 |
| IPv4 | 206.189.66[.]142 |
Unconfirmed, X-DSCGI-PATH header tie only |
| IPv4 | 108.165.147[.]64 |
Report indicator, retired before the hunt |
| ASN | AS20473 |
The Constant Company, LLC |
| Ports | 22, 80, 443, 1143, 4443, 9998, 9999, 18081 | On 208.85.17[.]99 |
File hashes (SHA-256):
| File | SHA-256 | Note |
|---|---|---|
exp2.py |
7aa9f64e71d7d6dde8a6c0db200dc73a7064ac4adf65bb0f9affd9236351ba0c |
In-band root exploit framework |
OPERATION_MEMORY.md |
afc3f9b853243c88bfb5678fd86c4a2985fceffa8554a119fabb793eea2a8bd7 |
Operator memory file |
poc.py |
269a9b9539fa95a0fee5eb8ac5baa38dd350cae0611bd8e535dd8099a9548ffb |
Separate actor cluster |
Host-based indicators:
| Type | Value |
|---|---|
| Appliance artefact | /home/runtime/tmp/ics-root-run-inband-*.pl, ics-root-result-inband-* |
| Appliance artefact | /home/runtime/tmp/.svc/authwatch.log |
| Request header | X-DSCGI-PATH: /home/webserver/htdocs/dana/fb/smb/wu.cgi |
| Open-dir layout | /ivanti/, /run/<UTCts>-<ip>-<pid>-https-inband/, /iw/ |
| Operator working dir | /root/opsh, /root/operationshell |
The findings in this post rest on analysis of files found in a publicly exposed directory and on Etugen's scan and crawl data, kept separate from what public reporting described. All indicators were valid at the time of writing.
