Last week, we published a report describing two major vulnerabilities in PHP (CVE-2026-109618, CVE-2026-109619). Since then, alongside much of the security industry, the Wiz Research team has been monitoring for related activity in the wild and reviewing publicly available exploit code. So far, we have observed a limited number of exploitation attempts in our telemetry and have not identified a publicly available proof of concept (PoC) demonstrating complete, general end-to-end exploitation against an arbitrary target. Some partners have, however, privately disclosed to us exploits that work against a variety of targets and we continue to experiment internally. Videos demonstrating our successful exploitations are available at php2shell.com.
This post summarizes what we have observed in terms of remediation efforts and exploitation attempts across real world environments and in our own honeypot data to date and shares findings from our ongoing investigation into these activities.
We will continue monitoring developments and update this post as new evidence emerges.
Observed exposure trends
Following PHP2Shell’s public disclosure on October 21, 2026, Wiz telemetry has recorded an approximate 67% decrease in the daily number of distinct Internet-exposed machines vulnerable to PHP2Shell over the past few days. Separately, among vulnerable Internet-exposed machines, the proportion running PHP version 7.3 or earlier fell from 8.3% to 5.7% over a period of five days. This measures the share of the observed population running older versions that did not receive official backports.
During this period, the number of significantly affected organizations - defined here as those with at least one exposed and vulnerable instance - fell by approximately 47.9% (see graph below). For reference, our data shows that PHP itself is in use by 65% of organizations in our dataset.
Together, these observations are consistent with organizations collectively reducing their exposure through a combination of patching, upgrading, retiring affected machines and restricting internet access (note that this data shows the overall trend, but does not establish the relative contribution of each remediation strategy; scan coverage and size of observed population can also affect the overall reported numbers over time).
Exploitation attempts observed by Wiz research
We have so far observed the following types of activities in this context:
Attempts using the PHP2Shell exploit mechanism, with techniques matching those of public PoCs.
PHP2Shell-branded tools unrelated to the vulnerabilities that instead relied on session poisoning and a separate local file inclusion (LFI) vulnerability in the application.
Attempts using the PHP2Shell exploit mechanism
We observed two variants of an open source exploit kit targeting PHP-based software. Neither completed the exploit chain in the attempts we captured. The older variant encountered request-size limits or failed to produce the expected memory-exhaustion condition. The newer variant did consistently exhaust PHP’s memory, but failed to obtain the memory addresses needed to continue.
Variant 1: the legacy chain
The first request to our PHP-CGI honeypot came from 3.37.227[.]134. It matched the kit’s older chain, found under archive/legacy-8m/exploit.py and its accompanying stage scripts. The first full exploit stage used a multipart body containing 1,005 parts, including a field named big filled with approximately 12 MB of padding:
POST / HTTP/1.1
Host: <honeypot>
Content-Type: multipart/form-data; boundary=SSSSSSSSSSSSSSSSS
Content-Length: 12655437
[1,005 parts]
1001 x p0000 = "x"
1 x PHPSESSID = "\x00"
1 x PHP_SESSION_UPLOAD_PROGRESS = "pwn"
1 x f (file) = "A" x 64
1 x big = "B" x ~12 MBAccording to the kit’s notes, this stage attempts to exhaust memory during a session reset, leaving the session state available for a later request.
On our honeypot, it failed before reaching that code. The declared request size exceeded the configured 8 MB post_max_size limit, so PHP skipped processing the multipart body and logged:
POST Content-Length of 12655437 bytes exceeds the limit of 8388608 bytesThe author has since moved this chain into the kit’s archive directory.
A later attempt against Roundcube
In a later attempt, 103.151.172[.]95 sent a longer sequence from the legacy chain. It included stalled connections intended to occupy other Apache workers.
When only one worker was available the exploit attempted heap-shaping by sending requests containing 1,001 fields of 3,000 bytes each. These requests didn’t trigger the memory exhaustion flow required. So there is no evidence that this attempt reached the intended memory-exhaustion condition.
Variant 2: the current chain
Most IP addresses we captured used the newer chain, built from pure/mk_a1.py and pure/mk_leak_b.py. We observed this variant in multiple attempts.
This variant progressed further: its first stage consistently caused PHP to exhaust its memory. The following stage, which attempts to leak process memory, failed in every run we captured.
The server logged a fatal error indicating that PHP reached its limit, for example:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 81920 bytes) in Unknown on line 0.Keeping requests on the same worker
The chain depends on consecutive exploit requests reaching the same Apache child process. To increase the chances of that happening, the kit attempts to occupy the other workers with incomplete requests. Each connection declares a large body, sends a single byte and stalls:
POST /index.php HTTP/1.1
Host: <honeypot>
Content-Type: application/x-www-form-urlencoded
Content-Length: 1048576
xOne address, 178.249.214[.]6, opened 399 of these connections alongside 400 GET requests before sending the exploit stages. The address is a VPN exit node, which limits what we can infer about the source.
Stage A1: triggering memory exhaustion
A1 is a chunked multipart request containing a null-byte session ID, 860 empty file parts with long, deeply nested array names and several groups of padding fields:
POST /?q0=v&q1=v&q2=v&q3=v&q4=v HTTP/1.1Host: <honeypot>
Content-Type: multipart/form-data; boundary=CCCCCCCCCC
Transfer-Encoding: chunked
[1,060,211 bytes, 974 parts]
1 x PHPSESSID = "\x00"
860 x files[R00000KKKK...][a][a]... (file, empty)
14 x f0000xxxx... = "vvvvvvvv"
78 x b0000 = "B" x 8000
20 x u00 = "U" x 4000
1 x PHP_SESSION_UPLOAD_PROGRESS = "k" x 4000The request is designed to exhaust memory during session handling at a point that can leave the session ID pointing to freed memory.
Every A1 request we captured returned HTTP 500, accompanied by a PHP error matching:
Allowed memory size of 67108864 bytes exhausted ... in Unknown on line 0This confirms that A1 reached the intended memory-exhaustion condition on our honeypot. It does not, by itself, confirm that the stale session state needed by the next stage was preserved.
Stage B1: attempting the memory leak
B1 followed roughly a second later. It sent another chunked multipart request containing PHPSESSID=a, PHP_SESSION_UPLOAD_PROGRESS=k0and two large padding fields.
If this request reaches the same worker before PHP resets the stale session state, PHP can write reclaimed heap contents into a PHPSESSID response cookie. The kit then extracts heap and libphp addresses from that cookie to prepare the final exploit stage.
We observed no such leak. In all but one run, the connection closed without a response. The remaining run returned a normal 32-character session cookie. None of the sources sent the final exploit stage.
Why the leaks may have failed
The failed leaks highlight a broader challenge: building a generalized exploit that works reliably across PHP versions and deployment configurations is difficult. The kit’s B1 layout was calculated for the official php:8.4.26-apache image with a 128 MB memory limit. Other instances like our Roundcube honeypot ran the same PHP version from a different build, with additional extensions and a 64 MB memory limit. These differences can affect heap layout and memory reuse, potentially preventing the leak from working as expected.
Reliable worker pinning adds another challenge. Consecutive exploit requests must reach the same Apache child process while the required session state persists. Request timeouts, network latency and worker availability can disrupt this sequence. In our own testing, request timeouts combined with network latency were enough to prevent the chain from completing over an internet connection.
So far, we have not identified a publicly available, generalized solution for either worker pinning or information leaking across different deployments. Simply copying public PoCs and running them at scale does not address the work needed to turn a configuration-specific exploit into a reliable operational kit. We expect these barriers to diminish over time: some threat actors have the expertise needed to adapt the chain and build more robust tooling.
Other attempts
We also saw failed exploitation attempts from 15.204.59[.]70 and 162.35.99[.]94, but these scanners did successfully exploit Adel Karimi's honeypot, which was a likely contributing factor to CISA’s decision to include PHP2Shell in their KEV list.
PHP2Shell-branded tools unrelated to the vulnerabilities
We also observed tools labeled as PHP2Shell exploits that did not actually attempt to exploit either vulnerability. The earliest such traffic, from 85.11.187[.]35, matched a Go port of “Chain A” from WoYinDao/CVE-2026-109618-CVSS-9.2-Critical.
The tool used a longstanding session-poisoning technique, attempting to write PHP code into a session file through the upload-progress feature. The request below is abbreviated:
POST /index.php HTTP/1.1
Host: <honeypot>
User-Agent: Go-http-client/1.1
Content-Type: multipart/form-data; boundary=----php2shell-golang
PHP_SESSION_UPLOAD_PROGRESS = <?php echo "PHP2SHELL_XBu4Je"; system($_GET["c"]); ?>
PHPSESSID = <attacker-chosen ID>
f (file) = "Z"It then attempted to execute that code by including the session file:
GET /lfi_sink.php?c=id&f=/tmp/sess_SUjKIKy3Rr6QsaJ1Ik7Rme8h3n HTTP/1.1Crucially, lfi_sink.php is a vulnerable endpoint supplied by the PoC’s lab environment. The tool assumes that this endpoint exists on the target; without it or an equivalent local file inclusion (LFI) vulnerability, the chain cannot execute code.
A padded variant triggered our memory-exhaustion detection, but we observed no successful code execution. Despite the PHP2Shell branding, this activity relied on an unrelated technique and a vulnerable application endpoint.
Conclusion
We have not yet observed successful end-to-end PHP2Shell exploitation in our own telemetry. However, Adel Karimi’s public report and supporting data provide the most robust public evidence we have seen to date, correlating exploit traffic, memory disclosure and subsequent code execution on his honeypots. Notably, those targets used a favorable single-worker Apache mod_php configuration, so the findings do not establish reliability across other deployments.
Our observations show that triggering memory exhaustion alone is not enough to complete the exploit chain. Differences in PHP builds, memory limits and worker behavior can prevent subsequent stages from working. The challenge for opportunistic attackers is turning currently available public PoCs into similarly reliable operational tooling or developing it on their own. In our view, PHP2Shell remains a risk in both the short and long term and applying the PHP security updates or remediating through other means therefore remains essential.
IOCs
| Type | Indicator | First Seen | Last Seen | Description |
|---|---|---|---|---|
| IPv4 | 85.11.187[.]35 | 2026-10-21 | 2026-10-21 | Exploitation attempt |
| IPv4 | 172.206.2[.]199 | 2026-10-25 | 2026-10-25 | Scanner + exploitation attempt |
| IPv4 | 3.37.227[.]134 | 2026-10-21 | 2026-10-21 | Exploitation attempt |
| IPv4 | 103.151.172[.]95 | 2026-10-25 | 2026-10-25 | Exploitation attempt |
| IPv4 | 178.249.214[.]6 | 2026-10-24 | 2026-10-24 | Exploitation attempt (VPN) |
| IPv4 | 31.56.197[.]72 | 2026-10-21 | 2026-10-21 | C2 (payload server) |
| IPv4 | 135.136.19[.]197 | 2026-10-26 | 2026-10-26 | Scanner + exploitation attempt (VPN) |
| IPv4 | 15.204.59[.]70 | 2026-10-24 | 2026-10-24 | Exploitation attempt |
| IPv4 | 162.35.99[.]94 | 2026-10-24 | 2026-10-24 | Exploitation attempt |