Hunting Leaked PHP2Shell RCE Across Open Directories (CVE-2026-109618, CVE-2026-109619)

Hunting Leaked PHP2Shell RCE Across Open Directories (CVE-2026-109618, CVE-2026-109619)

Published on

Hunting Leaked PHP2Shell RCE Across Open Directories (CVE-2026-109618, CVE-2026-109619)

Two critical PHP remote code execution bugs, CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2, leaked before their scheduled patch on October 21, 2026 at 14:00 UTC.

A large share of the web runs on PHP, so the exposed surface is big. And attackers wasted no time: php2shell scanning hit our honeypots about 20 minutes after the patch shipped. What we haven’t seen yet is a successful exploit.

So far, we’ve seen attempts and staged tooling, but no confirmed compromises, and no vendors have reported any. Below we map how much PHP is exposed, why a version number in a header is a weak way to judge real risk, and what turned up in attacker open directories through AttackCapture.

What happened

On October 20 the PHP security team put out an advance notice: an emergency release coming, two critical bugs, no technical detail, patch set for October 21 at 14:00 UTC. They kept the option to ship sooner if the details got out or exploitation turned up.

The details leaked. Over October 20 and 21 the two CVEs and a nickname, "php2shell", started circulating, and several researchers confirmed the bugs are real:

PHP shipped the fix on October 21 at about 14:00 UTC in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. End-of-life branches get no upstream release, though distro security teams and backport repos cover most older versions.

The scramble was real even without a confirmed compromise. Oh Dear's uptime monitoring recorded 18.8% of the sites it watches going offline at the peak, against 0.9% a week earlier, as operators pulled their own sites down rather than wait to get hit.

The flaws: what the advisory confirms

What is confirmed:

  • Two CVEs, CVE-2026-109618 and CVE-2026-109619, both critical at CVSS v4.0 9.2.

  • Both are remote code execution in the PHP interpreter itself, not in a plugin or framework on top of it.

  • Fixed in PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35.

The root cause is confirmed. In PHP's advisory (GHSA-w8hw-w9fx-j79w, CVE-2026-109618), this is remote code execution via out-of-memory corruption in PHP core. When an allocation fails mid-request, PHP's old OOM path used longjmp() to bail out of the current context without accounting for memory that was only partially initialized, and request shutdown then reads or branches on that invalid state. php.net describes both fixes under Core as "avoid state corruption via bailout," and the patch removes the longjmp OOM path.

The entry point is multipart/form-data parsing: an attacker crafts requests that exhaust memory on purpose (no usable content length, unrestricted headers per part, empty file controls that still allocate), which is why the attempts we log carry oversized multipart bodies and leave a burst of "Allowed memory size exhausted" errors in PHP-FPM. One common trigger is session.upload_progress, on by default since PHP 5.4, so turning it off is a useful stopgap, though the advisory frames the bug as the OOM-bailout handling rather than that one feature. Either way it is reachable without authentication on a default install, since PHP parses request data before your application code runs.

Worth keeping in mind through the rest of this: reaching memory corruption is not the same as getting code execution. That gap is the story.

Figure 01Figure 01. PHP2Shell at a glance: two critical PHP core remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2, with the exposed PHP footprint measured from Hunt.io scan data.

Scope of exposure

To get a sense of how much PHP is exposed, we pulled HTTP scan data for hosts that leak their PHP version in the X-Powered-By header. The query runs against Hunt.io's HTTP scan feed in HuntSQL, pinned to a single day so it reproduces:

SELECT uniq(ip) AS unique_ips, count(*) AS records
FROM ip.events.http.30day
WHERE http.headers.x_powered_by LIKE '%PHP%'
  AND timestamp >= '2026-10-20 00:00:00'
  AND timestamp <  '2026-10-21 00:00:00'

                
Copy

