PHP2Shell: Exploitpogingen en trends in remediatie
Auteurs: Yaara Shriki, Shahar Dorfman, Alma Blachsan, Yaron Samuel Datum: 27 oktober 2026
Vorige week hebben we een rapport gepubliceerd over twee grote kwetsbaarheden in PHP (CVE-2026-109618, CVE-2026-109619). Sindsdien heeft het Wiz Research-team, samen met een groot deel van de security-industrie, gezocht naar gerelateerde activiteiten in het wild en publiek beschikbare exploit-code beoordeeld.
Tot nu toe hebben we een beperkt aantal exploitpogingen waargenomen in onze telemetry en hebben we geen publiek beschikbare proof of concept (PoC) geïdentificeerd die een volledige, algemene end-to-end exploitatie tegen een willekeurig doelwit demonstreert. Sommige partners hebben ons echter privé exploits gemeld die werken tegen verschillende doelwitten, en we blijven intern experimenteren. Video's die onze succesvolle exploitaties demonstreren, zijn beschikbaar op php2shell.com.
Dit bericht vat samen wat we tot nu toe hebben waargenomen met betrekking tot remediatie-inspanningen en exploitpogingen in echte omgevingen en in onze eigen honeypot-data. We zullen ontwikkelingen blijven monitoren en dit bericht bijwerken zodra er nieuw bewijs naar voren komt.
Waargenomen trends in exposure
Na de publieke bekendmaking van PHP2Shell op 21 oktober 2026 heeft de telemetry van Wiz een afname van ongeveer 67% geregistreerd in het dagelijkse aantal unieke, via internet bereikbare machines die kwetsbaar zijn voor PHP2Shell over de afgelopen dagen.
Daarnaast is, onder de kwetsbare internet-exposed machines, het aandeel dat PHP-versie 7.3 of ouder gebruikt in vijf dagen tijd gedaald van 8,3% naar 5,7%. Dit meet het aandeel van de waargenomen populatie die oudere versies gebruikt die geen officiële backports hebben ontvangen.
In deze periode daalde het aantal significant getroffen organisaties — gedefinieerd als organisaties met ten minste één blootgestelde en kwetsbare instantie — met ongeveer 47,9%. Ter referentie: onze data laat zien dat PHP zelf wordt gebruikt door 65% van de organisaties in onze dataset.
Samen zijn deze waarnemingen consistent met organisaties die hun exposure collectief verminderen door een combinatie van patchen, upgraden, het uitfaseren van getroffen machines en het beperken van internettoegang. (Let op: deze data toont de algemene trend, maar stelt niet de relatieve bijdrage van elke remediatiestrategie vast; de scan-dekking en de grootte van de waargenomen populatie kunnen ook de gerapporteerde cijfers over tijd beïnvloeden).
Een week na de publieke bekendmaking zijn minder dan 53% van de aanvankelijk getroffen organisaties nog steeds kwetsbaar voor PHP2Shell.
Door Wiz Research waargenomen exploitpogingen
We hebben tot nu toe de volgende soorten activiteiten waargenomen in deze context:
- Pogingen met het PHP2Shell-exploitmechanisme, met technieken die overeenkomen met publieke PoC's.
- Tools met de naam 'PHP2Shell' die niet gerelateerd zijn aan de kwetsbaarheden, maar in plaats daarvan vertrouwden op session poisoning en een aparte local file inclusion (LFI) kwetsbaarheid in de applicatie.
Pogingen met het PHP2Shell-exploitmechanisme
We hebben twee varianten waargenomen van een open-source exploit-kit die gericht is op PHP-gebaseerde software. Geen van beide heeft de exploit-keten voltooid in de pogingen die we hebben vastgelegd. De oudere variant stuitte op limieten voor de grootte van het verzoek of slaagde er niet in de verwachte conditie van geheugenuitputting (memory exhaustion) te creëren. De nieuwere variant putte het geheugen van PHP consistent uit, maar slaagde er niet in de geheugenadressen te verkrijgen die nodig waren om verder te gaan.
Variant 1: de legacy chain
Het eerste verzoek aan onze PHP-CGI honeypot kwam van 3.37.227[.]134. Dit kwam overeen met de oudere keten van de kit, te vinden onder archive/legacy-8m/exploit.py en de bijbehorende stage-scripts. De eerste volledige exploit-fase gebruikte een multipart body met 1.005 delen, inclusief een veld genaamd big gevuld met ongeveer 12 MB aan 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 MB
Volgens de aantekeningen van de kit probeert deze fase het geheugen uit te putten tijdens een session reset, waardoor de sessiestatus beschikbaar blijft voor een later verzoek.
Op onze honeypot mislukte dit voordat de code werd bereikt. De opgegeven grootte van het verzoek overschreed de geconfigureerde postmaxsize limiet van 8 MB, waardoor PHP de verwerking van de multipart body oversloeg en logde:
POST Content-Length of 12655437 bytes exceeds the limit of 8388608 bytes
De auteur heeft deze keten inmiddels verplaatst naar de archiefmap van de kit.
Een latere poging tegen Roundcube In een latere poging stuurde 103.151.172[.]95 een langere reeks vanuit de legacy chain. Deze bevatte vertraagde verbindingen die bedoeld waren om andere Apache-workers te bezetten. Wanneer er slechts één worker beschikbaar was, probeerde de exploit heap-shaping door verzoeken te sturen met 1.001 velden van elk 3.000 bytes. Deze verzoeken triggerden de vereiste memory exhaustion flow niet. Er is dus geen bewijs dat deze poging de beoogde conditie van geheugenuitputting heeft bereikt.
Variant 2: de huidige chain
De meeste IP-adressen die we hebben vastgelegd gebruikten de nieuwere keten, gebouwd vanuit pure/mka1.py en pure/mkleak_b.py. We hebben deze variant in meerdere pogingen waargenomen.
Deze variant kwam verder: de eerste fase zorgde consistent voor geheugenuitputting in PHP. De volgende fase, die probeert het procesgeheugen te lekken, mislukte in elke run die we vastlegden. De server logde een fatale fout die aangaf dat PHP zijn limiet had bereikt, bijvoorbeeld:
Allowed memory size of 134217728 bytes exhausted (tried to allocate 81920 bytes) in Unknown on line 0.
Verzoeken op dezelfde worker houden De keten is afhankelijk van het feit dat opeenvolgende exploit-verzoeken dezelfde Apache-child-process bereiken. Om de kans op dit scenario te vergroten, probeert de kit andere workers te bezetten met onvolledige verzoeken. Elke verbinding declareert een grote body, verstuurt één byte en blijft vervolgens hangen:
POST /index.php HTTP/1.1
Host: <honeypot>
Content-Type: application/x-www-form-urlencoded
Content-Length: 1048576
x
Eén adres, 178.249.214[.]6, opende 399 van deze verbindingen samen met 400 GET-verzoeken voordat de exploit-fasen werden verzonden. Dit adres is een VPN-exitnode, wat de conclusies over de bron beperkt.
Stage A1: triggering memory exhaustion A1 is een chunked multipart verzoek met een null-byte sessie-ID, 860 lege bestandsdelen met lange, diep geneste array-namen en verschillende groepen padding-velden:
POST /?q0=v&q1=v&q2=v&q3=v&q4=v HTTP/1.1
Host: <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 4000
Het verzoek is ontworpen om het geheugen uit te putten tijdens de afhandeling van de sessie, op een punt dat het sessie-ID naar vrijgegeven geheugen kan laten wijzen. Elk A1-verzoek dat we vastlegden gaf HTTP 500 terug, vergezeld van een PHP-fout:
Allowed memory size of 67108864 bytes exhausted ... in Unknown on line 0
Dit bevestigt dat A1 de beoogde conditie van geheugenuitputting op onze honeypot heeft bereikt. Het bevestigt echter niet dat de verouderde sessiestatus, die nodig is voor de volgende fase, is behouden.
Stage B1: attempting the memory leak B1 volgde ongeveer een seconde later. Er werd een ander chunked multipart verzoek verzonden met PHPSESSID=a, PHPSESSIONUPLOAD_PROGRESS=k0 en twee grote padding-velden.
Als dit verzoek dezelfde worker bereikt voordat PHP de verouderde sessiestatus reset, kan PHP herwonnen heap-inhoud wegschrijven in een PHPSESSID response cookie. De kit extraheert vervolgens heap- en libphp-adressen uit die cookie om de laatste exploit-fase voor te bereiden.
We hebben geen dergelijke lekken waargenomen. In bijna alle gevallen werd de verbinding gesloten zonder respons. De enige overgebleven run gaf een normale 32-karakter sessie-cookie terug. Geen van de bronnen verstuurde de uiteindelijke exploit-fase.
Waarom de lekken mogelijk zijn mislukt
De mislukte lekken benadrukken een bredere uitdaging: het bouwen van een gegeneraliseerde exploit die betrouwbaar werkt over verschillende PHP-versies en deployment-configuraties is moeilijk. De B1-layout van de kit was berekend voor de officiële php:8.4.26-apache image met een geheugenlimiet van 128 MB. Andere instanties, zoals onze Roundcube-honeypot, draaiden dezelfde PHP-versie vanuit een andere build, met extra extensies en een geheugenlimiet van 64 MB. Deze verschillen kunnen de heap-layout en het hergebruik van geheugen beïnvloeden, wat kan voorkomen dat het lek werkt zoals verwacht.
Betrouwbare worker pinning vormt een andere uitdaging. Opeenvolgende exploit-verzoeken moeten hetzelfde Apache-child-proces bereiken terwijl de vereiste sessiestatus behouden blijft. Time-outs van verzoeken, netwerklatentie en de beschikbaarheid van workers kunnen deze reeks verstoren. In onze eigen tests waren time-outs in combinatie met netwerklatentie voldoende om te voorkomen dat de keten via een internetverbinding werd voltooid.
Tot nu toe hebben we geen publiek beschikbare, gegeneraliseerde oplossing geïdentificeerd voor worker pinning of informatielekken over verschillende deployments heen. Het simpelweg kopiëren van publieke PoC's en deze op schaal uitvoeren, lost het werk niet op dat nodig is om een configuratie-specifieke exploit om te zetten in een betrouwbare operationele kit. We verwachten dat deze barrières in de loop van de tijd zullen afnemen; sommige dreigingsactoren hebben de expertise om de keten aan te passen en robuustere tooling te bouwen.
Andere pogingen
We zagen ook mislukte exploitpogingen van 15.204.59[.]70 en 162.35.99[.]94, maar deze scanners exploiteerden wel succesvol de honeypot van Adel Karimi. Dit was waarschijnlijk een bijdragende factor aan de beslissing van CISA om PHP2Shell op te nemen in hun KEV-lijst.
PHP2Shell-branded tools die niet gerelateerd zijn aan de kwetsbaarheden
We observeerden ook tools met het label 'PHP2Shell exploits' die in werkelijkheid geen poging deden om een van de twee kwetsbaarheden te exploiteren. Het vroegste verkeer hiervan, afkomstig van 85.11.187[.]35, kwam overeen met een Go-poort van “Chain A” van WoYinDao/CVE-2026-109618-CVSS-9.2-Critical.
De tool maakte gebruik van een langdurige session-poisoning techniek, waarbij geprobeerd werd PHP-code in een sessiebestand te schrijven via de upload-progress functie. Het onderstaande verzoek is ingekort:
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"
Vervolgens probeerde de tool die code uit te voeren door het sessiebestand in te sluiten:
GET /lfisink.php?c=id&f=/tmp/sessSUjKIKy3Rr6QsaJ1Ik7Rme8h3n HTTP/1.1
Cruciaal is dat lfi_sink.php een kwetsbaar eindpunt is dat wordt geleverd door de lab-omgeving van de PoC. De tool gaat ervan uit dat dit eindpunt bestaat op het doelwit; zonder dit endpoint of een equivalente local file inclusion (LFI) kwetsbaarheid kan de keten geen code uitvoeren.
Een variant met padding triggerde onze detectie voor geheugenuitputting, maar we zagen geen succesvolle code-executie. Ondanks de PHP2Shell-branding vertrouwde deze activiteit op een niet-gerelateerde techniek en een kwetsbaar applicatie-eindpunt.
Conclusie
We hebben nog geen succesvolle end-to-end PHP2Shell-exploitatie waargenomen in onze eigen telemetry. Echter, het publieke rapport van Adel Karimi en de ondersteunende data leveren het meest robuuste publieke bewijs dat we tot nu toe hebben gezien, waarbij exploit-verkeer, geheugenonthulling en daaropvolgende code-executie op zijn honeypots met elkaar in verband worden gebracht. Opmerkelijk is dat die doelwitten een gunstige single-worker Apache mod_php configuratie gebruikten, dus de resultaten bewijzen geen betrouwbaarheid over andere deployments heen.
Onze waarnemingen laten zien dat het alleen triggeren van geheugenuitputting niet voldoende is om de exploit-keten te voltooien. Verschillen in PHP-builds, geheugenlimieten en worker-gedrag kunnen voorkomen dat volgende fasen werken. De uitdaging voor opportunistische aanvallers is om huidige publieke PoC's om te zetten in vergelijkbare betrouwbare operationele tooling, of dit zelf te ontwikkelen. Naar onze mening blijft PHP2Shell een risico op zowel korte als lange termijn; het toepassen van PHP-beveiligingsupdates of remediëren via andere middelen blijft daarom essentieel.
IOC's
| Type | Indicator | Eerste gezien | Laatst gezien | Beschrijving |
|---|---|---|---|---|
| IPv4 | 85.11.187[.]35 | 2026-10-21 | 2026-10-21 | Exploitpoging |
| IPv4 | 172.206.2[.]199 | 2026-10-25 | 2026-10-25 | Scanner + exploitpoging |
| IPv4 | 3.37.227[.]134 | 2026-10-21 | 2026-10-21 | Exploitpoging |
| IPv4 | 103.151.172[.]95 | 2026-10-25 | 2026-10-25 | Exploitpoging |
| IPv4 | 178.249.214[.]6 | 2026-10-24 | 2026-10-24 | Exploitpoging (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 + exploitpoging (VPN) |
| IPv4 | 15.204.59[.]70 | 2026-10-24 | 2026-10-24 | Exploitpoging |
| IPv4 | 162.35.99[.]94 | 2026-10-24 | 2026-10-24 | Exploitpoging |
Groetjes,