Pulp sci-fi illustration of a mainframe vault door cracked open by a glowing green snake of code

PHP2Shell: patch PHP now, then go hunting

ALERT · Exploitation attempts seen. Last updated 23 October 2026. See the Alert Tracker

Two critical bugs in PHP itself, now nicknamed PHP2Shell, can give an unauthenticated attacker code execution on a web server. Fixed releases came out on 21 October, a honeypot was hit four days before that, and the only real fix is to upgrade.

Updated 23 October 2026, adding Amazon’s indicators, NVD scores, researcher credits, a draft hunt and corrected wording, and removing an unsourced ‘several hundred’ figure.

What happened

On 21 October 2026 the PHP project shipped PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. These are security releases for two flaws in the engine rather than in any framework or plugin, which is why this one lands on everybody’s desk at once.

  • CVE-2026-109618, ‘RCE via OOM corruption’ (GHSA-w8hw-w9fx-j79w). If PHP runs out of memory at exactly the wrong moment, it can bail out while internal request data is only half set up. The clean-up code then treats that junk as valid. The advisory describes several ways to push a request into that state with crafted multipart uploads that still look as if they are within PHP’s limits.
  • CVE-2026-109619, ‘RCE via stale global state’ (GHSA-6wmf-4rv5-p3rp). A fatal error at the wrong point can leave a worker holding pointers into memory that belonged to an earlier request. The next request served by that worker can then use freed memory. It’s a classic use-after-free, spread across two HTTP requests.

The PHP project rates both Critical, with a CVSS v4.0 score of 9.2. NVD has since added its own CVSS v3.1 scores: 9.8 for CVE-2026-109618 and 8.1 for CVE-2026-109619. You may have seen 10.0 quoted on social media. That figure came from a leak on 20 October and, according to the PHP Foundation, it is wrong. The leak carried the CVE numbers, a wrong release time and that wrong score, but no technical detail. It was still enough to pull the release forward by a day. The Foundation credits researchers at Calif, Wiz and OpenAI with the reports that made the full impact of the memory bug clear.

Apache with mod_php is the worst case. There, the Foundation says, full remote code execution was demonstrated with default settings, triggered before any application code runs. Your WordPress hardening doesn’t come into it. PHP-FPM is no refuge either: the Foundation says code execution was also confirmed there, through application-level code paths.

Is it being exploited?

Attempts, certainly. Amazon Threat Intelligence saw an attempt against its MadPot honeypots on 17 October, four days before disclosure, and more between 02:00 and 08:00 UTC on 21 October, from what Amazon believes were several actors. It now says ‘PHP2Shell is now seeing broad exploitation attempts in the wild’, while adding that ‘it’s unclear if any of these attempts would have succeeded in real-world systems’. watchTowr reports in-the-wild exploitation through its own honeypot network from 21 October.

CISA’s alert of 21 October said it had not observed exploitation at the time of publication, and neither CVE was in its Known Exploited Vulnerabilities catalogue when we checked on 22 October. It still urges immediate patching. I wouldn’t wait for KEV to catch up. KEV is a scoreboard, not a forecast.

Who is affected

According to php.net, the short answer is any PHP installation that serves web requests. That covers PHP-FPM, Apache with mod_php, php-cgi, FrankenPHP and LiteSpeed. Any version below the fixed releases on each branch is vulnerable. watchTowr also says older unsupported branches, going back to PHP 5, are affected.

In practice, look for it in these places:

  • Shared and managed hosting. cPanel, Plesk and the like often let you choose a PHP version per site. Check which one each site actually uses. ‘Pretty sure it’s on 8.3’ is a hunch, not an inventory.
  • WordPress, Drupal, Magento, Moodle and every other PHP application. The bug is in the runtime, so a fully patched CMS on an old PHP build is still exposed.
  • Containers. Base images pin a PHP version. Rebuild and redeploy, and don’t assume a restart pulls in anything new.
  • Appliances and vendor products that embed PHP. CISA points out that PHP is often a component of other software, so you may not see it directly.