For October 20, 2026 that returned 683,922 unique IPs across 4,303,096 scan records. Read the IP figure as a floor, not a full count. Hosts with expose_php set to Off do not leak the version at all, and some only carry it in the Server header (http.headers.server), so the real PHP footprint is larger, just harder to pin to a version.

To break it down by version, group the same match on the X-Powered-By value:

SELECT http.headers.x_powered_by, uniq(ip) AS ips
FROM ip.events.http.30day
WHERE http.headers.x_powered_by LIKE '%PHP%'
  AND timestamp >= '2026-10-20 00:00:00'
  AND timestamp <  '2026-10-21 00:00:00'
GROUP BY http.headers.x_powered_by
ORDER BY ips DESC
LIMIT 30

                
Copy

Top exposed versions by unique IP that day (this is the head of a long tail, so the numbers do not add up to the total):

PHP versionUnique IPsNote
7.4.33~80,000End of life since Nov 2022
5.6.40~30,800End of life
8.3.35~21,700Supported branch
8.0.30~21,000End of life
5.4.16~20,500End of life
7.2.24~18,200End of life
7.2.34~15,600End of life
5.3.3~14,200End of life
8.3.33~11,800Supported branch
Figure 02Figure 02. The same breakdown run in HuntSQL: 4.3M matching scan events across October 20, 2026, with exposed PHP versions ranked by unique IP (7.4.33 leads at 79,994).

A few things stand out. Most of what is exposed runs on end-of-life branches, 7.x and 5.x and 8.0, that are not getting a fix at all. Supported branches show up too: 8.3.35 sits third and other 8.3.x builds are close behind, so hosts that were up to date were still exposed during the pre-patch window, same as the old ones. Even fully patched systems were exposed before the fix shipped before 14:00 UTC on the 21st.

Figure 03Figure 03. Exposed PHP versions by unique IP on October 20, 2026, from a one-day Hunt.io scan snapshot. End-of-life builds dominate the top of the list, with supported 8.3.x branches in the mix too.

A caveat that matters

A version string in a header tells you what the software claims to be, not whether it is actually vulnerable. Linux distributions patch bugs and leave the upstream version number untouched all the time, so a host reporting an "old" PHP build may already be fixed. Any count built purely on version strings will run high. We call it out because these exposure numbers get passed around without that context, and they shouldn't be.

Exploitation in the wild: attempted, not achieved

This is the part to get right. As of October 21, 2026 at 23:45 UTC, we see live php2shell attempts and plenty of tooling being staged, but no successful in-the-wild compromise, and no vendor has confirmed one. It comes down to four things:

  • Attempts began quickly but have stayed low-volume. Scanning started about 20 minutes after the 14:00 UTC patch. Our honeypots have logged two php2shell requests, both from a single IP that has already rotated its user-agent.

  • Tooling is ahead of results. About ten attacker workspaces in AttackCapture hold php2shell tooling. None holds a victim list, a shell, or stolen data from it.

  • The only mass-exploitation operator we found ran ten passes against up to 123 servers and logged zero shells.

  • The exploit is hard to land. Code execution on a real site needs a second weakness or a server without address-space randomization. VulnCheck found no public PoC that clears that bar on x86-64, and the researchers who tore the public code apart say the same: Justin Elze (@HackingLZ) reviewed all 30 public GitHub repos and found nothing that works against a real target, Marcus Hutchins (@MalwareTechBlog) points out the RCE needs ASLR-protected memory addresses, and @an0n_r0 notes the one credible PoC is stuck on an unrealistic single-worker PHP-FPM setup.

Who is scanning

The php2shell traffic we see comes from an established Mirai-style IoT botnet that has been around since at least May 2026 and just added php2shell to its spreading kit. Its scanner, 45.198.224[.]169, shares a network (VPSVAULT, AS215925) and scanning fingerprint with hosts that have served the botnet's C2 infrastructure. At 20:36 UTC on the 21st it came back with a new user-agent, php2shell-109618.

What is sitting in the open directories

