Incident check

Was my server compromised through PHP2Shell? A checklist

Short answer

Exploitation attempts began on 17 October 2026, before the fix was public. After patching, review logs from that date for memory-limit errors, HTTP 500 bursts and worker crashes; look for new .php files, cron jobs and users; and rotate secrets your PHP apps held in memory, because PHP2Shell can leak them.

On this page

Why you should check even after patching

Two facts make PHP2Shell different from a routine update:

  • Attacks started early. Amazon’s honeypots recorded an exploitation attempt on 17 October 2026, four days before public disclosure. Exploitation attempts have been reported widely since.
  • Secrets can leak without a break-in. Researchers showed PHP2Shell can expose live PHP worker memory — which may hold database passwords, API keys and other visitors’ session tokens — even without running code on the server.

So patching closes the door, but you still need to check whether anyone came in, and rotate what might have been read. Work through the steps in order. Commands assume a typical Linux server; adjust log paths for your setup.

1. Review logs from 17 October onward

The published reports describe these warning signs:

  • Unusual multipart requests followed by memory-limit errors or repeated HTTP 500 responses
  • Unusually large PHPSESSID cookies
  • Unexplained PHP worker restarts or crashes

Search PHP and web-server error logs for memory exhaustion and worker crashes:

# PHP "Allowed memory size ... exhausted" errors
sudo grep -h "Allowed memory size" /var/log/php*-fpm.log /var/log/nginx/error.log /var/log/apache2/error.log /var/log/httpd/error_log 2>/dev/null | tail -50

# PHP-FPM workers that died unexpectedly
sudo grep -hE "exited on signal|SIGSEGV|SIGBUS" /var/log/php*-fpm.log 2>/dev/null | tail -50

Look for bursts of HTTP 500 responses, then inspect the requests around them:

# 500s per day in an Nginx/Apache "combined" access log (status is field 9)
sudo awk '$9 == 500 {split($4, d, ":"); print d[1]}' /var/log/nginx/access.log | sort | uniq -c

Access logs rarely include cookies. If you use Cloudflare or another WAF/CDN, check its firewall events for blocked PHP2Shell rules and oversized cookie headers.

2. Hunt for web shells

Attackers who get code execution usually drop a small PHP file to keep access. Look for PHP files created or changed since 17 October:

sudo find /var/www -type f -name '*.php' -newermt '2026-10-17' -printf '%TY-%Tm-%Td %TH:%TM  %p\n' | sort

PHP files in upload or cache directories are a red flag on any framework:

sudo find /var/www -type f -name '*.php' \( -path '*/uploads/*' -o -path '*/storage/*' -o -path '*/cache/*' \)

Search for common web-shell patterns (expect some false positives in legitimate libraries — review each hit):

sudo grep -rlE "eval\s*\(\s*(base64_decode|gzinflate|str_rot13)|(system|passthru|shell_exec)\s*\(\s*\\\$_(GET|POST|REQUEST)" /var/www --include='*.php'

WordPress users can also run wp core verify-checksums and wp plugin verify-checksums --all — see the WordPress guide.

3. Check for persistence

# Scheduled tasks for the web user and root
sudo crontab -u www-data -l 2>/dev/null; sudo crontab -l 2>/dev/null; ls -la /etc/cron.*

# Recently added users and SSH keys
sudo awk -F: '$3 >= 1000 {print $1}' /etc/passwd
sudo find / -name authorized_keys -newermt '2026-10-17' 2>/dev/null

# Unexpected services and outbound connections
systemctl list-unit-files --state=enabled --type=service | head -50
sudo ss -tupn state established

Anything you can’t explain deserves a closer look before you move on. (On RHEL-family systems the web user is usually apache, not www-data.)

4. Rotate the secrets PHP held

Because PHP2Shell can expose worker memory, rotate secrets even if you found nothing, if your server was exposed and unpatched for any length of time:

  • Database and cache (Redis/Memcached) passwords
  • API keys for payment, email, storage and cloud services
  • Application secrets: APP_KEY and session secrets (Laravel), salts (WordPress), JWT signing keys
  • Admin passwords for your CMS and hosting panel
  • Then invalidate sessions so stolen session cookies stop working

5. If you find evidence of compromise

  1. Preserve evidence first. Copy logs and suspicious files somewhere safe before you clean up or rotate anything.
  2. Isolate the affected server — take it off the public internet if you can.
  3. Rebuild rather than clean. Restore from a backup taken before 17 October 2026, on a patched PHP, then reapply content changes carefully.
  4. Rotate every credential the server could access.
  5. Check your legal duties. If personal data may have been accessed and you’re subject to the GDPR, you generally have 72 hours from becoming aware of a breach to notify your data protection authority (Article 33).
  6. Get professional help for anything beyond a single small site — incident response is a specialist job.

Need help with the patching side, or a second pair of eyes on what you found? Patch help — we’ll refer you to incident-response specialists if it’s more than a patch.

Shayan Abbas writes these PHP security guides from the official advisories and vendor guidance listed below, and updates them when those change. About this site

Sources

  1. The Hacker News — PHP issues emergency patches (signs of earlier compromise)
  2. Help Net Security — exploitation attempt recorded on 17 October
  3. Qualys — memory disclosure and post-remediation verification
  4. GDPR Article 33 — notification of a personal data breach

Know about the next critical PHP bug first

Short, plain-English alerts when a serious PHP vulnerability or fix lands — with what to patch and how. About two emails a month.