How Attackers Are Hiding PHP Web Shells Inside HTTP Cookies on Linux Servers

Introduction

Microsoft's Defender Security Research Team has documented a stealthy new approach attackers are using to run PHP web shells on Linux servers. Rather than embedding commands in URLs where they can be easily spotted, threat actors are routing execution through HTTP cookie headers — a blind spot in most monitoring setups. The shells are also paired with cron jobs to ensure they survive deletion and persist across reboots.

What Happened

Traditional PHP web shells are relatively easy to detect: they accept commands via URL parameters or POST request bodies, both of which are logged and monitored by web application firewalls (WAFs). The technique Microsoft identified flips this around.

These newer shells check for a specific cookie value on each incoming request. If the right cookie is present, its value is decoded and executed. From the outside, the HTTP request looks like any other page visit — there's nothing in the URL or request body to raise a flag.

To make things worse, attackers are using scheduled cron jobs to re-deploy the web shell automatically if it gets detected and removed. This means simply deleting the file isn't enough — the infection comes back within minutes.

Why It Matters

This technique bypasses two layers of detection that most server operators rely on:

  • WAF rules that look for commands in URLs and POST bodies won't fire — there's nothing suspicious in either place
  • Web server access logs typically don't record cookie values, so there's no trail in the logs either

Combined with cron-based persistence, this creates a scenario where a compromised server can stay compromised for a long time without anyone noticing. It's a low-noise, high-durability foothold.

Who Is Affected

Any Linux server running PHP-based web applications is potentially at risk — this includes WordPress, Joomla, Laravel, and custom PHP apps alike. The technique is particularly dangerous on servers where:

  • File uploads are permitted without strict execution controls
  • Cron jobs are not regularly audited
  • Cookie values are not included in web server logging

How to Protect Yourself

1. Hunt for suspicious PHP files

Look for files in your webroot that reference cookie variables alongside dynamic execution functions:

# Files referencing cookies + dynamic execution
grep -Erl '\$_COOKIE.*(eval|system|exec|shell_exec|passthru)' /var/www/html --include="*.php"

# Files using base64_decode with cookie input
grep -rl "base64_decode.*COOKIE\|COOKIE.*base64_decode" /var/www/html --include="*.php"

# Recently modified PHP files (last 7 days)
find /var/www/html -name "*.php" -mtime -7 -ls

2. Audit all cron jobs

# Check every user's crontab
for user in $(cut -f1 -d: /etc/passwd); do
  crontab -l -u "$user" 2>/dev/null && echo "--- $user"
done

# Check system-wide cron directories
cat /etc/cron.d/*
cat /etc/crontab
ls -la /var/spool/cron/crontabs/

3. Enable cookie logging in your web server

By default, cookie values aren't logged. Add them so you have visibility:

# nginx — add to your log_format block
log_format detailed '$remote_addr - [$time_local] "$request" $status '
                    'cookie="$http_cookie"';
access_log /var/log/nginx/access.log detailed;
# Apache
LogFormat "%h %t \"%r\" %>s \"%{Cookie}i\"" cookie_log
CustomLog /var/log/apache2/access.log cookie_log

⚠️ Cookie logs will also capture session tokens. Restrict log file access accordingly.

4. Block PHP execution in upload directories

# nginx
location ~* /uploads/.*\.php$ {
    deny all;
    return 404;
}

5. Deny cron access for the web server user

echo "www-data" >> /etc/cron.deny

6. Set up file integrity monitoring

apt install aide -y
aide --init
mv /var/lib/aide/aide.db.new /var/lib/aide/aide.db
# Daily check
echo "0 3 * * * root aide --check" >> /etc/cron.d/aide-check

Source

Microsoft Details Cookie-Controlled PHP Web Shells Persisting via Cron on Linux Servers — The Hacker News