AttackCapture pulls in attacker staging servers left exposed on the internet and lets us search inside the files. Pulling the php2shell tooling out of everything else is a one-line query: a Code Search for php2shell, or for either CVE ID, surfaces the staged scripts directly.

Figure 04Figure 04. Finding the tooling is a one-line search. A Code Search for php2shell across the captured open directories returns 146 matching files, here probe_rfc1867.py and verify_fixation.py with CVE-2026-109619 and the session.upload_progress trigger sitting right in the code. Searching the CVE IDs directly works the same way.

About ten of those open directories hold php2shell tooling right now. Grouped by what they actually are:

TierHostsWhat it isResult
Custom tooling102.210.149[.]166Hand-written scripts plus WordPress plugin bugs, ~3.3K-site target listOwn scan results empty. Pivoted to an AVideo SQL injection that did yield account data. Idle since 16:05 UTC
Custom tooling122.10.110[.]72, 122.10.17[.]49One operator, shared directory, php2shell project inside a broad workspaceLab only, no php2shell victims in either http.log
Custom tooling58.221.60[.]160:8000Chinese-commented probe scripts (probe_rfc1867.py, verify_fixation.py) that detect session.upload_progress exposure and verify session fixation, plus X-Powered-By version scanners and target listsSurface scanning only, no shells or php2shell victims (seen 2026-10-22)
Mass exploitation206.188.197[.]105 (BL Networks, AS399629, NL)Mass-exploit tool routed through a ~97-proxy farm, 10 runs 19:11 to 20:23 UTC, list grown from 23 to 123 serversNo code execution or shell logged, callback listener caught only internet scanners
Public PoC reuse41.223.30[.]7, 157.230.117[.]70Same public tool, identical file hashesTooling only
Public PoC reuse104.219.251[.]31Different public PoC repo plus defender WAF rulesResearch / defensive
Public PoC reuse107.150.31[.]151PoC held before the patch, WHMCS namedNo results
Targeted assessment217.160.132[.]82Pentest-style write-up against a hosting provider, dated 21 Oct, lists php2shell among risks checkedJudged not exploitable there
Research / labs47.100.125[.]108, 54.169.109[.]7, 139.162.165[.]136Test setups and harnessesNone
Figure 05Figure 05. Public PoC reuse and staged webshells on 104.219.251[.]31:8123 in AttackCapture. The workspace holds a cloned php2shell PoC plus ready-to-drop PHP backdoors (shell.php pulling from maste.mangsud[.]org, autologin_fd.php, the tebaran_* CMS deployers). No php2shell victim was recorded on this host.

The only real compromises in any of these directories have nothing to do with php2shell: account data taken from an AVideo install by SQL injection (102.210.149[.]166), and one third-party server calling back to the 122.10.x operator after a Java attack. We keep those separate on purpose. Staging a php2shell tool is not the same as landing it, and we are not going to blur the two.

What they are aiming at

Operators are pointing php2shell at commerce, billing, and general web hosting, with a clear preference for servers on old PHP that will never be patched. Neither target set we recovered shows a successful compromise.

The ranked list on 102.210.149[.]166 narrowed roughly 13.3K candidate hosts down to ~3.3K live sites, then ranked them by PHP version and the data each holds:

PlatformSitesTop-priorityData at risk
WooCommerce~3K0Customers, orders
WHMCS25125Customers, billing, support tickets
Magento13131Customers, orders, admin

Their own notes say no attack chain against these sites was verified. The top-priority 56 sites run PHP 5.x to 8.1, branches PHP itself no longer supports. A fix is still reachable for most of them though: distro security teams and backport repos like packages.sury.org and ppa:ondrej/php ship patched builds back to 5.6, usually without changing the version string. The real exposure is operators who never apply those updates, not an absence of a fix. Geography skews to the US (~1.8K), then Germany (277), Singapore (250) and the UK (202). The operator even logged 151 sites that rejected the exploit request outright with HTTP 403, 405 or 406.

