China Chopper has been public for over a decade and remains in use because it is trivial to deploy: the server side is a single line, and the attacker’s client does the heavy lifting by sending code in each request. Small size defeats size-based triage, but the stub text and the structure of the client traffic are both highly regular, which makes it a good candidate for simple, durable rules.
Signals at a Glance
| Signal | Where | ATT&CK |
|---|---|---|
| A script file of roughly 70 to 100 bytes containing eval and a request parameter | File scan, YARA | T1505.003 |
| POST parameters (commonly z0, z1, z2) containing base64 that decodes to server-side code | Web logs with bodies, WAF, IDS | T1505.003 |
| Decoded body beginning with ini_set and set_time_limit calls (PHP variant) | IDS, WAF | T1059 |
| Response wrapped in short start and end markers | IDS, packet capture | T1071.001 |
| Same URI receiving repeated POSTs from a single client | Access logs | T1505.003 |
The Server-Side Stub
The ASPX stub is a single line of JScript using eval over a request item with the literal string "unsafe", which is about 73 bytes with a typical password. PHP and JSP stubs are similar in size. YARA catches it in file scans of web roots:
rule HUNT_ChinaChopper_Server_Stubs
{
meta:
description = "China Chopper style one-line server stubs (tune/validate)"
strings:
$aspx = /<%@\s*Page\s+Language\s*=\s*"Jscript"\s*%>\s*<%\s*eval\s*\(\s*Request\.Item\s*\[\s*"[^"]{1,32}"\s*\]\s*,\s*"unsafe"\s*\)/ nocase
$php1 = /<\?php\s*@?eval\s*\(\s*\$_(POST|REQUEST|GET)\s*\[\s*['"][^'"]{1,32}['"]\s*\]\s*\)/ nocase
$php2 = /@?assert\s*\(\s*\$_(POST|REQUEST)\s*\[/ nocase
condition:
filesize < 2KB and any of them
}
The Client Traffic
The client sends code in the POST body, base64-encoded in numbered parameters. For PHP, the first decoded fragment begins with an @ini_set call, which base64-encodes to a stable prefix. A Suricata rule can alert on that prefix in a request body. Validate against your own traffic and replace the local SID range as needed:
alert http $EXTERNAL_NET any -> $HOME_NET any ( msg:"HUNT China Chopper style POST with base64 ini_set parameter"; flow:established,to_server; http.method; content:"POST"; http.request_body; content:"=QGluaV9zZXQ"; fast_pattern; classtype:web-application-attack; sid:1000601; rev:1; ) # Tune/validate: proxies or TLS termination must expose the decrypted body. # Variants rename parameters or encode differently; treat as one signal.
- Alert on requests whose body contains parameters with long base64 values to a script that your application owners cannot explain.
- Hunt for responses wrapped in short, fixed start and end markers; the client uses them to extract command output.
- Combine with process telemetry: successful use ends in cmd.exe, sh or a PowerShell child of the web server process within seconds of a POST.
- Keep full request logging, including POST bodies where policy allows, on internet-facing servers. Without it, scoping a China Chopper intrusion is slow.
Use the Neo23x0 signature-base China Chopper YARA rules, Emerging Threats open rules for web shell traffic, SigmaHQ web shell rules and CISA advisories on web shell hunting. Variants change parameter names and encoding, so validate every rule against your own environment and pair string matches with process lineage.
Build Detections That Fire
Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.
- Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
- Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
- 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Stay ahead of emerging threats. Get notified when we publish new intelligence reports and advisories.
Subscribe to Alerts