
PHP2Shell (CVE-2026-109618, CVE-2026-109619): Attacked Before the CVE, Blocked Before the Fix, No Mass Exploitation Yet
At 10:37 UTC on Wednesday, October 21, a server protected by the CrowdSec WAF blocked a request aimed at a PHP flaw that had no published CVE. The CVE records appeared 2 hours and 57 minutes later. PHP’s fix followed 26 minutes after that.
CVE-2026-109618 and CVE-2026-109619, together PHP2Shell, are two CVSS 9.2 flaws in PHP itself that let an unauthenticated attacker run code on the server. Five days of CrowdSec Network data show attempts that began before disclosure, but no mass exploitation: no public exploit works reliably on a default PHP setup yet. Upgrade to 8.5.12, 8.4.27, 8.3.36, or 8.2.35 while that holds.
→ You can track CVE-2026-109618 here and CVE-2026-109619 here.
We published an article on Friday that covered the exposure, upgrade paths, and how virtual patching keeps PHP websites online while you upgrade. This follow-up is the data: five days on the CrowdSec Network, phase by phase.
What did the first five days of PHP2Shell look like?
- 3 h 47 min: how long the CrowdSec virtual patch was live before PHP released its fix.
- 17: IP addresses blocked before the two CVEs were even published.
- 1,730: CrowdSec sensors, run by 771 organizations in 73 countries, that blocked PHP2Shell requests from Wednesday to Sunday.
- 1,187: IP addresses seen sending PHP2Shell requests by Sunday night.
- About 130: new sources a day from Friday to Sunday, flat through the weekend.
- 0: publicly confirmed compromises through PHP2Shell, as far as we know.
How we counted: from October 21 to 25, 2026 (UTC), the CrowdSec Network recorded 10,073 signals from 1,187 unique IP addresses sending requests that match the PHP2Shell exploitation patterns. Each signal is one attempt blocked by a sensor running the WAF rules crowdsecurity/vpatch-CVE-2026-109618 and crowdsecurity/vpatch-CVE-2026-109619 (first released October 21, 10:13 UTC).
How did PHP2Shell exploitation unfold, phase by phase?
Details and a proof of concept leaked on Tuesday, October 20th. CrowdSec turned them into a virtual patch that was live before the CVEs were published. Wednesday, in UTC:
- 10:13 The CrowdSec virtual patch goes live on the Hub.
- 10:37 A CrowdSec sensor blocks its first PHP2Shell request.
- 13:34 CVE-2026-109618 and CVE-2026-109619 are published. 17 IP addresses are already blocked.
- 14:00 PHP releases 8.5.12, 8.4.27, 8.3.36 and 8.2.35. 18 IP addresses already blocked.
- 16:25 The rule is split into one rule per CVE.
From there, read by who showed up rather than by the calendar, the 1,161 IP addresses the two Hub rules blocked fall into four phases.
Phase 1, probing (Wednesday, 10:37 to 16:25 UTC). 72 addresses, a quiet mix: 40% had attacked React2Shell (CVE-2025-55182) in the previous 90 days, a quarter were new to the network, and most touched a single sensor. The exception arrived at 15:23: a mass scanner hosted in Bulgaria that went on to reach 246 sensors.
Phase 2, first scanning (Wednesday 16:25 to Thursday 10:00). 238 addresses at a steady pace, mostly trying the easier of the two bugs, the session upload route of CVE-2026-109619. The first tools that openly call themselves PHP2Shell scanners appear.
Phase 3, the re-tasked fleet (Thursday, 10:00 to 15:00). 405 addresses in five hours, the largest phase. 72% had attacked React2Shell, 30% sat on Microsoft Azure, and only 9% were new. This was not a crowd discovering PHP2Shell; it was one known fleet switching targets in a morning.
Phase 4, the commodity trickle (Thursday 15:00 to Sunday). The fleet never came back. The 446 addresses that followed were a different crowd: 6% React2Shell veterans, 2% on Azure, 30% never seen before. They brought the widest scanners, one reaching 726 sensors. PHP2Shell had joined the background scanning that runs against every known bug, and through the weekend, new addresses held at about 130 a day, against 612 on Thursday: no second wave.

Why hasn’t PHP2Shell turned into mass exploitation?
Because no public exploit works reliably on a default PHP setup, and attackers are still trying to build or find one. As Sansec puts it after testing the code circulating online: “The public exploits do not work against a default PHP installation.” VulnCheck counted hundreds of proof-of-concept repositories on GitHub, very few of them legitimate; one got past a standard memory protection, but only on PHP 8.4.26 in one specific setup. Reliable exploits exist, but not in public, and VulnCheck reports no confirmed successful exploitation in the wild.
The CrowdSec data from October 21 to 25 shows attackers testing, not harvesting:
- Half of the 1,187 sources sent a single request in five days, and 82% sent three or fewer.
- Known PHP2Shell techniques need several requests against the same server, so a real attempt repeats itself. Only 24 sources ever sent ten or more requests to the same sensor.
- 78% of the sources that sent a user agent posed as a web browser.

What would tell us PHP2Shell is turning into mass exploitation?
Any one of these signals would change our reading. With 70% of websites running PHP, a reliable public exploit would put every unpatched server in range at once. React2Shell showed how fast that goes: its count of sources grew 27-fold between its second and sixth day.
- A public exploit that works on default PHP. Expect the curve to bend within days.
- New sources breaking out above the 130 a day seen since Friday.
- More repeat tries. Since Thursday, 7 to 11 sources a day have sent ten or more requests to one sensor.
- The memory bug (CVE-2026-109618) is catching up. 147 sources have tried it so far, against 429 for the session route.
If part of your PHP estate cannot be patched this week, decide now what you will take offline the day the first signal fires.
What should you do about PHP2Shell this week?
Our recently published article covers the upgrade path for each PHP version and how to set up the CrowdSec WAF. Since then:
- Patch, then restart. Upgrade to 8.5.12, 8.4.27, 8.3.36, or 8.2.35, or your distribution’s fixed package, and restart every PHP worker: a patched binary does nothing for workers still running the old one. Check the version your web server reports.
- Keep the CrowdSec WAF with virtual patching rules on until the last server is upgraded. Docker, Kubernetes, and Windows installs do not update the Hub on their own; update them by hand.
- Block known senders. The PHP2Shell Attackers blocklist presented on Friday grows as senders are confirmed. With 30% of the weekend’s newcomers never seen before, keep the WAF rules on too.
- Watch the Live Exploit Tracker. It shows the exploitation phase and the addresses involved as activity changes.
What this data does not show
- A blocked request is an exploitation attempt. CrowdSec cannot see whether the same sources succeeded elsewhere, and sees nothing before the first rule went live at 10:13 UTC on October 21.
- 1,187 IP addresses are not 1,187 attackers, and the sensors are a sample, not a census, mostly in Germany, France, and the United States.
- The four phases are our reading of when addresses first appeared, not the Live Exploit Tracker’s phases. They cover the two Hub rules only; target paths and user agents are recorded for about four in ten sources.
- One sensor can protect several websites, so “the same sensor” is not always the same site.
Related CrowdSec threat alerts
- PHP2Shell virtual patching: keep your PHP websites online while you upgrade, our Friday article
- Week 50 — CVE-2025-55182, React2Shell remote code execution and Week 51 — the React2Shell surge: the campaign whose infrastructure drove PHP2Shell’s third phase
Written by Matthieu M., Data Team Lead, CrowdSec. Published October 26, 2026.