The mass-exploitation server on 206.188.197[.]105 hit 123 servers across cloud, shared-hosting and ISP networks. About 57 run PHP, many on unsupported 5.x to 7.x. Ten rejected the request outright, including three of the five sitting behind Cloudflare. None was exploited.

Figure 06Figure 06. The mass-exploitation operator staged in the open: 206.188.197[.]105:9999 in AttackCapture, first seen 2026-10-21 21:05:54 UTC. One directory holds the exploit toolkit (aslr_exploit.py, deep_probe.py, c2.py), a proxy list, and per-target folders. Ten runs against up to 123 servers logged zero shells.

What to do right now

  1. Patch now. The fix is out: PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35. On managed hosting, confirm your provider's timeline today.

  2. If you cannot patch immediately, put a WAF in front of it. Cloudflare switched on managed WAF rules for php2shell across all plans, including Free, at 03:02 UTC on October 21; in our data they block some attempts but not all, so treat the WAF as a layer that buys time, not a fix. Patching is the fix that actually closes it.

  3. Inventory your PHP. Know every host and what it runs. Anything on 7.x or older is not getting a fix, so plan the upgrade.

  4. Hunt for the attempt signatures in the indicators below, especially the php2shell user-agent, multipart posts carrying PHP_SESSION_UPLOAD_PROGRESS with an oversized body, and bursts of "Allowed memory size exhausted" in PHP-FPM logs. Those show you were targeted, not that you were compromised.

IOCs and network observables

Network, request, and log indicators tied to the activity above. Everything here is attempt and staging infrastructure, not evidence of a successful php2shell compromise.

UseIndicatorContext
Block45.198.224[.]0/24Scanner network, AS215925
Block85.11.167[.]243Second scanner (peer reporting)
Block92.118.112[.]100Payload host
Block89.32.41[.]16, 89.32.41[.]50, 45.198.224[.]88Botnet binary hosts
Block*.botlesscucks[.]st, *.godofthunder[.]st, *.gettingheadfromduckysmom[.]stBotnet C2 domains
DetectUser-agent containing php2shellSeen as php2shell-scan/109618 and php2shell-109618
DetectJA4H po11cn050000_0a87faf13e54_fe81d65a9ab0_0b5a6e5841d5Scanner fingerprint (peer reporting)
DetectMultipart POST with a PHP_SESSION_UPLOAD_PROGRESS field and an unusually large bodyExploit request pattern
DetectA burst of "Allowed memory size exhausted" errors in PHP-FPM from 21 Oct onServer-side trace of an attempt, not of compromise
Watch91.90.123[.]25, user-agent php2shell-verify/1.0Likely research checker (Belgium)

Staging-only operator and reuse hosts referenced above: 102.210.149[.]166, 122.10.110[.]72, 122.10.17[.]49, 58.221.60[.]160, 206.188.197[.]105, 41.223.30[.]7, 157.230.117[.]70, 104.219.251[.]31, 107.150.31[.]151, 217.160.132[.]82, 47.100.125[.]108, 54.169.109[.]7, 139.162.165[.]136.

Summary

The leak squeezed the usual patch window down to almost nothing. php2shell details were public on October 20, the fix landed around 14:00 UTC on the 21st, and scanning started roughly 20 minutes after that. The interest is real: an established IoT botnet bolted php2shell onto its spreading kit, and at least ten workspaces are holding tooling, one of them spraying 123 servers through a proxy network.

The part that matters is what has not happened. We have not confirmed any successful exploitation. The bugs get you memory corruption, but turning that into code execution on a live server needs a second weakness or a host without address randomization, and no public tool clears that on x86-64 right now. Big exposure, clear intent, no confirmed working mass exploit yet. That is the window to patch and watch for the attempt signatures, instead of waiting for a working exploit to decide for you. We are watching, and if a real compromise shows up in our data we will say so.

