Incident check
PHP2Shell Signs of Compromise: How to Tell Whether Anyone Got In
Updating PHP stops the next attack. It says nothing about the last one. If your server ran a vulnerable build after PHP2Shell went public on October 21, 2026, spend an hour on the checks below before calling the matter closed.
October 23, 2026 · 12 min read
The short answer
Look for the signs Wiz and CrowdStrike published: unusual multipart POST requests followed by memory-limit errors, repeated HTTP 500 responses, oversized or malformed PHPSESSID cookies, PHP workers that keep restarting without explanation, and fatal memory errors ending "in Unknown on line 0". Then check for new PHP files, unknown admin users, strange cron jobs and outbound connections.
On this page
The patch closes the hole, not the case
The PHP project shipped the fixes on October 21, 2026, as releases 8.2.35, 8.3.36, 8.4.27 and 8.5.12. Installing one of them ends the exposure from that moment forward. It does not reach back in time. Any server that answered web requests on an older build after disclosure had a window, and a server on end-of-life PHP may still have one. This page is about the other question: did anyone use it?
Here is the state of play. Within a day of disclosure, Cloudflare and other security firms saw probes hitting their sensors and honeypots, mostly against the session upload-progress code. In NBC News reporting on October 22, several firms said they had yet to see a confirmed successful break-in; pulling one off means chaining bugs together, and it depends on how a given server recycles its workers. As of October 21, CISA's list of known exploited vulnerabilities did not include either CVE. Attempts are under way. Confirmed compromises had not been publicly reported as of October 22. That can change any day.
So the odds favor most small business sites, and odds are not an audit. If you have not updated yet, do that first: confirm your version, then follow the guide for shared hosting or for a VPS or Docker. Hunting for intruders on a server that is still open is mopping during the flood.
Installing the fix ends the exposure. It does not end the question.
Why your access log looks perfectly bored
Most break-ins leave tracks where owners already look: a hammered login page, a new administrator in the dashboard. PHP2Shell sits a floor lower. The flaw is in the PHP interpreter, which parses an incoming request before WordPress, Drupal or any other application gets a say. Wiz Research, which found the bugs, warns that they execute below the application layer, so application logs may hold little context.
CrowdStrike's analysis goes further. On Apache with mod_php, it says, a single anonymous POST request can be enough to make a worker start a shell, with no login, no session and no vulnerable application code involved. The server then answers with an ordinary HTTP 200. In the access log, the attack is one more POST among thousands, marked as a success. A security plugin's activity log is quieter still, because no WordPress code ran for it to watch.
An anonymous POST
No login, no password. One crafted upload request to any PHP page.
PHP parses the upload
Before your site's code runs, PHP reads the multipart body and tracks upload progress.
stops here
Memory runs out mid-step
A fatal error leaves request data half built, or freed memory still referenced.
The next request inherits it
The same worker reuses that stale state, and the attacker's code runs on your server.

