Article Banner

Citrix NetScaler Zero-Days Exploited to Plant Disguised Web Shells and Tunnel Into Internal Networks

For most of September, attackers broke into Citrix NetScaler without a password. Many companies use this gateway to let staff and partners reach inside systems from the internet. Google's Mandiant team and Palo Alto Networks' Unit 42 found that the attackers used two flaws before Citrix had a fix. Even fully updated gateways were open to them.

Think of it like the crew in Ocean's Eleven taking over the casino's camera room. Once they control the system everyone trusts, they can move through the building unseen. The attackers hid small remote-control programs in files dressed up as harmless icons and page styles. Then they gave themselves full control of the device. Installing Citrix's fix later does not remove them.

The gateway sits between the internet and the inside network, so one break-in exposes much more than one device. In at least one case, the attackers used it as a tunnel to explore inside systems and steal passwords. In another, they copied the device's settings, which hold saved passwords and the secret keys behind its security certificates. Mandiant names government, finance, tech, education, and legal firms among the likely victims.

Hunting Controls & Observations

Citrix disclosed eight NetScaler ADC and Gateway vulnerabilities on September 27, 2026 (bulletin CTX697096), and CISA added two of them to its Known Exploited Vulnerabilities catalog the same day. CVE-2026-88772 (CVSS v4.0 9.5) is a memory overflow in the pre-authentication DTLS handshake: malformed DTLS records sent over UDP/443 corrupt heap memory in the NetScaler Packet Processing Engine (NSPPE) and run shellcode as root. Mandiant and the Google Threat Intelligence Group (GTIG) date this exploitation to early September 2026. CVE-2026-88771 (CVSS v4.0 9.5) is an input-validation flaw that affects default configurations; Unit 42 documents a three-stage log-poisoning chain that turns it into unauthenticated command execution, and Rapid7 saw the first attempt on September 20. Neither Mandiant nor Unit 42 names a threat actor. Unit 42's Cortex Xpanse counted 50,277 potentially vulnerable exposed instances on September 27. Because TLS terminates on the appliance, upstream devices never see the HTTP paths and headers the web shells use, and standard log forwarding misses /var/log/messages, where the crash evidence lands. Organizations can detect this activity through multiple telemetry sources:

  • Appliance Controls: NetScaler ns.log forwarded over syslog (Splunk Add-on for Citrix NetScaler, citrix:netscaler:syslog; the Microsoft Sentinel Citrix ADC connector, Syslog table), /var/log/messages for kernel and pitboss crash records, the Apache httpaccess.log and httpaccess-vpn.log web logs or AppFlow, core files in /var/core/, and file integrity monitoring on /etc/httpd.conf, /nsconfig/httpd.conf, and the VPN script and media directories
  • Network Controls: Inbound UDP/443 at the perimeter, NSIP and SNIP flow logs, and firewall records for connections the appliance opens to internal hosts or to SMTP on TCP/25
  • Endpoint Controls: Microsoft Defender for Endpoint or other EDR on the Windows hosts behind the gateway (StoreFront, Delivery Controllers, VDA hosts, domain controllers, and PAM servers), where inbound connections from the appliance surface
  • Identity & Access Controls: Logons sourced from NetScaler addresses, Gateway and VPN session records, and use of the LDAP bind, RADIUS, and TACACS credentials stored in the appliance configuration

Behavioral Indicators of Attack