Hunt.io watches this kind of infrastructure as it goes up, the exposed tooling and the servers staging it, so you catch something like php2shell while it is still being built instead of after it has hit you. If you want to run these hunts against your own environment, book a demo.

Two critical PHP remote code execution bugs, CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2, leaked before their scheduled patch on October 21, 2026 at 14:00 UTC.

A large share of the web runs on PHP, so the exposed surface is big. And attackers wasted no time: php2shell scanning hit our honeypots about 20 minutes after the patch shipped. What we haven’t seen yet is a successful exploit.

So far, we’ve seen attempts and staged tooling, but no confirmed compromises, and no vendors have reported any. Below we map how much PHP is exposed, why a version number in a header is a weak way to judge real risk, and what turned up in attacker open directories through AttackCapture.

What happened

On October 20 the PHP security team put out an advance notice: an emergency release coming, two critical bugs, no technical detail, patch set for October 21 at 14:00 UTC. They kept the option to ship sooner if the details got out or exploitation turned up.

The details leaked. Over October 20 and 21 the two CVEs and a nickname, "php2shell", started circulating, and several researchers confirmed the bugs are real:

PHP shipped the fix on October 21 at about 14:00 UTC in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. End-of-life branches get no upstream release, though distro security teams and backport repos cover most older versions.

The scramble was real even without a confirmed compromise. Oh Dear's uptime monitoring recorded 18.8% of the sites it watches going offline at the peak, against 0.9% a week earlier, as operators pulled their own sites down rather than wait to get hit.

The flaws: what the advisory confirms

What is confirmed:

  • Two CVEs, CVE-2026-109618 and CVE-2026-109619, both critical at CVSS v4.0 9.2.

  • Both are remote code execution in the PHP interpreter itself, not in a plugin or framework on top of it.

  • Fixed in PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35.

The root cause is confirmed. In PHP's advisory (GHSA-w8hw-w9fx-j79w, CVE-2026-109618), this is remote code execution via out-of-memory corruption in PHP core. When an allocation fails mid-request, PHP's old OOM path used longjmp() to bail out of the current context without accounting for memory that was only partially initialized, and request shutdown then reads or branches on that invalid state. php.net describes both fixes under Core as "avoid state corruption via bailout," and the patch removes the longjmp OOM path.

The entry point is multipart/form-data parsing: an attacker crafts requests that exhaust memory on purpose (no usable content length, unrestricted headers per part, empty file controls that still allocate), which is why the attempts we log carry oversized multipart bodies and leave a burst of "Allowed memory size exhausted" errors in PHP-FPM. One common trigger is session.upload_progress, on by default since PHP 5.4, so turning it off is a useful stopgap, though the advisory frames the bug as the OOM-bailout handling rather than that one feature. Either way it is reachable without authentication on a default install, since PHP parses request data before your application code runs.

Worth keeping in mind through the rest of this: reaching memory corruption is not the same as getting code execution. That gap is the story.

Figure 01Figure 01. PHP2Shell at a glance: two critical PHP core remote code execution flaws, CVE-2026-109618 and CVE-2026-109619, both rated CVSS v4.0 9.2, with the exposed PHP footprint measured from Hunt.io scan data.

Scope of exposure

To get a sense of how much PHP is exposed, we pulled HTTP scan data for hosts that leak their PHP version in the X-Powered-By header. The query runs against Hunt.io's HTTP scan feed in HuntSQL, pinned to a single day so it reproduces:

SELECT uniq(ip) AS unique_ips, count(*) AS records
FROM ip.events.http.30day
WHERE http.headers.x_powered_by LIKE '%PHP%'
  AND timestamp >= '2026-10-20 00:00:00'
  AND timestamp <  '2026-10-21 00:00:00'

                
Copy

For October 20, 2026 that returned 683,922 unique IPs across 4,303,096 scan records. Read the IP figure as a floor, not a full count. Hosts with expose_php set to Off do not leak the version at all, and some only carry it in the Server header (http.headers.server), so the real PHP footprint is larger, just harder to pin to a version.

