Zero-Day CISA KEV Threat Actor

The login failed and NetScaler ran the command anyway

October 6, 2026·8 min read·Chris Boker, Founder, CVEasy AI
A rejected login at a mint authentication gate still writes a gold line into a stack of ink log bars, a gold dashed timer ring marks the delay, and a green root worker reads that gold line and fires a rust arrow into a dark appliance tile

The request that took these appliances was a login that failed. No bypass and no stolen credential, just a plain administrative login against the NetScaler management interface carrying a username nobody would ever type. Authentication did what it was built to do and rejected it. Some minutes later, on a maintenance timer the operator never touched, the appliance executed the contents of that username as root.

That is CVE-2026-88771, one of two Citrix NetScaler zero-days an unattributed intrusion set has been mass-exploiting since early September. Citrix shipped fixes in bulletin CTX697096 on September 27, 2026, CISA listed the flaw the same day with a three-day federal deadline, and eSentire traced live exploitation back to September 5. Palo Alto Networks counted 50,277 instances answering from the public internet (Unit 42).

Who is on the other end of this

Nobody has named the group and ATT&CK has no group ID for the activity, so we track it internally as the NetScaler Edge Intrusion Cluster, a label of convenience, not an attribution. The operators take the appliance configuration, install something quiet and leave, which reads as access brokerage rather than extortion. Targets are whoever puts NetScaler ADC or Gateway in front of remote access: finance, healthcare, managed service providers, critical infrastructure. Two distinct post-exploitation toolsets have been reported against these CVEs, implants documented by Mandiant (Google Cloud Threat Intelligence) and a Perl dropper leaving different artifacts (The Hacker News), so no single indicator list covers this.

The log is the execution surface

NetScaler audits failed management logins to /var/log/ns.log and writes the submitted username into the line as received, which every appliance does some version of. What reads the log afterward is the problem. NetScaler ships a telemetry worker, admautoregd, enabled by default and running as root, which periodically invokes a maintenance script at /netscaler/ns_monuploadd_err.pl to summarise packet engine crash records. On vulnerable builds that script pulls matching lines out of the log through a chain of grep, sed and awk, then drops the captured text into a shell command without quoting it (watchTowr Labs).

So the login never has to succeed. An attacker needs the username field to reach the log file, and the appliance's own privileged housekeeping finishes the job on its own schedule. The injected line is shaped to look like a fabricated packet engine failure so the parser matches it, which is why every hunt list this week carries pitboss and NSPPE (LevelBlue SpiderLabs).

Two assumptions break at once, and the second is the expensive one. First, that a rejected login is a non-event, which is why failed authentication is the most heavily sampled and discarded record class in most SOCs. Second, that a log is a record of what happened rather than an input to something that runs. Detection content for pre-auth remote code execution is almost always built on a request and response pair, and nothing anomalous comes back here: a rejected login, a gap of indeterminate length, then root.

Log injection itself is old, so I am not calling this a new technique class. The shape is what is under-covered: the sink is a pre-authentication audit path rather than an attacker-chosen file, the execution engine is a default-enabled root component the vendor ships, and decoupling the request from the execution removes the pair most pre-auth RCE detection depends on.

The core problem: the injection sink is the appliance's own audit log, reachable before authentication by design and impossible to disable without disabling auditing, and the payload runs from a privileged maintenance script the vendor ships enabled.

The shell has no extension and neither does the URL

Once they hold root the operators stop needing the log path, and the persistence layer is what defeats an indicator list. Both toolsets edit /etc/httpd.conf, switch the PHP engine on, and register a file extension nobody treats as executable. Mandiant observed AddHandler directives mapping .deb and .sig files to the PHP handler plus an AliasMatch rule routing icon requests under /vpn/media/ to a matching .sig file. The other cluster did the same with stylesheets in the LogonPoint directory.

The file on disk carries no executable extension and neither does the URL, while both halves of conventional web shell hunting look for exactly that. One toolset sets the setuid bit on /bin/sh so web server commands run as root; the other writes a superuser named sec_monitor into ns.conf, where it survives a reboot and a patch.

The two CVEs this cluster uses

CVEProductHow this cluster uses itKEV statusSource
CVE-2026-88771
CVSS v4.0 9.5
CWE-20
NetScaler ADC and Gateway, 14.1 before 14.1-73.37 and 13.1 before 13.1-64.23, plus matching FIPS and NDcPP builds Primary entry. Command injected into the audit log via the username field of a failed login, executed later by the root telemetry worker. Hits the default configuration. In KEV, due September 30, 2026 CISA
CVE-2026-88772
CVSS v4.0 9.5
CWE-119
Same builds, where DTLS is enabled on a VPN virtual server Alternate entry. Malformed DTLS record headers corrupt packet engine heap memory, giving a path over UDP/443. Reported exploited in the same campaign Google Cloud