The following behaviors, drawn from the Mandiant, Unit 42, and Rapid7 analyses, outlast any single indicator because the operators rotate hosting infrastructure and name their implants after legitimate Citrix files:

  • A DTLSv1.0 SSL_HANDSHAKE_FAILURE logged with reason "Handshake failure-Internal Error", followed within minutes by an NSPPE crash and a pitboss "NOT restarting NSPPE" record that leaves the appliance degraded. This is the footprint of the CVE-2026-88772 heap corruption.
  • A failed Gateway login whose logged text contains pitboss PPE missed too many heartbeats NSPPE; followed by a shell command. The root-run Perl script /netscaler/ns_monuploadd_err.pl parses the poisoned ns.log line and executes everything after NSPPE, which pulls a Base64 dropper back out of the User-Agent stored in /var/log/httpaccess-vpn.log and pipes it to sh or php.
  • New AddHandler, php_flag engine on, Alias, or AliasMatch directives in httpd.conf that make .deb, .sig, .ico, or .css requests run as PHP, followed by an httpd restart or a quiet kill -HUP reload.
  • Requests to /vpn/media/*.ico, /vpn/scripts/linux/, or /logon/LogonPoint/custom/receiver.min*.css that return HTTP 404 or 200 with multi-kilobyte bodies and long processing times, the response pattern of a web shell hiding behind a fake error page.
  • The setuid bit set on /bin/sh (chmod u+s or chmod 6555), so that any command the unprivileged web server runs executes as root.
  • A nohup Python process running exec(base64.b64decode(...)) with the hidden files /tmp/.uxdport and /tmp/.uxdlock, the SLAPSHOT tunneler listening on a loopback port that the WHIPSHOT web shell relays into.
  • The NetScaler appliance opening connections to internal hosts, PAM or vault systems, domain controllers outside its configured authentication traffic, or SMTP on TCP/25. Mandiant observed manual internal reconnaissance and credential theft through the SLAPSHOT proxy in at least one intrusion.
  • An archive of /flash/nsconfig written into the public /var/netscaler/gui/vpn/ directory, where an unauthenticated GET /vpn/c returns the device configuration, encrypted admin and bind passwords, and TLS private keys.

MITRE Enterprise ATT&CK Tactics and Techniques

None of the three reports publishes ATT&CK identifiers, so the mapping below is inferred from the behaviors each vendor describes. It follows the kill chain from reconnaissance through exfiltration:

Controls' Observables

Appliance Controls

The appliance's own logs carry the exploitation evidence, but only if ns.log, /var/log/messages, and the web logs leave the device before an attacker can truncate them.

  • DTLS handshake failure plus packet-engine crash: SSL_HANDSHAKE_FAILURE with DTLSv1.0 and "Handshake failure-Internal Error", correlated with qat0: Process ... NSPPE-## exit with orphan rings and pitboss "NOT restarting NSPPE" on the same appliance. Unexpected HA failovers and new files in /var/core/ support the finding.
    • Related MITRE Techniques: T1190
    • Detection Difficulty: LOW
  • Poisoned pitboss messages: "missed too many heartbeats" or "unexpectedly died" lines in ns.log that carry shell metacharacters or commands after NSPPE.
    • Related MITRE Techniques: T1190, T1059.004, T1140
    • Detection Difficulty: LOW
  • Web server configuration drift: New AddHandler application/x-httpd-php, php_flag engine on, or AliasMatch directives in /etc/httpd.conf, /nsconfig/httpd.conf, or /flash/nsconfig/httpd.conf.
    • Related MITRE Techniques: T1505.003, T1036.008
    • Detection Difficulty: MEDIUM
  • Runtime artifacts: A setuid /bin/sh, the files /tmp/.uxdport and /tmp/.uxdlock, and nohup Python processes executing Base64. These checks run on the box; no default log carries them.
    • Related MITRE Techniques: T1548.001, T1059.006, T1090.001
    • Detection Difficulty: MEDIUM

Web & Application Controls

The web shells hide in plain sight behind Citrix-looking paths, so response size and status code separate them from real client downloads.

  • Masqueraded web shell requests: 404 or 200 responses over 5,000 bytes for /vpn/media/, /vpn/scripts/, or /vpn/theme/ paths, and any request to /logon/LogonPoint/custom/receiver.min*.css.
    • Related MITRE Techniques: T1505.003, T1036.008, T1071.001
    • Detection Difficulty: MEDIUM
  • Staged configuration download: Any request for /vpn/c, which serves the archived nsconfig without authentication.
    • Related MITRE Techniques: T1074.001, T1552.001
    • Detection Difficulty: LOW
  • Encoded User-Agents: User-Agent strings that hold long Base64 blobs, such as the dropper staged in httpaccess-vpn.log.
    • Related MITRE Techniques: T1140
    • Detection Difficulty: MEDIUM

Network Controls

A NetScaler talks to a known, short list of internal services. Anything outside that list deserves a look.

  • Appliance-initiated admin sessions: NSIP or SNIP addresses connecting to internal hosts on SSH, SMB, RPC, RDP, or WinRM, or to SMTP on TCP/25.
    • Related MITRE Techniques: T1090.001, T1041
    • Detection Difficulty: LOW
  • Unexpected inbound DTLS: UDP/443 traffic to Gateways that do not need DTLS, or to appliances where it was disabled.
    • Related MITRE Techniques: T1190
    • Detection Difficulty: MEDIUM

Identity & Access Controls

The stolen configuration turns into identity abuse downstream, often weeks after the appliance compromise.

  • Reuse of appliance service credentials: LDAP bind, RADIUS, or TACACS accounts from ns.conf authenticating from hosts other than the NetScaler.
    • Related MITRE Techniques: T1552.001
    • Detection Difficulty: HIGH
  • Unusual logons on the Citrix tier: RDP or network logons to StoreFront, Delivery Controllers, VDA hosts, and PAM platforms that originate from the appliance.
    • Related MITRE Techniques: T1090.001
    • Detection Difficulty: MEDIUM

Insights and Recommendation

Organizations that ran a vulnerable NetScaler in September face root-level control of their remote-access gateway, theft of every secret it stores, and a tunnel into the internal network. The staged nsconfig archive alone hands over the LDAP, RADIUS, and TACACS bind passwords and the TLS private keys, which lets an intruder impersonate the Gateway and authenticate to the directory long after the appliance is rebuilt. Because the web shells survive patching and Citrix has since disclosed a third exploited NetScaler flaw (CVE-2026-88779, fixed in 14.1-73.41 and 13.1-64.28), patch status says little about whether a device is clean.

As of 2026-10-10, AbuseIPDB scores all eleven addresses checked from the three reports at 24% confidence or lower. Nine of the eleven sit on commercial hosting, including four of Unit 42's addresses on BL Networks; 66.227.183.84 is a residential Charter Communications line; and 104.28.215.137 belongs to Cloudflare. GreyNoise has not observed 143.198.7.94, Mandiant's scanning and staging host, scanning the internet as of the same date. Reputation feeds would not have flagged this campaign, which is why the queries below hunt behavior rather than addresses.

Security teams should upgrade to the builds that fix CVE-2026-88779 (14.1-73.41 or 13.1-64.28 and later, which supersede the CVE-2026-88771 and CVE-2026-88772 fixes), but first preserve a VPX memory snapshot, a technical support bundle, the packet-engine core dumps, and the remote syslog, because patching and rebooting destroy evidence. On every appliance exposed since September 4, run the Mandiant checks: grep -En -i "application/x-httpd-php|php_flag|AliasMatch" /etc/httpd.conf, ls -l /bin/sh for a -rwsr-xr-x mode, ls -la /tmp/.uxdport* /tmp/.uxdlock, and a search of /var/netscaler/gui/ and /netscaler/ns_gui/ for PHP content in non-PHP files (T1505.003, T1548.001, T1090.001). Citrix recommends redeploying a new, updated instance for any appliance with evidence of compromise rather than cleaning it in place. Forward ns.log, /var/log/messages, and the web logs to a SIEM, block inbound UDP/443 where DTLS is not required, keep the NSIP and management interfaces off the internet, and deny the appliance any outbound path outside its documented allow-list, including SMTP on TCP/25. After patching, revoke Gateway and VPN sessions and rotate every credential the configuration holds: admin and local accounts, SSH keys, TLS certificates and private keys, LDAP bind accounts, RADIUS and TACACS secrets, SNMP strings, and NITRO API credentials. Then hunt the StoreFront, Delivery Controller, VDA, and PAM tier for logons and connections that originate from the appliance.

Source and Credits

This summary is based on Mandiant and Google Threat Intelligence Group's research article "Defending Against Active Exploitation of Citrix NetScaler ADC and Gateway Appliances" published on September 29, 2026.

Additional analysis comes from Unit 42 (Palo Alto Networks), "Threat Brief: NetScaler Zero Days CVE-2026-88771 and CVE-2026-88772 Exploited in the Wild" published on September 30, 2026 and updated through October 8, 2026, and from Rapid7, "Zero-Day Exploitation of Citrix NetScaler ADC and Gateway: CVE-2026-88771 and CVE-2026-88772" published on September 28, 2026 and updated October 6, 2026.

Live-status corroboration for selected indicators was provided by Darknet CTI corroboration (Focused Hunts), drawing on AbuseIPDB, GreyNoise, and AlienVault OTX as checked on 2026-10-10. This is a secondary source used only to confirm current reputation and hosting context; all threat behavior and indicators derive from the Mandiant, Unit 42, and Rapid7 reports.

Threat Hunting IOCs & Queries

The operators rotate hosting and name their implants after Citrix client files, so treat the indicators below as seeds for scoping and rely on the behavioral queries for detection. None of the published addresses passed the reputation filter for an indicator sweep, so this post carries no IOC sweep query. Mandiant publishes additional indicators in a GTI Collection on VirusTotal, and Citrix documents an IOC scanner on the NetScaler Console security advisory dashboard.

Known Indicators of Compromise

  • File Hashes (SHA256):
    • ae22ef2517b5c0fb47f78745b9cb5260acee0e751b89bcd354640ff8bc8d29ec – nsg64.deb RC4-encrypted PHP web shell (Unit 42) (AlienVault OTX: listed in 2 public payload-delivery pulses, as of 2026-10-10)
    • 1bd314b661396c7086f6367fbbb48025e03ca2de69c073d53a8b0a38aa5fbb7d – Base64 payload delivered through the CVE-2026-88771 log-poisoning chain (Unit 42)
    • 79c65fa04541032e251fa4796b97800374b63c7982593dd1a2e0db605d429186 – decoded shell script that drops .ctxs.receiver and patches httpd.conf (Unit 42)
    • ed082f744f035035900f67edf438f2f7d0528ac501234f63d476d65273cdb9a1 – .ctxs.receiver web shell (Rapid7)
  • IP Addresses:
    • 157.254.167.12 – exploitation and web shell backdoor (Mandiant) (AbuseIPDB 0% confidence, 0 reports, TierPoint data center, as of 2026-10-10)
    • 143.198.7.94 – scanning and staging (Mandiant) (AbuseIPDB 18% confidence, 4 reports, DigitalOcean; GreyNoise: not observed scanning, as of 2026-10-10)
    • 193.149.176.207 – requested nsgbuild.deb daily from September 15 to 24, most of the observed staging requests (Unit 42) (AbuseIPDB 0% confidence, BL Networks, as of 2026-10-10)
    • 162.33.178.9 – requested nsgbuild.deb and nsgsupport.deb on September 14 (Unit 42) (AbuseIPDB 0% confidence, BL Networks, as of 2026-10-10)
    • 104.248.244.66 – fingerprinting on August 21 and 22 (Unit 42) (AbuseIPDB 0% confidence, DigitalOcean, as of 2026-10-10)
    • 77.83.199.39 – fingerprinting on August 21 and 22 (Unit 42) (AbuseIPDB 12% confidence, 3 reports, HZ Hosting, as of 2026-10-10)
    • 45.61.136.143 – Unit 42 IOC list (AbuseIPDB 0% confidence, BL Networks, as of 2026-10-10)
    • 216.245.184.164 – Unit 42 IOC list (AbuseIPDB 0% confidence, BL Networks, as of 2026-10-10)
    • 66.227.183.84 – Unit 42 IOC list (AbuseIPDB 0% confidence, residential Charter Communications line, as of 2026-10-10)
    • 104.28.215.137, 104.28.247.136 – Unit 42 IOC list; Unit 42 reports Cloudflare WARP addresses requesting staged .deb files from September 9 to 11 (AbuseIPDB lists 104.28.215.137 under Cloudflare, Inc., as of 2026-10-10). Shared address space: scope with it, do not block on it.
    • 149.104.78.208 – CVE-2026-88771 command injection attempt on September 20 (Rapid7) (AbuseIPDB 0% confidence, LightNode data center in Japan, as of 2026-10-10)
  • File Paths:
    • /var/netscaler/gui/vpn/scripts/linux/ (nsginstaller*.deb, nsgclient*.deb, nsg64.deb, *.sig, *.php) – web shell staging
    • /var/netscaler/logon/LogonPoint/custom/.ctxs.receiver – PHP web shell served as receiver.min.css
    • /var/netscaler/gui/vpn/c – archived /flash/nsconfig, downloadable at /vpn/c
    • /tmp/.uxdport, /tmp/.uxdlock – SLAPSHOT port and lock files
    • /var/netscaler/.ns_suidcmd – SUID binary used by nsg64.deb to escalate
    • /netscaler/ns_monuploadd_err.pl – legitimate script that executes the poisoned log text
  • HTTP Artifacts: Request headers NSC_LDAP, NSC_CLIENTTYPE, X-UX and X-UX-[0-9]+; cookie CsrfToken=e826d7ddf3c85920 with NSC_TASS (per-implant); nsg64.deb RC4 key 7489a0f93c67fa5cdaeb4b921d90594d; URIs /vpn/media/*.ico and /logon/LogonPoint/custom/receiver.min.<hex>.css
  • YARA Rules (Mandiant): G_APT_Backdoorwebshell_WHIPSHOT_1, G_APT_Tunneler_SLAPSHOT_1, G_Hunting_Config_NetScaler_PHP_1, G_Hunting_Backdoorwebshell_NetScaler_C2Headers_1, G_Hunting_Script_NetScaler_Persistence_1

Notes: Indicators are current as of the cited reports (September 28 to October 8, 2026). Live-status annotations reflect AbuseIPDB, GreyNoise, and AlienVault OTX corroboration on 2026-10-10, a secondary source distinct from the cited reports.

NetScaler Appliance Reaching Internal Admin Services

Priority: High - Observed by Mandiant in this campaign on a KEV-listed flaw; Command and Control impact through the SLAPSHOT internal proxy; Tier 1 endpoint telemetry
Behavior Targeted: NetScaler NSIP or SNIP addresses opening connections to internal hosts on SSH, SMTP, RPC, SMB, RDP, or WinRM, the footprint of an operator tunneling through SLAPSHOT to explore the network and steal credentials.
MITRE ATT&CK: T1090.001, T1041
Telemetry Required: Firewall or NetFlow records between the appliance segment and the internal network mapped to the Splunk CIM Network_Traffic data model; Microsoft Defender for Endpoint on the internal Windows hosts (DeviceNetworkEvents). Both queries read the appliance addresses from a list you maintain: a Splunk lookup netscaler_addresses.csv with field ip, and a Sentinel watchlist NetScalerAddresses.
Expected Results: Connections from an appliance address to admin-service ports on hosts it does not load-balance, especially domain controllers, PAM or vault servers, or many distinct hosts in a short window.
False Positive Likelihood: MEDIUM - A Gateway with the RDP proxy feature legitimately reaches TCP/3389 on published desktops, and SNIP addresses reach any back-end service the ADC load-balances on these ports.
Tuning Guidance: Exclude the back-end servers and ports defined in your load-balancing and RDP proxy configuration. Add your PAM and vault ports to the port list. Defender advanced hunting keeps 30 days, so the KQL window stops at 30 days; widen the Splunk window to cover your full exposure since September 4.
Detection Difficulty: EASY - Once the appliance's legitimate back ends are excluded, any remaining admin-port session from the NetScaler stands out.

Splunk SPL Query

| tstats summariesonly=false count dc(All_Traffic.dest_ip) AS distinct_dests values(All_Traffic.dest_ip) AS dests
    min(_time) AS first_seen max(_time) AS last_seen
    from datamodel=Network_Traffic.All_Traffic
    where earliest=-45d All_Traffic.dest_port IN (22,25,135,445,3389,5985,5986)
    by All_Traffic.src_ip All_Traffic.dest_port
| rename All_Traffic.* AS *
| lookup netscaler_addresses.csv ip AS src_ip OUTPUT ip AS netscaler_ip
| where isnotnull(netscaler_ip)
| sort - distinct_dests
| convert ctime(first_seen) ctime(last_seen)

Microsoft KQL Query (Defender/Sentinel)

let NetScalerIPs = _GetWatchlist("NetScalerAddresses") | project SearchKey;
DeviceNetworkEvents
| where Timestamp > ago(30d)
| where ActionType == "InboundConnectionAccepted"
| where RemoteIP in (NetScalerIPs)
| where LocalPort in (22, 25, 135, 445, 3389, 5985, 5986)
| summarize Connections = count(), DistinctHosts = dcount(DeviceName), Hosts = make_set(DeviceName, 50),
    FirstSeen = min(Timestamp), LastSeen = max(Timestamp) by RemoteIP, LocalPort
| order by DistinctHosts desc

Masqueraded Web Shell and Staged Configuration Requests

Priority: Medium - Observed in this campaign on a KEV-listed flaw; Persistence-stage impact; artifact-level durability on Citrix web paths
Behavior Targeted: Requests that reach a PHP web shell hidden behind Citrix-looking paths (/vpn/media/*.ico, /vpn/scripts/, /vpn/theme/, /logon/LogonPoint/custom/receiver.min*.css) and downloads of the staged configuration archive at /vpn/c.
MITRE ATT&CK: T1505.003, T1036.008, T1074.001
Telemetry Required: NetScaler web logs (httpaccess.log, httpaccess-vpn.log) or AppFlow records forwarded to the SIEM. In Splunk they must be mapped to the CIM Web data model; in Sentinel they land in the Syslog table through the Citrix ADC connector. TLS terminates on the appliance, so upstream proxies and firewalls cannot supply this data.
Expected Results: 404 or 200 responses over 5,000 bytes on these paths, any hit on receiver.min under /logon/LogonPoint/custom/, requests for .sig files, and any request for /vpn/c.
False Positive Likelihood: MEDIUM - Real Citrix Gateway client packages under /vpn/scripts/ return large 200 responses.
Tuning Guidance: Hash the client packages your Citrix build ships and exclude their exact URLs; keep every 404 over the size threshold, because a genuine missing file returns a small error page. Raise or lower the 5,000-byte threshold to match your error-page size. The Sentinel parser assumes the Apache combined log layout; adjust the extract() patterns if your syslog format differs.
Detection Difficulty: MODERATE - Requires web logs that most deployments do not forward by default, and the paths themselves are legitimate.

Splunk SPL Query

| tstats summariesonly=false count avg(Web.bytes_out) AS avg_bytes_out dc(Web.src) AS sources
    min(_time) AS first_seen max(_time) AS last_seen
    from datamodel=Web.Web
    where earliest=-45d Web.status IN ("200","404")
        (Web.url="*/vpn/media/*" OR Web.url="*/vpn/scripts/*" OR Web.url="*/vpn/theme/*"
        OR Web.url="*/logon/LogonPoint/custom/*" OR Web.url="*/vpn/c")
    by Web.dest Web.url Web.status