To break it down by version, group the same match on the X-Powered-By value:

SELECT http.headers.x_powered_by, uniq(ip) AS ips
FROM ip.events.http.30day
WHERE http.headers.x_powered_by LIKE '%PHP%'
  AND timestamp >= '2026-10-20 00:00:00'
  AND timestamp <  '2026-10-21 00:00:00'
GROUP BY http.headers.x_powered_by
ORDER BY ips DESC
LIMIT 30

                
Copy

Top exposed versions by unique IP that day (this is the head of a long tail, so the numbers do not add up to the total):

PHP versionUnique IPsNote
7.4.33~80,000End of life since Nov 2022
5.6.40~30,800End of life
8.3.35~21,700Supported branch
8.0.30~21,000End of life
5.4.16~20,500End of life
7.2.24~18,200End of life
7.2.34~15,600End of life
5.3.3~14,200End of life
8.3.33~11,800Supported branch
Figure 02Figure 02. The same breakdown run in HuntSQL: 4.3M matching scan events across October 20, 2026, with exposed PHP versions ranked by unique IP (7.4.33 leads at 79,994).

A few things stand out. Most of what is exposed runs on end-of-life branches, 7.x and 5.x and 8.0, that are not getting a fix at all. Supported branches show up too: 8.3.35 sits third and other 8.3.x builds are close behind, so hosts that were up to date were still exposed during the pre-patch window, same as the old ones. Even fully patched systems were exposed before the fix shipped before 14:00 UTC on the 21st.

Figure 03Figure 03. Exposed PHP versions by unique IP on October 20, 2026, from a one-day Hunt.io scan snapshot. End-of-life builds dominate the top of the list, with supported 8.3.x branches in the mix too.

A caveat that matters

A version string in a header tells you what the software claims to be, not whether it is actually vulnerable. Linux distributions patch bugs and leave the upstream version number untouched all the time, so a host reporting an "old" PHP build may already be fixed. Any count built purely on version strings will run high. We call it out because these exposure numbers get passed around without that context, and they shouldn't be.

Exploitation in the wild: attempted, not achieved

This is the part to get right. As of October 21, 2026 at 23:45 UTC, we see live php2shell attempts and plenty of tooling being staged, but no successful in-the-wild compromise, and no vendor has confirmed one. It comes down to four things:

  • Attempts began quickly but have stayed low-volume. Scanning started about 20 minutes after the 14:00 UTC patch. Our honeypots have logged two php2shell requests, both from a single IP that has already rotated its user-agent.

  • Tooling is ahead of results. About ten attacker workspaces in AttackCapture hold php2shell tooling. None holds a victim list, a shell, or stolen data from it.

  • The only mass-exploitation operator we found ran ten passes against up to 123 servers and logged zero shells.

  • The exploit is hard to land. Code execution on a real site needs a second weakness or a server without address-space randomization. VulnCheck found no public PoC that clears that bar on x86-64, and the researchers who tore the public code apart say the same: Justin Elze (@HackingLZ) reviewed all 30 public GitHub repos and found nothing that works against a real target, Marcus Hutchins (@MalwareTechBlog) points out the RCE needs ASLR-protected memory addresses, and @an0n_r0 notes the one credible PoC is stuck on an unrealistic single-worker PHP-FPM setup.

Who is scanning

The php2shell traffic we see comes from an established Mirai-style IoT botnet that has been around since at least May 2026 and just added php2shell to its spreading kit. Its scanner, 45.198.224[.]169, shares a network (VPSVAULT, AS215925) and scanning fingerprint with hosts that have served the botnet's C2 infrastructure. At 20:36 UTC on the 21st it came back with a new user-agent, php2shell-109618.

What is sitting in the open directories

AttackCapture pulls in attacker staging servers left exposed on the internet and lets us search inside the files. Pulling the php2shell tooling out of everything else is a one-line query: a Code Search for php2shell, or for either CVE ID, surfaces the staged scripts directly.