Two 9.5s and one queue

Both CVEs land on 9.5 under CVSS v4.0, both unauthenticated remote code execution, same product, same bulletin, same day, which hands a severity-sorted queue two identical rows. CVE-2026-88771 fires against the default configuration, while CVE-2026-88772 needs DTLS on a VPN virtual server and arrives over UDP/443, a different firewall rule. EPSS inverts the problem rather than fixing it: CVE-2026-88771 carries a probability near one percent, which parks it far down a likelihood-sorted queue, while that same CVE had three weeks of confirmed exploitation behind it and a three-day deadline ahead.

How TRIS scores these appliances

TRIS, the Threat and Risk Intelligence Scoring engine inside CVEasy AI, scores a finding against the appliance it was found on rather than against the advisory. Three layers decide these two.

Exploitation status. CVE-2026-88771 is confirmed in the wild, named by CISA, with a public root cause analysis. CVE-2026-88772 is reported exploited by the responders who worked the intrusions but carries no deadline of its own. Both sit above a proof of concept: a public exploit is a forecast, a responder describing implants pulled off a customer appliance is an observation.

Reachability and preconditions. A Gateway virtual server answering the public internet scores at the top of the band, while a NetScaler load balancing internally with its management interface on a management VRF scores several bands lower on the identical build. CVE-2026-88772 scores only where DTLS is enabled.

Blast radius. The appliance holds LDAP and RADIUS bind credentials, SSL private keys, live session material and a map of the virtual servers behind it, so one compromised appliance is a set of keys plus the floor plan for the network it fronts.

Same CVE, same version string, two appliances: top band ACT on the exposed Gateway with DTLS on, several bands down on the segmented internal load balancer.

What to hunt this week

Start with the handler map rather than the shell: a configuration change is harder to randomise than a filename. Grep /etc/httpd.conf, /nsconfig/httpd.conf and /flash/nsconfig/httpd.conf for application/x-httpd-php, php_flag and AliasMatch, then compare against a known-good build. Any AddHandler or AddType line registering .deb, .sig, .css or .tgz as PHP is the finding, as is any alias pointing a public path into a script directory. Check /bin/sh, where -rwsr-xr-x owned by root means setuid was set for you, and read ns.conf for superuser accounts your team did not create.

Two log notes will save you a wrong conclusion. /var/log/httperror* outlives access log tampering and carries PHP parse errors referencing the disguised extensions. And finding pitboss or NSPPE in an attacker-controlled authentication field tells you a poisoned line reached the log, not that it ran: on a patched appliance it sits inert, on an unpatched one it executed. Grading it blocked because the login failed is the easiest way to misclose this ticket.

Patching does not evict: the fix closes the log injection path and nothing else. A setuid /bin/sh, an extra superuser in the saved configuration, an alias rule in httpd.conf and a web shell under a dotfile name all survive the upgrade and the reboot.

Patch, then assume the box is dirty

1. Upgrade to 14.1-73.37 or later, 13.1-64.23 or later, or 13.1-37.279 for the 13.1 FIPS and NDcPP branches. NetScaler 12.1 and 13.0 are end of life and get no fix, so those need replacing.

2. Take DTLS off any VPN virtual server that does not need it, which removes the CVE-2026-88772 path outright, and confine the management interface to a management network.

3. Rotate everything the appliance held: LDAP and RADIUS bind accounts, SSL private keys and their certificates, every service credential in ns.conf, and active session material. Configuration theft is the objective here, so rotation is the remediation rather than a precaution.

4. Hunt before you patch, then rebuild from a clean image rather than cleaning in place. Patching first destroys the timeline you need to scope the intrusion, and the dropper deletes itself, so its absence proves nothing.

How CVEasy AI surfaces this

CVEasy AI, the number one local-first CTEM platform, ingests the Citrix bulletin, the KEV catalog and the responders' writeups, then runs them through TRIS against your inventory on your own hardware. Nothing leaves your infrastructure to get scored, and the output is an appliance list in remediation order. BASzy replays this cluster's kill chain in authorized engagements, so you learn whether the path is reachable before somebody else does.

Sources: Citrix CTX697096, CISA, Google Cloud Threat Intelligence, Unit 42 and watchTowr Labs.

Two appliances on the same build are not the same finding

TRIS scores every NetScaler in your estate on reachability, preconditions and blast radius, and hands your analyst the list in remediation order.

Related Reading