| rename Web.* AS *
| where avg_bytes_out > 5000 OR match(url, "receiver\.min|\.sig|/vpn/c$")
| sort - avg_bytes_out
| convert ctime(first_seen) ctime(last_seen)

Microsoft KQL Query (Defender/Sentinel)

Syslog
| where TimeGenerated > ago(45d)
| where SyslogMessage has_any ("/vpn/media/", "/vpn/scripts/", "/vpn/theme/", "/logon/LogonPoint/custom/", "/vpn/c")
| extend Url = extract(@'"(?:GET|POST|HEAD) (\S+)', 1, SyslogMessage),
    Status = extract(@'" (\d{3}) ', 1, SyslogMessage),
    BytesOut = toint(extract(@'" \d{3} (\d+)', 1, SyslogMessage))
| where Status in ("200", "404")
| where BytesOut > 5000 or Url matches regex @"receiver\.min|\.sig|^/vpn/c$"
| summarize Requests = count(), AvgBytesOut = avg(BytesOut), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated)
    by HostName, Url, Status
| order by AvgBytesOut desc

Log-Poisoning Command Injection (CVE-2026-88771)

Priority: Medium - Observed in this campaign on a KEV-listed flaw; Execution-stage impact with a durable behavior pattern; product-specific telemetry only
Behavior Targeted: Failed-login text that imitates a pitboss "missed too many heartbeats" or "unexpectedly died" message and appends a shell command after NSPPE, which ns_monuploadd_err.pl then executes as root on an unpatched appliance.
MITRE ATT&CK: T1190, T1059.004, T1140
Telemetry Required: NetScaler ns.log over syslog (Splunk Add-on for Citrix NetScaler, citrix:netscaler:syslog; or generic syslog); Microsoft Sentinel Citrix ADC connector (Syslog table).
Expected Results: The injected command text, such as a grep of httpaccess-vpn.log piped through Base64 decoding into sh or php, or a tar czf /var/netscaler/gui/vpn/c archive command, with first and last seen times and the appliances that logged it.
False Positive Likelihood: LOW - Genuine pitboss messages do not carry shell metacharacters. Unit 42 notes that a match on a patched appliance shows an attempt, not a compromise; on an unpatched appliance, treat it as executed.
Tuning Guidance: The capture starts at the first ;, |, &, or $ after NSPPE; add characters if your logs show other separators. Widen the window back to September 4 to cover the full exposure period.
Detection Difficulty: EASY - The poisoned line is distinctive once ns.log reaches the SIEM.