Figure 04Figure 04. Finding the tooling is a one-line search. A Code Search for php2shell across the captured open directories returns 146 matching files, here probe_rfc1867.py and verify_fixation.py with CVE-2026-109619 and the session.upload_progress trigger sitting right in the code. Searching the CVE IDs directly works the same way.

About ten of those open directories hold php2shell tooling right now. Grouped by what they actually are:

TierHostsWhat it isResult
Custom tooling102.210.149[.]166Hand-written scripts plus WordPress plugin bugs, ~3.3K-site target listOwn scan results empty. Pivoted to an AVideo SQL injection that did yield account data. Idle since 16:05 UTC
Custom tooling122.10.110[.]72, 122.10.17[.]49One operator, shared directory, php2shell project inside a broad workspaceLab only, no php2shell victims in either http.log
Custom tooling58.221.60[.]160:8000Chinese-commented probe scripts (probe_rfc1867.py, verify_fixation.py) that detect session.upload_progress exposure and verify session fixation, plus X-Powered-By version scanners and target listsSurface scanning only, no shells or php2shell victims (seen 2026-10-22)
Mass exploitation206.188.197[.]105 (BL Networks, AS399629, NL)Mass-exploit tool routed through a ~97-proxy farm, 10 runs 19:11 to 20:23 UTC, list grown from 23 to 123 serversNo code execution or shell logged, callback listener caught only internet scanners
Public PoC reuse41.223.30[.]7, 157.230.117[.]70Same public tool, identical file hashesTooling only
Public PoC reuse104.219.251[.]31Different public PoC repo plus defender WAF rulesResearch / defensive
Public PoC reuse107.150.31[.]151PoC held before the patch, WHMCS namedNo results
Targeted assessment217.160.132[.]82Pentest-style write-up against a hosting provider, dated 21 Oct, lists php2shell among risks checkedJudged not exploitable there
Research / labs47.100.125[.]108, 54.169.109[.]7, 139.162.165[.]136Test setups and harnessesNone
Figure 05Figure 05. Public PoC reuse and staged webshells on 104.219.251[.]31:8123 in AttackCapture. The workspace holds a cloned php2shell PoC plus ready-to-drop PHP backdoors (shell.php pulling from maste.mangsud[.]org, autologin_fd.php, the tebaran_* CMS deployers). No php2shell victim was recorded on this host.

The only real compromises in any of these directories have nothing to do with php2shell: account data taken from an AVideo install by SQL injection (102.210.149[.]166), and one third-party server calling back to the 122.10.x operator after a Java attack. We keep those separate on purpose. Staging a php2shell tool is not the same as landing it, and we are not going to blur the two.

What they are aiming at

Operators are pointing php2shell at commerce, billing, and general web hosting, with a clear preference for servers on old PHP that will never be patched. Neither target set we recovered shows a successful compromise.

The ranked list on 102.210.149[.]166 narrowed roughly 13.3K candidate hosts down to ~3.3K live sites, then ranked them by PHP version and the data each holds:

PlatformSitesTop-priorityData at risk
WooCommerce~3K0Customers, orders
WHMCS25125Customers, billing, support tickets
Magento13131Customers, orders, admin

Their own notes say no attack chain against these sites was verified. The top-priority 56 sites run PHP 5.x to 8.1, branches PHP itself no longer supports. A fix is still reachable for most of them though: distro security teams and backport repos like packages.sury.org and ppa:ondrej/php ship patched builds back to 5.6, usually without changing the version string. The real exposure is operators who never apply those updates, not an absence of a fix. Geography skews to the US (~1.8K), then Germany (277), Singapore (250) and the UK (202). The operator even logged 151 sites that rejected the exploit request outright with HTTP 403, 405 or 406.

The mass-exploitation server on 206.188.197[.]105 hit 123 servers across cloud, shared-hosting and ISP networks. About 57 run PHP, many on unsupported 5.x to 7.x. Ten rejected the request outright, including three of the five sitting behind Cloudflare. None was exploited.

