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
  1. The patch closes the hole, not the case
  2. Why your access log looks perfectly bored
  3. Six tells the researchers have published
  4. A server walk-through, log by log
  5. Found something? Keep the evidence before you clean
  6. Scare or break-in: reading what you found
  7. Handing the investigation to someone else

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.

1

An anonymous POST

No login, no password. One crafted upload request to any PHP page.

2

PHP parses the upload

Before your site's code runs, PHP reads the multipart body and tracks upload progress.

Patched PHP stops here
3

Memory runs out mid-step

A fatal error leaves request data half built, or freed memory still referenced.

4

The next request inherits it

The same worker reuses that stale state, and the attacker's code runs on your server.

The damage happens while PHP is still parsing the request, before the site's own code runs; patched PHP stops it at step two.
Muddy bare footprints on a torn strip of paper beside a green circuit board, with a brass magnifying glass held over the board's main chip
The footprints exist; they are simply not upstairs in the application, where the security plugin keeps watch.

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.

Published warning signs of PHP2Shell activity, as of October 23, 2026
What you seeWhere it shows upWho described it
Multipart requests, then memory errorsPOST requests carrying multipart form data, often to pages with no upload form, followed closely by memory-limit errorsAccess log for the requests; web server or PHP error log for the errorsWiz
Repeated 500 responsesBursts of HTTP 500 from pages that normally load fine, beyond the everyday causesStatus column of the access log; the host's error reportWiz
Odd session cookiesPHPSESSID response cookies that are unexpectedly large or malformedProxy, CDN or firewall logs that record headers; rarely in a default access logWiz
Worker churnPHP workers exiting and restarting with no deploy, config change or traffic spike to explain itPHP-FPM log; Apache error logWiz
A memory error that names no fileA fatal "Allowed memory size exhausted" error ending `in Unknown on line 0`Web server or PHP error logCrowdStrike, which calls that ending the tell
A web worker starting a shellShells or other unexpected programs running as children of PHP-FPM or Apache workersThe process list; endpoint monitoring, if you have itCrowdStrike

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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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.

Free · No obligation

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.

CallGet a quote