Splunk SPL Query

index=* (sourcetype="citrix:netscaler:syslog" OR sourcetype="syslog") earliest=-45d
    "pitboss" "NSPPE" ("missed too many heartbeats" OR "unexpectedly died")
| rex field=_raw "NSPPE[^;|&$]*(?<injected>[;|&$].*)$"
| where isnotnull(injected)
| stats count min(_time) AS first_seen max(_time) AS last_seen values(host) AS appliances by injected
| sort - count
| convert ctime(first_seen) ctime(last_seen)

Microsoft KQL Query (Defender/Sentinel)

Syslog
| where TimeGenerated > ago(45d)
| where SyslogMessage has "pitboss" and SyslogMessage has "NSPPE"
| where SyslogMessage has_any ("missed too many heartbeats", "unexpectedly died")
| extend Injected = extract(@"NSPPE[^;|&$]*([;|&$].*)$", 1, SyslogMessage)
| where isnotempty(Injected)
| summarize Count = count(), FirstSeen = min(TimeGenerated), LastSeen = max(TimeGenerated), Appliances = make_set(HostName, 20)
    by Injected
| order by Count desc

DTLS Exploitation Followed by a Packet-Engine Crash (CVE-2026-88772)

Priority: Medium - Observed in this campaign on a KEV-listed flaw; Initial Access stage; distinctive crash pattern in product-specific telemetry
Behavior Targeted: A DTLSv1.0 handshake failing with "Handshake failure-Internal Error", NSPPE exiting with orphan rings, and pitboss declining to restart the packet engine on the same appliance within 15 minutes.
MITRE ATT&CK: T1190
Telemetry Required: NetScaler ns.log and /var/log/messages over syslog (Splunk citrix:netscaler:syslog or syslog; Sentinel Syslog table). Mandiant notes that standard forwarding misses /var/log/messages, so add it to the appliance's syslog configuration first.
Expected Results: A 15-minute window on one appliance with two or more of the three signals, or any pitboss "NOT restarting NSPPE" record.
False Positive Likelihood: LOW - Internal-error DTLS failures are uncommon, and a packet engine that pitboss refuses to restart points to a crash, not routine load.
Tuning Guidance: Correlate hits with unexpected HA failovers and new files in /var/core/. Widen the 15-minute bin if your syslog pipeline delays /var/log/messages.
Detection Difficulty: MODERATE - The signal is clear, but only if crash logs leave the appliance.