Figure 06Figure 06. The mass-exploitation operator staged in the open: 206.188.197[.]105:9999 in AttackCapture, first seen 2026-10-21 21:05:54 UTC. One directory holds the exploit toolkit (aslr_exploit.py, deep_probe.py, c2.py), a proxy list, and per-target folders. Ten runs against up to 123 servers logged zero shells.

What to do right now

  1. Patch now. The fix is out: PHP 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35. On managed hosting, confirm your provider's timeline today.

  2. If you cannot patch immediately, put a WAF in front of it. Cloudflare switched on managed WAF rules for php2shell across all plans, including Free, at 03:02 UTC on October 21; in our data they block some attempts but not all, so treat the WAF as a layer that buys time, not a fix. Patching is the fix that actually closes it.

  3. Inventory your PHP. Know every host and what it runs. Anything on 7.x or older is not getting a fix, so plan the upgrade.

  4. Hunt for the attempt signatures in the indicators below, especially the php2shell user-agent, multipart posts carrying PHP_SESSION_UPLOAD_PROGRESS with an oversized body, and bursts of "Allowed memory size exhausted" in PHP-FPM logs. Those show you were targeted, not that you were compromised.

IOCs and network observables

Network, request, and log indicators tied to the activity above. Everything here is attempt and staging infrastructure, not evidence of a successful php2shell compromise.

UseIndicatorContext
Block45.198.224[.]0/24Scanner network, AS215925
Block85.11.167[.]243Second scanner (peer reporting)
Block92.118.112[.]100Payload host
Block89.32.41[.]16, 89.32.41[.]50, 45.198.224[.]88Botnet binary hosts
Block*.botlesscucks[.]st, *.godofthunder[.]st, *.gettingheadfromduckysmom[.]stBotnet C2 domains
DetectUser-agent containing php2shellSeen as php2shell-scan/109618 and php2shell-109618
DetectJA4H po11cn050000_0a87faf13e54_fe81d65a9ab0_0b5a6e5841d5Scanner fingerprint (peer reporting)
DetectMultipart POST with a PHP_SESSION_UPLOAD_PROGRESS field and an unusually large bodyExploit request pattern
DetectA burst of "Allowed memory size exhausted" errors in PHP-FPM from 21 Oct onServer-side trace of an attempt, not of compromise
Watch91.90.123[.]25, user-agent php2shell-verify/1.0Likely research checker (Belgium)

Staging-only operator and reuse hosts referenced above: 102.210.149[.]166, 122.10.110[.]72, 122.10.17[.]49, 58.221.60[.]160, 206.188.197[.]105, 41.223.30[.]7, 157.230.117[.]70, 104.219.251[.]31, 107.150.31[.]151, 217.160.132[.]82, 47.100.125[.]108, 54.169.109[.]7, 139.162.165[.]136.

Summary

The leak squeezed the usual patch window down to almost nothing. php2shell details were public on October 20, the fix landed around 14:00 UTC on the 21st, and scanning started roughly 20 minutes after that. The interest is real: an established IoT botnet bolted php2shell onto its spreading kit, and at least ten workspaces are holding tooling, one of them spraying 123 servers through a proxy network.

The part that matters is what has not happened. We have not confirmed any successful exploitation. The bugs get you memory corruption, but turning that into code execution on a live server needs a second weakness or a host without address randomization, and no public tool clears that on x86-64 right now. Big exposure, clear intent, no confirmed working mass exploit yet. That is the window to patch and watch for the attempt signatures, instead of waiting for a working exploit to decide for you. We are watching, and if a real compromise shows up in our data we will say so.

Hunt.io watches this kind of infrastructure as it goes up, the exposed tooling and the servers staging it, so you catch something like php2shell while it is still being built instead of after it has hit you. If you want to run these hunts against your own environment, book a demo.