Introduction In late September 2026, Mandiant Consulting and Google Threat Intelligence Group (GTIG) identified active, in-the-wild exploitation of a zero-day vulnerability (CVE-2026-88772) affecting Citrix NetScaler ADC and NetScaler Gateway appliances. We have observed evidence that organizations in North America and Europe in the government, financial services, technology, education, energy and utilities, and legal and professional services sectors were likely impacted by this exploitation campaign, which has been ongoing since at least early September. According to vendor disclosures, threat actors are also actively exploiting a second zero-day vulnerability (CVE-2026-88771). Exploitation of CVE-2026-88772 bypasses authentication and triggers an unhandled termination of the NetScaler Packet Processing Engine (NSPPE) to establish initial root-level access. Analysis of the actor’s post-exploitation toolkit reveals newly discovered custom PHP web shells, such as WHIPSHOT, capable of disguising Base64-encoded command-and-control (C&C) payloads within native HTTP headers. The toolkit also includes a novel companion Python tunneler, SLAPSHOT, capable of proxying traffic into internal networks for reconnaissance and credential theft. In at least one observed intrusion, the threat actor routed traffic through this proxy to manually conduct internal reconnaissance and credential theft. Citrix issued guidance for customers on newly addressed vulnerabilities and recommended updates here. We encourage defenders to review the Citrix documentation and prioritize patching of these vulnerabilities. As part of this blog, Mandiant is also issuing containment and remediation guidance. Campaign Overview Initial Access During the initial pre-authentication cryptographic handshake the NSPPE parses inbound DTLS record structures. While Google Threat Intelligence Group does not possess exploit code, analysis of frontline telemetry suggests that transmitting specially malformed or fragmented record headers induces heap memory boundary corruption within the packet engine, diverting control flow to execute arbitrary shellcode with root-level operating system privileges on the underlying FreeBSD platform. Successful exploitation attempts generated two log artifacts: 0-PPE-0 : default SSLLOG SSL_HANDSHAKE_FAILURE 0 : SPCBId - ClientIP - ClientPort - VserverServiceIP - VserverServicePort 443 - ClientVersion DTLSv1.0 - CipherSuite "TLS1-AES-256-CBC-SHA" - Session New - Reason "Handshake failure-Internal Error" Figure 1: SSL Handshake Failure recorded in Syslog qat0: Process NSPPE- exit with orphan rings 5:500 pitboss[]: pitboss NOT restarting NSPPE- () Figure 2: NSPPE Process Termination (/var/log/messages) recorded by the FreeBSD kernel and the appliance watchdog daemon (pitboss) Establish Foothold and Persistence Following successful exploitation, the initial web shell payload self-installs by modifying target httpd.conf files, configuring the system to treat specified non-script file types as executable PHP scripts, setting the stage for the deployment of additional custom malware including WHIPSHOT (a PHP web shell) and SLAPSHOT (a Python proxy/tunneler). Web Server Persistence Method A: Package Handler Masquerading (.deb) In one case, the initial installer modified /etc/httpd.conf to have the web server handle .deb files as though they were PHP scripts. php_flag engine on Header set Cache-Control "no-cache" AddHandler application/x-httpd-php .deb Figure 3: Persistence via package handler masquerading This configuration change allowed the actor to stage web shells with deceptive file type extensions in /netscaler/gui/vpn/scripts/linux. Web Server Persistence Method B: Icon Aliasing and Signature File Handler (.sig) In other intrusions, the threat actor implemented a stealthier configuration hook that disguised web shell execution as image requests: php_flag engine on# AliasMatch ^/vpn/media/(.+).ico$ /var/netscaler/gui/vpn/scripts/linux/$1.sig AddHandler application/x-httpd-php .sig Figure 4: Persistence via icon aliasing and signature file handler This configuration directive performs three actions: Enables the mod_php engine. Registers .sig files as executable PHP scripts. Maps any incoming HTTP request ending in .ico under /vpn/media/ directly to a corresponding .sig file with the same base name inside /var/netscaler/gui/vpn/scripts/linux/. For example, clients accessing /vpn/media/e6ee7c85.ico would be served by the dropped PHP web shell e6ee7c85.sig. In at least one case, web server access logs showed GET requests returning HTTP 404 responses, but exhibiting elevated processing durations and multi-kilobyte response sizes. In subsequent days, the actor attempted access to non-existent .sig files, which generated missing-file errors in httperror-vpn logs implying the files were not there. This may be an indication of attackers managing similar web shells in multiple compromised environments. Root Privilege Persistence Although the initial exploitation of CVE-2026-88772 executes with root privileges, subsequent requests processed by the web server (httpd) run under an unprivileged web service context. To establish persistent root-level execution for its web shells, the threat actor leveraged its lightweight installer web shells to assert the setuid (Set User ID) bit on the /bin/sh executable: chmod u+s /bin/sh Figure 5: Command to set the User ID By altering the permissions of /bin/sh, the threat actor was able to ensure that subsequent web requests processed by the web server would execute with the elevated permissions. To apply the /etc/httpd.conf modifications alongside the SUID shell change, the installer initiated a full NetScaler appliance reboot (/netscaler/nsshutdown -R). In other variations of the web shell, the threat actor issued a command to restart the web service directly and assign root setuid (Set User ID) permissions to the /bin/sh executable. system('/bin/httpd -k restart -f /etc/httpd.conf && chmod u+s /bin/sh'); Figure 6: Command to restart the webservice Malware Analysis The threat actor has deployed multiple PHP web shells and a tunneler malware to proxy traffic into the victim organization’s network facilitating internal reconnaissance, lateral movement and credential harvesting. Installer and Standalone web shells Mandiant recovered several lightweight PHP web shells staged in files with .deb and .sig extensions that provide direct command execution and automated appliance persistence. Across directly observed intrusions, the web shell filenames varied between victims. We observed multiple examples of lightweight web shells using variations of “nginstaller,” often followed by a number, as the filename. One example, when executed via command-line interface (CLI), it modifies /etc/httpd.conf, enables setuid root permissions on /bin/sh (chmod u+s /bin/sh), scrubs references to /vpn/scripts/linux from /etc/crontab, and initiates an appliance reboot via /netscaler/nsshutdown -R. Over HTTP, it extracts Base64-encoded commands from the HTTP_NSC_LDAP header, executes them via shell_exec(), and returns Base64-encoded output. Another observed web shell variant that returns a spoofed HTTP 404 Not Found response code. It restarts the Apache daemon (/bin/httpd -k restart -f /etc/httpd.conf) to apply configuration changes and executes incoming payloads using eval(). For evasion, it uses a regular expression (#^.*/vpn/scripts/linux.*\n#m) to systematically scrub its installation path from system `/etc/crontab`. The web shell executes incoming Base64-encoded payloads received via HTTP from the HTTP_NSC_LDAP header directly as PHP using `eval()`. e6ee7c85.sig: A web shell variant that also enforces HTTP 404 Not Found responses, but extracts Base64-encoded payloads from the HTTP_NSC_CLIENTTYPE request header, likewise executing via eval(). WHIPSHOT WHIPSHOT is a PHP web shell disguised as a Debian package and placed in /netscaler/ns_gui/vpn/scripts/linux/. It functions as an HTTP transport bridge for the SLAPSHOT proxy daemon. Key capabilities and behaviors include: HTTP Chunked Transport: It inspects incoming HTTP request headers for sequential parameter blocks (HTTP_X_UX_0 through HTTP_X_UX_95 or HTTP_X_UX). It concatenates these header values, Base64-decodes the resulting stream, and forwards the data over loopback to the SLAPSHOT proxy. Process Management & Launcher: Before establishing a connection, WHIPSHOT checks for the presence of /tmp/.uxdport and /tmp/.uxdlock. If the proxy is not active, WHIPSHOT extracts an embedded Base64 payload containing SLAPSHOT and spawns it in the background using: nohup -c 'import base64;exec(base64.b64decode(""))' /tmp/.uxdport /tmp/.uxdlock > /dev/null 2>&1 Figure 7: Command to execute SLAPSHOT in the background Loopback IPC: Once SLAPSHOT is active, WHIPSHOT reads the dynamic TCP port recorded in /tmp/.uxdport, establishes a socket connection to 127.0.0.1:, and relays the client request. Evasion: WHIPSHOT suppresses standard error reporting (error_reporting(0)) and sets an HTTP 404 Not Found response header while returning the tunneled TCP response within the HTTP body. SLAPSHOT SLAPSHOT is a TCP tunneling tool written in Python. It acts as an internal network bridge, accepting commands from WHIPSHOT and forwarding arbitrary TCP streams to internal hosts. Key capabilities and behaviors include: Dynamic Port Binding & Locking: When launched, SLAPSHOT binds to an ephemeral port on 127.0.0.1, writes the active port number to a specified file such as /tmp/.uxdport, and uses fcntl.flock to secure an exclusive file lock on a lock file such as /tmp/.uxdlock via ensuring only a single instance runs concurrently. Custom Wire Protocol: Communication with the proxy uses a custom binary protocol where each message consists of a 4-byte big-endian length prefix followed by a JSON payload. Supported command actions include: open: Establishes an outbound TCP socket to a target host and port. push: Writes data to an open session. pull: Polls and reads data from an open session socket. exch: Sends and receives C&C data to and from an open session socket. close: Terminates a specified network session. ping: Performs a basic health-check verification. Idle Timeout: The daemon monitors connection activity and automatically closes the individual session sockets after 15 minutes of inactivity. If no active sessions or commands are received within 10 minutes (configurable via the UXD_IDLE_EXIT variable), SLAPSHOT removes its port and lock files, and terminates its process to minimize memory footprint and detection risk. Implications This campaign underscores the continued targeting of edge devices to gain initial access to victim networks, a trend that GTIG has tracked across a range of threat actors. Notably, these vulnerabilities made up about half of the enterprise-related zero-days in 2025. These appliances—including Application Delivery Controllers, VPN gateways, and firewalls—remain attractive targets because they are exposed to the internet, sit outside the reach of endpoint detection and response (EDR) tools, and often store or process credentials that can be used to move deeper into the network. We expect threat actors to continue to exploit vulnerabilities in edge devices, given the proven effectiveness of this tactic. Hunting, Containment, and Remediation Guidance Organizations should begin by analyzing existing logs and configuration files to detect potential signs of compromise. Hunting Strategies Citrix NetScaler ADC Appliances Verify Web Server Configuration: Inspect /etc/httpd.conf on all NetScaler ADC appliances for unauthorized MIME types, script handler directives, or web path aliasing. Any instance of AddHandler or AddType registering non-PHP file extensions (such as .deb, .sig, .html, .rpm, or .tgz) to run as PHP scripts, or any AliasMatch diverting public web paths (/vpn/media/, /vpn/theme/, /vpn/images/) to appliance script directories, indicates compromise. grep -En -i "application/x-httpd-php|php_flag|AliasMatch" /etc/httpd.conf Figure 8: Web path aliasing 2. Audit Appliance Staging and Client Plug-in Directories: Audit the contents of native client plug-in paths (/var/netscaler/gui/vpn/scripts/linux/, /var/netscaler/gui/vpns/scripts/vista/, /var/netscaler/gui/vpns/scripts/mac/) and web asset paths (/netscaler/ns_gui/vpn/media/, /var/vpn/theme/). Legitimate client deliverables in these directories are compiled binaries or archives; any file identified as ASCII text or containing PHP script markers is anomalous. In default installations, these directories contain legitimate compiled client binaries and static web assets. Inspect them for plain-text scripts masquerading under non-script extensions or files containing PHP code: file /var/netscaler/gui/vpn/scripts/linux/* /var/netscaler/gui/vpns/scripts/vista/* /var/netscaler/gui/vpns/scripts/mac/* /netscaler/ns_gui/vpn/media/* 2>/dev/null | grep -E "ASCII text|PHP script" grep -rlE "/dev/null Figure 9: Inspect client plugin paths for scripts masquerading as non-script extensions or files containing PHP code 3. Review Web Server Access & Error Logs: Review /var/log/httperror* for syntax, parse, or execution errors referencing disguised or non-standard file extensions (which persist even if access logs were scrubbed). Audit /var/log/httpaccess.log for requests targeting static media, icons, or script paths returning simulated HTTP 404 status codes or unexpectedly large response payloads. Search access logs for sudden chronological gaps or truncated lines around /vpn/scripts/ or /vpn/media/, which may indicate execution of the actor's regex-based log wiper. grep -E -i "\.(deb|sig|rpm|tgz|sh|so|dat|ico|png|html)" /var/log/httperror* Figure 10: Search for non-standard file extensions and execution errors grep -E "/vpn/media/|/vpn/scripts/|/vpn/theme/" /var/log/httpaccess.log* | awk '$9 ~ /200|404/ && $10 > 5000' Figure 11: Search for unexpectedly large response payloads 4. Check for Ephemeral IPC Artifacts: Inspect the /tmp/ directory on appliances for lock files and port pointer files created by SLAPSHOT. The presence of /tmp/.uxdport or /tmp/.uxdlock indicates active or recent execution of the SLAPSHOT proxy daemon. Responders should record the port contained in .uxdport and inspect the listening process via sockstat -4 -l: ls -la /tmp/.uxdport* /tmp/.uxdlock Figure 12: Search for files created by SLAPSHOT 5. Verify Shell and Binary Permissions: Inspect /bin/sh to confirm unauthorized SUID permissions have not been established. If permissions indicate -rwsr-xr-x with root ownership, the binary has been modified for persistent setuid privilege escalation. ls -l /bin/sh Figure 13: Check for unauthorized SUID permissions 6. Examine Process Execution & Shell History: Inspect active system processes for anomalous Python interpreters executing background commands referencing /tmp/.uxdport or running under nohup. Review /var/log/sh.log for administrative commands executed outside change windows, including forced restarts (/netscaler/nsshutdown -R) and manual Apache restarts (httpd -k restart). ps aux | grep -E "python.*(\.uxd|uxdport|uxdlock|base64)" Figure 14: Inspect system process for anomalous Python interpreters Note: Citrix has published guidance on using its indicator of compromise (IOC) Scanner to identify potential indicators of compromise on an organization’s NetScaler infrastructure. For additional details, refer to the following Citrix documentation: https://docs.netscaler.com/en-us/netscaler-console-service/instance-advisory/security-advisory-dashboard.html https://docs.netscaler.com/en-us/netscaler-console-service/instance-advisory/ioc.html Note: Organizations should apply hunting techniques holistically across their broader infrastructure to identify potential lateral movement originating from the NetScaler infrastructure. These techniques should be applied across the environment, including, but not limited to, other Privileged Access Management (PAM) platforms. Containment and Remediation Strategies Organizations that have not yet applied the latest security updates should immediately assess their exposure and risk. Broad internet isolation or strict IP allow-listing on NetScaler Gateways can create significant disruption for organizations supporting remote workforces through Citrix Virtual Apps and Desktops (formerly XenApp and XenDesktop). For this reason, Mandiant recommends a targeted, phased approach that prioritizes patching while applying appropriate containment and compensating controls based on the organization’s risk profile. Immediate Mitigation Organizations should evaluate the following options based on their risk tolerance, evidence of compromise, and operational requirements. Option 1 — Apply the Latest Citrix Build (Mandiant Recommended) Implement the latest Citrix build that addresses the in-scope vulnerabilities. Organizations should upgrade to the following fixed releases (or later) depending on their current deployment track: NetScaler 14.1 Track: Upgrade to version 14.1-73.37 and later releases. NetScaler 13.1 Track: Upgrade to version 13.1-64.23 and later releases of 13.1. Note: Specific patched builds are also available for 14.1-FIPS and 13.1-FIPS/NDcPP deployments Organizations that cannot locate specific builds in the Citrix customer downloads portal should open a Severity 1 support case with Citrix to confirm and obtain the latest build containing the required fixes. Option 2 — Isolate Compromised or Suspected Appliances For confirmed or suspected compromise, isolate affected NetScaler appliances from the network. This option can introduce significant business disruption, particularly when the appliance provides remote access or other critical services. If the hunting strategies described above identify indicators of compromise, Mandiant recommends implementing the following containment actions: Isolate the node. Immediately remove the confirmed or suspected appliance from the network. Halt HA synchronization. For NetScalers deployed in High Availability (HA) pairs, assess both nodes independently. Disable configuration synchronization until both nodes have been validated to prevent a compromised node from replicating malicious changes, such as modified httpd.conf files, to the standby node. Restrict egress. Block observed threat actor infrastructure and restrict outbound internet connectivity from the appliance. In particular, prevent arbitrary outbound TCP/UDP traffic and block outbound SMTP over TCP/25 unless explicitly required. Review hypervisor network isolation. If the NetScaler runs as a VPX appliance in a virtualized environment, review vSphere vSwitch and Port Group configurations. Confirm that the NetScaler VPX is appropriately segmented and does not share a Layer 2 network with hypervisor management interfaces, such as ESXi vmk0 or vCenter, or other highly sensitive infrastructure tiers. Refer to the Mandiant hardening guidance for vSphere for additional recommendations. Option 3 — Apply Targeted Compensating Controls If immediate patching is not possible, organizations should implement targeted controls to reduce the exposed attack surface until the affected appliances can be updated. The DTLS and UDP/443 controls below are specific to CVE-2026-88772 and should not be relied on to mitigate CVE-2026-88771. Installing a fixed NetScaler build remains required to address both vulnerabilities. Part A — Network Restrictions Disable DTLS where operationally feasible. If patching is delayed, disable DTLS on internet-facing NetScaler Gateway virtual servers where it is not required. In this campaign, the exploit payload is delivered over UDP/443 using Datagram Transport Layer Security (DTLS). Restrict inbound UDP/443 upstream. Block inbound UDP/443 to affected appliances unless DTLS is explicitly required. This control should be implemented on an upstream perimeter firewall or edge router. Relying exclusively on local NetScaler ACLs allows traffic to reach the vulnerable packet-processing engine (nsppe) before it is dropped. Implement upstream IP allow-listing where feasible. Organizations using NetScaler strictly for load balancing, or operating Access Gateways that serve a predictable set of external source IP addresses, should consider upstream network ACLs that drop unauthorized traffic before it reaches the appliance. For public-facing VPNs supporting large remote workforces, this approach may not be practical because dynamic residential IP addresses can create significant administrative and operational overhead. Preserve virtual appliance state for forensic analysis. For NetScalers deployed as virtual appliances, including NetScaler VPX on VMware vSphere or other hypervisors, take a full VM snapshot with memory state included before rebooting whenever operationally possible. Part B — Credential Rotation and Session Termination Organizations should operate under the assumption that credentials stored on a compromised appliance may have been exposed. Credential rotation and session termination should be coordinated across the appliance and connected systems. Revoke active sessions. Invalidate existing administrative, Gateway, and VPN sessions to remove potentially compromised session tokens. For organizations using the appliance as a gateway for Citrix Virtual Apps and Desktops, this should include terminating active ICA/HDX sessions where appropriate. Refer to Citrix CTX584227 for additional guidance. Rotate appliance secrets. Rotate NetScaler administrator credentials, local appliance accounts, Secure Shell (SSH) keys, TLS certificates, and associated private keys. Rotate integration credentials. Rotate LDAP bind and service accounts, RADIUS shared secrets, TACACS credentials, SNMP community strings, and NITRO/application programming interface (API) credentials. Audit downstream Citrix infrastructure. Review systems that the NetScaler communicates with directly, particularly Citrix StoreFront servers, Citrix Delivery Controllers (DDCs), and internal Citrix Virtual Apps and Desktops hosts. Review Windows Event Logs for anomalous interactive logons, unexpected remote desktop protocol (RDP) activity, signs of credential dumping, and other evidence of lateral movement. Organizations should also consider revoking and rotating TLS certificates and associated private keys stored on compromised appliances. Note: Organizations should rotate credentials after the appliance has been successfully patched. Part C — Control Plane Restrictions Organizations should apply additional restrictions to the NetScaler control and management planes. Restrict internet-facing services to required ports and protocols only. Implement default-deny outbound firewall rules for NetScaler appliances. Permit outbound connectivity only to explicitly approved destinations and services, including DNS, NTP, required OCSP/CRL services, approved backend applications, and approved management and security infrastructure. Explicitly block outbound SMTP over TCP/25 unless there is a documented business requirement. Prevent NSIP and management interfaces from being exposed to the internet. Restrict SSH, HTTPS management, and NITRO/API access to dedicated administrative networks, approved jump hosts, and explicitly approved source IP ranges. Part D — Logging and Detection Engineering Detection is a critical component of the response strategy. Mandiant recommends approaching detection across two areas: ensuring the necessary telemetry is available and implementing detections that correlate network, appliance, file system, and identity activity. Logging and Visibility Several of the detections below depend on logs that NetScaler does not forward by default. Before implementing detection logic, confirm that the SIEM receives the following telemetry: NetScaler audit logs (ns.log) through a syslog action, including SSL-related events. The appliance’s FreeBSD system log (/var/log/messages), which records NSPPE termination/crashes and pitboss messages and is not included in standard ns.log forwarding. Web server logs (/var/log/httpaccess.log and /var/log/httperror*), NetScaler Web Logging, or AppFlow telemetry. Because TLS terminates on the appliance, upstream network devices generally cannot inspect HTTP request paths or headers. Firewall or network flow logs for traffic originating from NetScaler NSIP and SNIP addresses. Secret Server or other privileged access management (PAM) audit logs. Detection Engineering Protocol and Traffic Analysis Alert on exploit-pattern DTLS failures. Look for SSL_HANDSHAKE_FAILURE events where ClientVersion is DTLSv1.0 and the reason is Handshake failure-Internal Error. Successful exploitation observed during this activity produced this event. Review individual occurrences and prioritize clusters originating from the same appliance. Correlate DTLS failures with engine termination/crashes. A matching DTLS handshake failure followed within minutes by an NSPPE termination/crash on the same appliance is a strong exploitation signal and should be investigated with high priority. Review unexpected inbound UDP/443. Focus on appliances where DTLS is disabled or not expected. Baseline the sources that normally establish DTLS connections with each Gateway. Because exploitation can require very little traffic, volume-based anomaly detection alone may not identify the activity. Appliance Process and Memory Stability Monitor for NSPPE termination/crashes. Generate high-severity alerts for kernel messages indicating that an NSPPE process exited or was terminated by a signal. Also monitor for the creation of new NSPPE core files under /var/core/. Alert when pitboss does not restart NSPPE. Monitor for pitboss messages containing pitboss NOT restarting NSPPE. Alert on these messages and NSPPE kernel termination/crash events independently rather than requiring both conditions to occur. Correlate with availability events. Treat unexpected HA failovers or appliance restarts on internet-facing Gateways within the same time window as supporting evidence of potential exploitation. File System and Configuration Integrity Monitor critical VPN script paths. Detect the creation, modification, or staging of .sig files, including files such as nsgclient.sig, within VPN-related directories such as: /var/netscaler/gui/vpn/scripts/linux/ /netscaler/ns_gui/vpn/scripts/linux/ /var/netscaler/gui/vpns/scripts/vista/ /var/netscaler/gui/vpns/scripts/mac/ /netscaler/ns_gui/vpn/media/ /var/vpn/theme/ Detect unauthorized web server configuration changes. Monitor /etc/httpd.conf, /nsconfig/httpd.conf, and /flash/nsconfig/httpd.conf for unauthorized modifications. In particular, alert on: The addition or modification of AddHandler application/x-httpd-php .[ext] directives. php_flag engine on configurations or other changes that enable PHP execution. Threat actor activity has included PHP-based web shells using extensions other than .php, and the specific extension may vary by environment. Alias, AliasMatch, or RewriteRule directives that map web asset paths such as /vpn/media/, /vpn/theme/, or /vpn/images/ to script directories or executable files. Check runtime state on a recurring basis. Monitor for: The SUID bit being set on /bin/sh The presence of /tmp/.uxdport or /tmp/.uxdlock Python processes launched through nohup or containing Base64-encoded payloads Unexpected changes to persistent configuration or startup files under /nsconfig/ Egress and Interaction Monitoring Detect suspicious web shell interaction with static or client-script paths. Focus on behavior rather than the requested path alone, since legitimate clients routinely access /vpn/media/ resources. Potential indicators include: 404 responses to /vpn/media/*.ico or /vpn/scripts/ paths that return multi-KB response bodies or exhibit unusually long processing times. “File does not exist” entries in HTTP error logs involving .sig or other non-standard files under /vpn/scripts/. These events may remain visible even when access logs have been modified or cleared. Gaps, malformed entries, or truncated lines in httpaccess.log around requests to /vpn/scripts/ or /vpn/media/. Identify anomalous appliance egress. Monitor outbound connections originating directly from NetScaler appliances and alert when destinations fall outside the organization’s approved egress allow-list. Prioritize activity involving credential vaults and PAM systems, connections to domain controllers over unexpected ports, connections to a large number of internal systems within a short period, and outbound SMTP over TCP/25. Indicators of Compromise (IOCs) Network & Transport Indicators Type Description Indicator Inbound Network Traffic Delivery protocol used for zero-day exploit delivery UDP :443 (DTLSv1.0) HTTP Request Header Inbound command execution header used by nsginstaller.deb HTTP_NSC_LDAP HTTP Request Header Inbound command execution header used by nsgclient.sig HTTP_NSC_CLIENTTYPE HTTP Request Header Chunked Base64 transport headers used by WHIPSHOT HTTP_X_UX / HTTP_X_UX_[0-9]+ URI Path Masquerading icon request URI routed to .sig web shell via AliasMatch /vpn/media/nsgclient.ico / /vpn/media/*.ico URI Path Staging path for malicious PHP web shells on NetScaler Gateway /vpn/scripts/linux/nsginstaller*.deb/vpn/scripts/linux/nsgclient*.deb/vpn/scripts/linux/*.php IPv4 Address Scanning and staging infrastructure 143.198.7.94 IPv4 Address Netscaler exploitation and installation of basic web shell backdoor 157.254.167.12 To assist the wider community in hunting and identifying activity outlined in this blog post, we have included indicators of compromise (IOCs) in a GTI Collection for registered users. File Indicators File Path /tmp/.uxdport SLAPSHOT Active Port Artifact File Path /tmp/.uxdlock SLAPSHOT Process Lock Artifact Detections YARA Rules rule G_APT_Backdoorwebshell_WHIPSHOT_1 { meta: description = "Detects WHIPSHOT PHP webshell tunneling frontend deployed on Citrix NetScaler ADC appliances" author = "GTIG" family = "WHIPSHOT" strings: // Chunked transport headers $sh1 = "HTTP_X_UX" ascii $sh2 = "HTTP_X_UX_" ascii // IPC lock and port pointers to local proxy daemon $si1 = "/.uxdport" ascii $si2 = "/.uxdlock" ascii $si3 = "/tmp/.uxdport /tmp/.uxdlock" ascii // Socket forwarding logic $sf1 = "fsockopen" ascii $sf2 = "127.0.0.1" ascii condition: filesize rule G_APT_Tunneler_SLAPSHOT_1 { meta: description = "Detects SLAPSHOT Python proxy daemon and tunneling tool deployed alongside WHIPSHOT on compromised NetScaler appliances" author = "GTIG" family = "SLAPSHOT" strings: // Lock and port files $ss1 = "/tmp/.uxdport" ascii fullword $ss2 = "/tmp/.uxdlock" ascii fullword $ss3 = "UXD_IDLE_EXIT" ascii fullword $ss4 = "127.0.0.1" ascii // Wire protocol command verbs $sc1 = "\"open\"" ascii fullword $sc2 = "\"conn\"" ascii fullword $sc3 = "\"push\"" ascii fullword $sc4 = "\"pull\"" ascii fullword $sc5 = "\"exch\"" ascii fullword $sc6 = "\"close\"" ascii fullword $sc7 = "\"ping\"" ascii fullword // Protocol parameter names $sp1 = "\"sid\"" ascii fullword $sp2 = "\"host\"" ascii fullword $sp3 = "\"port\"" ascii fullword $sp4 = "\"data\"" ascii fullword condition: filesize rule G_Hunting_Config_NetScaler_PHP_1 { meta: description = "Detects unauthorized Apache configuration directives registering non-standard extensions as PHP scripts, or aliasing web paths to appliance script directories on Citrix NetScaler ADC" author = "GTIG" strings: // NetScaler appliance configuration context markers $ns1 = "/netscaler" ascii nocase $ns2 = "/var/netscaler" ascii nocase $ns3 = "/vpn/" ascii nocase $ns4 = "ns_gui" ascii nocase $ns5 = "" ascii nocase $ns6 = "Listen 81" ascii nocase // Generic type or handler registration mapping non-standard file extensions to PHP $t1 = /Add(Handler|Type)\s+['"]?application\/x-httpd-php['"]?\s+\.([^p\s\r\n][a-zA-Z0-9_-]*|p[^h\s\r\n][a-zA-Z0-9_-]*|ph[^p\s\r\n][a-zA-Z0-9_-]*|php[^s\s\r\n][a-zA-Z0-9_-]*|phps[a-zA-Z0-9_-]+)/ ascii nocase // Diversion of web asset paths (media, theme, help, logon, images) to script staging directories $a1 = "AliasMatch" ascii nocase $a2 = /\^?\/vpn(s)?\/(media|theme|themes|images|help|logon|support)\// ascii nocase $a3 = /\/var\/netscaler\/gui\/vpn(s)?\/scripts\// ascii nocase $a4 = /\/vpn(s)?\/scripts\// ascii nocase // PHP execution flags $p1 = "php_flag engine on" ascii nocase // Exclusions for web pages, markup, and source code $not_html1 = " rule G_Hunting_Backdoorwebshell_NetScaler_C2Headers_1 { meta: description = "Detects standalone PHP webshells deployed on NetScaler appliances extracting commands from custom or native SetEnvIf HTTP headers" author = "GTIG" strings: // NetScaler C2 header patterns (both HTTP_NSC_* and raw NSC_*, covering all native SetEnvIf variables) $h1 = /(HTTP_)?NSC_[a-zA-Z0-9_]+/ ascii $h2 = /(HTTP_)?NSC_(USER|NONCE|LDAP|CLIENTTYPE|FT_HIDE)/ ascii nocase // Specific named NetScaler SetEnvIf headers $hs1 = "HTTP_NSC_LDAP" ascii fullword nocase $hs2 = "HTTP_NSC_CLIENTTYPE" ascii fullword nocase $hs3 = "HTTP_NSC_USER" ascii fullword nocase $hs4 = "HTTP_NSC_NONCE" ascii fullword nocase $hs5 = "HTTP_NSC_FT_HIDE" ascii fullword nocase $hs6 = "NSC_USER" ascii fullword nocase $hs7 = "NSC_NONCE" ascii fullword nocase $hs8 = "NSC_LDAP" ascii fullword nocase $hs9 = "NSC_CLIENTTYPE" ascii fullword nocase $hs10 = "NSC_FT_HIDE" ascii fullword nocase // Dynamic execution sinks $e1 = "eval(base64_decode(" ascii $e2 = "shell_exec(base64_decode(" ascii $e3 = "system(base64_decode(" ascii $e4 = "passthru(base64_decode(" ascii $e5 = "eval(" ascii $e6 = "base64_decode(" ascii $e7 = "shell_exec(" ascii $e8 = "passthru(" ascii $e9 = "system(" ascii $e10 = "exec(" ascii $e11 = "popen(" ascii $e12 = "proc_open(" ascii $e13 = "assert(" ascii // Concealment and response markers $c1 = "http_response_code(404)" ascii $c2 = "REQUEST_METHOD" ascii $c3 = "" ascii $c4 = "" ascii condition: filesize rule G_Hunting_Script_NetScaler_Persistence_1 { meta: description = "Detects appliance staging, installer, and anti-forensic maintenance scripts deployed during NetScaler compromise" author = "GTIG" strings: // Appliance restart / shutdown commands $cmd1 = "/netscaler/nsshutdown" ascii $cmd2 = "nsshutdown -R" ascii // SUID root backdoor creation $cmd3 = "chmod u+s /bin/sh" ascii // Web server reload / restart $cmd4 = "/bin/httpd -k restart" ascii $cmd5 = "httpd -k restart -f /etc/httpd.conf" ascii // Forensic access log scrubbing regex pattern (across any staging path) $scrub1 = /#\^\.\*\/vpn(s)?\/(scripts|media|theme|themes|help|logon)/ ascii // Apache configuration modification strings $cfg1 = "AddHandler application/x-httpd-php" ascii $cfg2 = "AddType application/x-httpd-php" ascii $cfg3 = "php_flag engine on" ascii $cfg4 = "AliasMatch" ascii $cfg5 = "SetEnvIf" ascii condition: filesize Google Security Operations Google Security Operations is continuously developing and updating rules within the Mandiant Intel Emerging Threats rule pack to ensure robust protection for customers. New rules are under active testing for threat activity detailed in this post, detection coverage will be added and deployed across Google SecOps. Acknowledgements This analysis would not have been possible without the assistance of Bella Valdescruz, Bhavesh Dhake, Chris Linklater, Christopher Romano, Geoff Carstairs, Greg Blaum, Josh Thackston, Kimberly Goody, Lianis Oliva, Matthew Quick, Michael Edie, Omar ElAhdan, Peter Ukhanov, Sagun Chetry, Stuart Carrera, Tyler McLellan.