Skip to content

Back to the catalog

PHP2Shell: Exploitation Attempts and Remediation Trends
wiz.ioarticle

PHP2Shell: Exploitation Attempts and Remediation Trends

Wiz Research follow-up on PHP2Shell (CVE-2026-109618, CVE-2026-109619) after the 21 October 2026 disclosure. Honeypot data shows two variants of an open source exploit kit, one stopped by post_max_size and the other by failed memory leaks and worker pinning, plus PHP2Shell-branded tools that rely on session poisoning and LFI. Daily exposed vulnerable machines fell about 67%.

TL;DR Wiz reports that PHP2Shell exploit attempts seen in its honeypots all failed, explains where each chain broke, and tracks a 67% drop in exposed hosts.
Document

What it is

Wiz Research's field report on PHP2Shell (CVE-2026-109618, CVE-2026-109619), one week after the 21 October 2026 disclosure. Wiz saw no successful end-to-end exploitation in its own telemetry. It found no public PoC that works generally against an arbitrary target. Wiz says some partners have privately disclosed exploits that work against a variety of targets. CISA added PHP2Shell to its KEV list, which Wiz links partly to Adel Karimi's honeypot being successfully exploited.

How it works

The observed kit is open source and has two chains. Both depend on exhausting PHP memory during session handling, then reusing stale session state on a later request.

flowchart TD
    L[Legacy chain, 12 MB body] --> L1{Over post_max_size?}
    L1 -->|8 MB limit| L2[Body skipped, stops]
    N[Current chain, stage A1] --> N1[Memory exhausted, HTTP 500]
    N1 --> N2[Stage B1 heap leak]
    N2 --> N3{Same worker, same heap layout?}
    N3 -->|No| N4[No leak, no final stage]
    N3 -->|Yes| N5[Karimi single-worker mod_php honeypots]
  • Legacy chain (archive/legacy-8m/exploit.py): a 1,005-part multipart POST with about 12 MB of padding. It failed on Wiz's honeypot because the declared size exceeded the 8 MB post_max_size. A later Roundcube attempt used stalled connections and 1,001 fields of 3,000 bytes each, and never reached memory exhaustion.
  • Current chain (pure/mk_a1.py, pure/mk_leak_b.py): most captured sources used this. Stage A1 is a chunked multipart request with a null-byte PHPSESSID, 860 empty file parts with deeply nested array names, and padding fields. It reliably triggered memory exhaustion. Stage B1 should make PHP write heap contents into a PHPSESSID cookie, from which the kit extracts heap and libphp addresses. B1 failed in every captured run, and no source sent the final stage.
  • Worker pinning: the chain needs consecutive requests to hit the same Apache child. The kit fills other workers with stalled POSTs (Content-Length: 1048576, one byte sent). One address, 178.249.214[.]6 (a VPN exit), opened 399 such connections plus 400 GETs.
  • Mislabelled tools: some "PHP2Shell" traffic, from 85.11.187[.]35, was a Go port of "Chain A" from the WoYinDao/CVE-2026-109618-CVSS-9.2-Critical repository. It uses session poisoning via upload progress, then includes /tmp/sess_* through lfi_sink.php, an endpoint from the PoC's lab. It needs a separate LFI bug and does not exploit either CVE.

Preconditions / Affected

The kit's B1 layout was tuned for the official php:8.4.26-apache image with a 128 MB memory limit. Wiz's Roundcube honeypot ran the same PHP version from a different build, with extra extensions and a 64 MB limit, and the leak failed. Karimi's successful honeypots used a favorable single-worker Apache mod_php setup. Wiz expects these barriers to shrink as capable actors adapt the chain.

What to do

Wiz's advice is to apply the PHP security updates, or remediate by other means. Hunting signals from the post:

  • PHP log lines POST Content-Length of 12655437 bytes exceeds the limit of 8388608 bytes.
  • Log lines Allowed memory size of 134217728 bytes exhausted ... in Unknown on line 0 (also seen with 67108864) paired with HTTP 500.
  • Bursts of incomplete POSTs with a large declared Content-Length and one byte of body.
  • Multipart bodies containing PHPSESSID set to \x00 together with PHP_SESSION_UPLOAD_PROGRESS.
  • Source IPs: 3.37.227[.]134, 103.151.172[.]95, 178.249.214[.]6, 15.204.59[.]70, 162.35.99[.]94, 85.11.187[.]35.

Caveats

  • post_max_size stopped one chain only incidentally. The post does not present it as a fix.
  • Memory exhaustion alone does not prove the stale session state survived.
  • Exposure figures: distinct vulnerable internet-exposed machines per day fell about 67%, and affected organizations fell about 47.9%. PHP 7.3 or earlier rose no further than 5.7% of vulnerable hosts, down from 8.3% over five days. These versions did not receive official backports. Wiz says the data cannot separate patching, upgrades, retirement or access restriction, and scan coverage can skew it.
  • The post gives no patched version numbers.

Organisations named here

  • heap shaping
  • memory exhaustion
  • Wiz Research

CVEs named here

  • CVE-2026-109618
  • CVE-2026-109619

Technologies named here

  • Wiz telemetry and honeypots
  • php2shell.com
  • PHP-CGI honeypot
  • CISA KEV list
  • Open source PHP2Shell exploit kit
  • Official php:8.4.26-apache image with 128 MB memory limit
  • WoYinDao/CVE-2026-109618-CVSS-9.2-Critical
  • Adel Karimi's public report
  • PHP
  • Apache
  • CISA KEV
  • Roundcube

Techniques named here

  • Multipart request abuse
  • Worker pinning
  • Session Poisoning
  • Local file inclusion

Threat actors named here

  • PHP2Shell exploitation attempts
  • Open source exploit kit targeting PHP-based software
  • PHP2Shell-branded tools unrelated to the vulnerabilities
  • Source IP 3.37.227[.]134
  • Source IP 103.151.172[.]95
  • Source IP 178.249.214[.]6
  • Source IPs 15.204.59[.]70 and 162.35.99[.]94
  • Source IP 85.11.187[.]35
  • PHP2Shell

Also named here

  • Adel Karimi