So the useful evidence lives elsewhere: the web server's error log, the PHP-FPM log, the process list and the file system. All of them are already on the server, and most logs are rotated away on a schedule, which is the best reason not to wait.
Six tells the researchers have published
Wiz and CrowdStrike have each described what an attempt or a success looks like from the server's side. Treat the list as smoke detectors, not a verdict. Each sign has innocent explanations, and a busy store with a heavy plugin can throw memory errors on a good day. What should worry you is a cluster of them, starting on or after October 21, 2026, that nobody on your side can explain.
| What you see | Where it shows up | Who described it | |
|---|---|---|---|
| Multipart requests, then memory errors | POST requests carrying multipart form data, often to pages with no upload form, followed closely by memory-limit errors | Access log for the requests; web server or PHP error log for the errors | Wiz |
| Repeated 500 responses | Bursts of HTTP 500 from pages that normally load fine, beyond the everyday causes | Status column of the access log; the host's error report | Wiz |
| Odd session cookies | PHPSESSID response cookies that are unexpectedly large or malformed | Proxy, CDN or firewall logs that record headers; rarely in a default access log | Wiz |
| Worker churn | PHP workers exiting and restarting with no deploy, config change or traffic spike to explain it | PHP-FPM log; Apache error log | Wiz |
| A memory error that names no file | A fatal "Allowed memory size exhausted" error ending `in Unknown on line 0` | Web server or PHP error log | CrowdStrike, which calls that ending the tell |
| A web worker starting a shell | Shells or other unexpected programs running as children of PHP-FPM or Apache workers | The process list; endpoint monitoring, if you have it | CrowdStrike |
The memory error is the easiest to search for. An everyday memory error from a bloated plugin names the file and line where PHP ran out, usually a path inside wp-content. The PHP2Shell kind names nothing, because no script had started yet. If your log only has the everyday kind, you have a memory limit problem worth fixing on its own merits, not an intruder.
A server walk-through, log by log
If you or your developer can reach the server over SSH, this is the order we work in. Copy before you search, note every finding with its time, and change nothing until the steps are done. The notes are what you hand the host, the insurer or us.
- 1
Copy the logs before they rotate
Copy the web server, PHP-FPM and system logs from October 20 onward, and older ones if they exist, to a machine off the server. Rotation deletes old logs on a schedule.
- 2
Search the error logs for the nameless memory error
On Debian and Ubuntu the usual files are /var/log/apache2/error.log or /var/log/nginx/error.log; on Red Hat, AlmaLinux and Rocky, /var/log/httpd/error_log. Run `grep "Unknown on line 0"` across them and `zgrep` across the compressed copies.
- 3
Read the PHP-FPM log for workers that died
The FPM log, often /var/log/php8.x-fpm.log on Debian and Ubuntu or under /var/log/php-fpm/ on Red Hat family systems, records each worker that exits. Planned recycling is normal. Bursts of workers exiting with errors, with no restart or deploy behind them, are the churn Wiz describes.
- 4
Line the access log up with the errors
For each suspicious error, open the access log at the same second. Look for POST requests to URLs that take no uploads, repeated from the same addresses, and runs of 500s. A 200 does not clear a request.
- 5
Look for PHP files where none belong
Run `find /var/www -name "*.php" -newermt 2026-10-20` to list PHP files changed since October 20, and treat any PHP file in an uploads folder as suspect. In WordPress, wp-content/uploads holds images and documents, never code.
- 6
Check accounts, keys and scheduled jobs
List CMS administrators (`wp user list --role=administrator` on WordPress), each account's ~/.ssh/authorized_keys, and scheduled jobs: `crontab -l -u www-data` (the web user may be apache or nginx), /etc/cron.d and `wp cron event list`. Anything nobody created is a finding.
- 7
Watch what the web user is doing now
`ps -ef --forest` shows whether PHP-FPM or Apache workers have shells or other programs as children. `ss -tnp` lists open connections and the program behind each. A PHP worker holding a long connection to an unfamiliar address needs an explanation.
On shared hosting, with a control panel and no SSH
You can see less here, and so can an intruder. In cPanel, the Metrics area has Errors for recent error lines and Raw Access for downloadable access logs, and File Manager can sort an uploads folder by date. In Plesk, each domain has a Logs page. If what you need is not exposed, ask the host in writing for the PHP error and access logs from October 20 onward. A status page reading "all systems normal" describes their servers, not your site.
Found something? Keep the evidence before you clean
The instinct on finding a strange file is to delete it. Resist that for ten minutes. The file, its timestamps and the log lines around it are the only record of how the intruder got in, and the host, an insurer and your rebuild plan all need it.
- 1.Take an evidence copy. Download the site files, a database export and the logs to a machine you trust, and leave the originals in place. On a virtual server, a provider snapshot is faster.
- 2.Close the hole if it is still open. Install the fixed PHP release, or apply the interim settings if the update must wait. A site being actively misused can go offline while you work.
- 3.Rotate every secret the server could read. The database password, CMS keys and salts, payment, email and storage API keys, SSH keys, the control panel password and every administrator password, changed from a clean device.
- 4.Rebuild from clean rather than cleaning in place. Use a fresh server or hosting account on patched PHP, install the CMS, theme and plugins from official sources, and restore content from a backup older than the earliest sign you found.
- 5.Tell the people who need to know. Your host, your payment processor if card data passes through the site, and anyone whose accounts may be exposed. If customer personal data sat on the server, ask your attorney about notification duties; DataCram is not a law firm.
Scare or break-in: reading what you found
Most owners will find something odd and nothing sinister. Here is how we sort the two; a finding on the line counts as the worse case.
Probably noise; keep watching
- Memory errors that name a plugin or theme file, the same ones as last month
- Scattered 500s that line up with a plugin update or a backup job
- Worker restarts that match a deploy or a host maintenance window
- Multipart POSTs that your firewall or CDN blocked before they reached PHP
- A clean file check, no new users, no odd cron jobs and no strange processes
Treat the server as compromised
- Memory errors ending in Unknown on line 0, clustered around odd POST requests
- PHP files in an uploads folder, or PHP files changed since October 20 that nobody on your side touched
- An administrator, SSH key or scheduled job no one can account for
- A web worker with a shell or an unfamiliar program as its child process
- Outbound connections from the web user to addresses you cannot identify
One item from the right column is enough to treat the server as untrusted. Once someone has had a shell, they can alter things a file scan will not catch, from a modified system program to a backdoor in the database. Cleaning in place means trusting the intruder's tidiness; rebuilding means trusting your backup. Our WordPress malware removal guide covers the site side of a cleanup.
A clean result today is a date, not a verdict
The left column is good news with an expiry date. CrowdStrike's chief executive put a timescale on the problem in a video interview with CNBC on October 23: the industry, he said, will "see a lot of breaches in coming months" from this flaw. Treat that as a calendar, not a headline. Keep the patch, keep the extra logging, and run these checks again next month. An hour of checking now is cheap next to a breach discovered in the spring.
Handing the investigation to someone else
Most owners reach the line about `ss -tnp` and sensibly decide this is not their weekend. Here is what DataCram does and what it costs.
Not patched yet
The PHP2Shell emergency fix updates PHP to a fixed release, tests the site, checks for the signs on this page and cleans up if anything turns up. WordPress repairs use our fixed Fix It Now prices; anything that is not WordPress gets a quote after a free check.
Found something
Our $349 malware cleanup removes infected files and database entries, changes passwords and keys, closes the way in, and requests a blocklist review if Google or the host flagged the site. Bigger cases go through malware removal and website security.
Broke it while fixing it
A PHP update that leaves a white screen is the $249 site down repair: we get the site up first, then find the cause, take a full backup and write down what failed.
Never again at 2 a.m.
Hosting and maintenance plans cover tested updates, off-server backups and security and uptime monitoring, with no long contract.
Two promises come with every Fix It Now job. We start within one business day of payment. Full refund if we can't fix it. A server fleet or a custom PHP app is scoped after a free check; call (210) 346-0848. Tired of guarding a PHP server at all? The Next.js option keeps the public site off PHP, and our security comparison and web security notes explain why.
Questions owners ask about PHP2Shell
Not reliably. Security plugins run inside WordPress, and PHP2Shell works while PHP is still parsing the request, before WordPress loads. A plugin can still catch what an intruder does afterward, such as a new admin user or a changed file, so its scan is worth running. It cannot see the attack itself or a memory leak. Here is why a fully updated CMS is still exposed.
Not on that evidence alone. CrowdStrike's analysis says a successful attack on Apache with mod_php can return an ordinary HTTP 200, so the access log can look normal. Check the error logs for memory errors ending in Unknown on line 0, the PHP-FPM log for unexplained worker churn, and the file system for PHP files nobody put there.
No. Most memory errors come from a heavy plugin, theme or import, and they name the file where PHP ran out. The one CrowdStrike flags ends in Unknown on line 0, because no PHP file was running yet. That ending, clustered around odd POST requests after October 21, 2026, is the version to worry about.
Start no later than October 20, 2026, when the PHP project gave advance notice, and go as far back as your logs reach. Attack attempts were reported from public disclosure on October 21 onward, so the days since then matter most. Copy the logs before you start, because rotation deletes older files on a schedule.
If the server ran a vulnerable PHP version on the open internet after October 21, yes. Wiz showed the bugs can leak process memory without running code, and that memory can hold passwords, tokens and API keys. A leak leaves no files behind, so a clean scan cannot rule it out. New keys cost an afternoon; stolen ones cost more.
No. The website health check is a quick outside look at security basics, speed, search visibility and on-page issues, with a plain-English fix for each failed check. It cannot read the PHP version behind a server that hides it, and it is not a vulnerability scan. For PHP2Shell, check the version directly.
Keep reading
- Emergency servicePHP2Shell Emergency Fix: We Patch Your PHP, Test the Site and Check for IntrudersWe update PHP to a fixed release, test every page, check for signs of a break-in and clean up if needed. WordPress fixes from $249, paid on the page.
- The long-term fixNobody Can Exploit PHP on a Site That Does Not Run It: The Next.js Way Out of PHP2ShellKeep WordPress private behind a Next.js front end, or drop PHP for Athena CMS. What each removes, what carries over, the honest limits and the prices.
- Shared hostingPatching PHP2Shell on Shared Hosting: cPanel, Plesk and Managed WordPressOn shared hosting your host patches PHP for PHP2Shell. How to confirm it in cPanel or Plesk, what to ask for in writing, and what breaks on newer PHP.
- Server patch guidePatch PHP2Shell on a VPS or in Docker: Packages, Restarts and ProofPatch PHP2Shell on Debian, Ubuntu, RHEL, Docker, FrankenPHP and LiteSpeed: which packages, which restarts, and how to prove the fix landed.
- Stopgap settingsPHP2Shell Temporary Mitigations: What Buys Days and What Only Looks BusyEvery interim PHP2Shell setting from the PHP project, where each line goes, what it blocks, what it misses, and why a firewall rule is only a stopgap.
- CMS owners' briefingPHP2Shell on WordPress, Drupal and Joomla: Your CMS Is Current. Is Your PHP?Why a fully updated WordPress, Drupal or Joomla site can still fall to PHP2Shell, why security plugins cannot fix it, and what to update first.
- Everything in PHP2ShellSee the section
Find out whether it was noise or a break-in
Tell us what you found, or what you are afraid you might find. We will say which it looks like, what we would do next and what it costs, before any work starts.
Which of these sounds like you? (pick any)
Rather talk now? Call (210) 346-0848.