Splunk SPL Query

index=* (sourcetype="citrix:netscaler:syslog" OR sourcetype="syslog") earliest=-45d
    (("SSL_HANDSHAKE_FAILURE" "DTLSv1.0" "Internal Error") OR "NOT restarting NSPPE" OR "exit with orphan rings")
| eval signal=case(match(_raw, "SSL_HANDSHAKE_FAILURE"), "dtls_handshake_internal_error",
    match(_raw, "NOT restarting NSPPE"), "pitboss_no_restart", true(), "nsppe_orphan_rings")
| bin _time span=15m
| stats count values(signal) AS signals dc(signal) AS signal_types by _time, host
| where signal_types >= 2 OR isnotnull(mvfind(signals, "pitboss_no_restart"))
| sort - _time

Microsoft KQL Query (Defender/Sentinel)

Syslog
| where TimeGenerated > ago(45d)
| where (SyslogMessage has "SSL_HANDSHAKE_FAILURE" and SyslogMessage has "DTLSv1.0" and SyslogMessage has "Internal Error")
    or SyslogMessage has "NOT restarting NSPPE"
    or SyslogMessage has "exit with orphan rings"
| extend Signal = case(SyslogMessage has "SSL_HANDSHAKE_FAILURE", "dtls_handshake_internal_error",
    SyslogMessage has "NOT restarting NSPPE", "pitboss_no_restart", "nsppe_orphan_rings")
| summarize Events = count(), Signals = make_set(Signal), SignalTypes = dcount(Signal)
    by HostName, Window = bin(TimeGenerated, 15m)
| where SignalTypes >= 2 or set_has_element(Signals, "pitboss_no_restart")
| order by Window desc

Note: These queries were generated with AI assistance and are a starting point for threat hunting and detection rule considerations.

Back to Hunting off the Red