What to do now

  1. Upgrade internet-facing systems first. The targets are 8.5.12, 8.4.27, 8.3.36 or 8.2.35 or later. The PHP project’s position is blunt: there are no complete mitigations, and updating is the only safe choice.
  2. Check what is really running. php -v tells you about the command-line binary. Your web server may load something else entirely, especially on hosts with several versions installed. Check the FPM pool or Apache module too, for example with php-fpm -v. A phpinfo() page shows the web-facing version, but delete it as soon as you’ve read it. A forgotten phpinfo.php is a free lunch, and somebody else will eat it.
  3. Distribution packages are fine, but check them properly. Linux distributions and LTS vendors got the patches in advance. A backported package may keep an older-looking version number, so look for the CVE IDs in the package changelog or the vendor advisory rather than trusting the version string. The PHP project also warned that the volunteer-run rpms.remirepo.net repository would not have updates on release day.
  4. End-of-life branches. PHP 8.1 and older get no official release. The security team has published minimal source backports for 7.4, 8.0 and 8.1 to help people who build from source, and some vendors offer backported fixes. CISA’s advice for anything that can’t be updated immediately, and for 8.1 and earlier, is to take it offline until it can be. Note too that 8.2 itself reaches end of life on 31 December 2026.
  5. If you truly cannot patch today, php.net lists stopgaps that narrow specific attack paths. They don’t make you safe. For CVE-2026-109618, set memory_limit=-1 administratively, lower post_max_size (8M without uploads, 32M with them), and enforce request size, field, part and header limits at the proxy. For CVE-2026-109619, set session.upload_progress.enabled=0 in php.ini or the pool configuration, not via ini_set() or .user.ini; on 8.5, also set fatal_error_backtraces=0. Restart every worker afterwards. Amazon suggests considering blocking multipart file uploads where you can’t patch, once you know what that would break. CISA adds that a web application firewall ‘may provide some protection’. That’s lawyer-grade hedging; take the ‘may’ literally.
  6. Look for compromise as well as patching. The NCSC says that if you can’t update or take a system offline straight away, you should check it for evidence of compromise and installed backdoors before you upgrade or mitigate. Amazon goes further and recommends starting investigations from at least 17 October, not from the disclosure date, since compromise may predate the advisory.

How to hunt for exploitation

What Amazon has published

Amazon lists six IP addresses seen attacking its sensors. Its own caveat matters: they ‘include shared anonymization infrastructure and are not exclusive to this threat activity’, and it advises organisations to investigate any sightings rather than block them. A hit is a reason to look harder at that server, not proof of anything.

IP addressFirst seen by Amazon
103.216.220.9217 October 2026
31.223.184.16621 October 2026
37.19.200.521 October 2026
134.209.159.6421 October 2026
103.114.163.18821 October 2026
95.217.98.3721 October 2026
Source: AWS Security Blog. Investigate, don’t block.

Amazon’s other lead is more useful: look for POST requests with the PHP_SESSION_UPLOAD_PROGRESS string in form uploads. That is PHP’s default field name for its upload-progress feature, the same feature the CVE-2026-109619 stopgap switches off. Two practical notes. Ordinary access logs don’t record request bodies, so you need a WAF, ModSecurity audit log or reverse proxy that captures them. And some applications use upload progress legitimately, so learn what normal looks like before you chase every match.

Behaviour after the break-in

Signatures will always arrive late, so behaviour is the better bet. A PHP worker or Apache process that suddenly starts sh, curl or wget is worth a look on any day. CISA flags exactly this: ‘PHP worker processes launching shells or downloading tools’.

That’s the basis of our Hunt of the week #1: possible PHP RCE follow-on activity. Be clear about its status: it is an untested draft. The Sigma rule passes sigma check and converts without errors to Defender, Splunk and Elastic queries (Elastic users should check the regex, as the hunt notes explain), but nothing in it has yet been run against live or lab data. Treat it as a starting point, not a finished detection.

  • Start with the Sigma rule for Linux process_creation. It is the portable version, and it works with free telemetry: auditd or Sysmon for Linux on the web servers. Falco and Wazuh, both free, can watch for the same behaviour, though this rule isn’t written for them.
  • Convert it with the free sigma-cli for whatever you run. The repository includes a field mapping for Elastic, whose free tier handles the ES|QL, EQL or Lucene output.
  • Already pay for Microsoft Defender XDR or Splunk? Hand-written KQL and SPL versions sit in the same folder. They are less tested than the rule: neither has even been parsed by Kusto or Splunk.

It maps to MITRE ATT&CK T1190 (Exploit Public-Facing Application), T1059.004 (Unix Shell), T1105 (Ingress Tool Transfer) and T1505.003 (Web Shell).

Know its limits. It’s a generic web-shell and RCE follow-on pattern, not a signature for PHP2Shell. It covers Linux only, and it will be noisy wherever PHP legitimately shells out. mail() calling sendmail is the usual suspect. Tune it before you trust it, and if you do test it, we’d like to hear how it behaved. The full repository, with licences and the rest of the Hunt Lab, is at github.com/CyberThreatNet/hunt-lab.

What to tell the board

This is unauthenticated remote code execution in a runtime that sits under a large share of the public web, possibly including systems you didn’t know ran PHP. Scanning and exploit attempts began before the fix existed. The useful questions aren’t about patch percentages. Start with inventory: do you know every PHP instance you own, including those inside vendor products and hosted sites? Then speed, because internet-facing systems needed patching in hours, not inside the usual 30-day window. Finally, has anyone looked for signs of compromise going back to 17 October? If the answer on inventory is ‘not sure’, that asset-inventory gap is the real finding, and it will outlast this bug.

For a hunt you can run against a related threat, see Plex2Shell implants in the Plex Codecs folder. More is in Threats & Vulnerabilities and Hunt Lab.

Sources