PHP2Shell Vulnerability search:
For the PHP2Shell Critical Vulnerability Blog: Please read the official Dynatrace blog, which includes a CVE-2026-109618 & CVE-2026-109619 overview, affected PHP versions, remediation guidance, and how Dynatrace helps identify affected workloads and signs of exploitation. This post will help you leverage Dynatrace to find the Hosts/Processes impacted by these vulnerability.
-
RCE via OOM corruption, CVE-2026-109618 (GHSA-ww8hw-w9fx-j79): out-of-memory handling can interrupt PHP while request data is only partially initialized, causing cleanup to treat invalid data as valid.
-
RCE via stale global state, CVE-2026-109619 (GHSA-6wmf-4rv5-p3rp): request-owned state may persist after its memory is freed, allowing a later request on the same worker to use stale state before reinitialization.
The following Notebooks DQL will help you identify impacted Hosts/Processes of the above mentioned vulnerabilities.
// PHP risk check: find PHP processes, the host they run on, and whether the PHP version is vulnerable or mitigated.
smartscapeNodes PROCESS
| filter iAny(arrayConcat(process.software_technologies.os, process.software_technologies.php)[][type] == "PHP")
| traverse {runs_on}, {HOST}, fieldsKeep:{name, process.software_technologies.os, process.software_technologies.php}
| fieldsAdd process_info = dt.traverse.history[0]
| fieldsAdd technology = arrayConcat(process_info[process.software_technologies.os], process_info[process.software_technologies.php])
| expand technology
| filter technology[type] == "PHP"
| fieldsAdd php_version = technology[version]
| filter php_version != "null"
| fieldsAdd version_parts = splitString(php_version, ".")
| fieldsAdd major = toLong(version_parts[0]), minor = toLong(version_parts[1]), patch = toLong(version_parts[2])
| fieldsAdd first_safe_patch = coalesce(if(minor == 2, 35), if(minor == 3, 36), if(minor == 4, 27), if(minor == 5, 12), 0)
| fieldsAdd vulnerability_status = if(
(major < 8) or (major == 8 and minor <= 1), "VULNERABLE",
else: if(major == 8 and patch < first_safe_patch, "VULNERABLE", else: "MITIGATED"))
| fieldsAdd priority = if(vulnerability_status == "VULNERABLE", 1, else: 2)
| fields process.name = process_info[name],
dt.smartscape.process = process_info[id],
host.name = name,
dt.smartscape.host = id,
php_version,
vulnerability_status,
priority
| filter in(vulnerability_status, if(arraySize(array("VULNERABLE","MITIGATED")) == 0, array(""), else: array("VULNERABLE","MITIGATED")))
| dedup {dt.smartscape.process, php_version}
| sort priority asc, php_version desc, host.name asc
| fieldsRemove priority