
CISA added CVE-2026-109618 and CVE-2026-109619 to the Known Exploited Vulnerabilities catalog on October 26. Both entries carry a dueDate of 2026-10-29 — three days — and both carry forensicTriage: Yes. The alert they hang off, Critical Vulnerabilities in PHP Require Immediate Patching, now opens with a banner: "CISA has updated this Alert to reflect the addition of CVE-2026-109618 and CVE-2026-109619 to its Known Exploited Vulnerabilities (KEV) Catalog on Oct. 26, 2026."
The requiredAction on both entries points at CISA's "Forensics Triage Requirements" alongside the patch instruction. That is a different question from the one everyone answered last week. Patching is a statement about now. Forensic triage is a statement about a window — and the window does not open on the disclosure date.
The window starts October 17
Amazon Threat Intelligence reported on October 21 that it "identified a PHP2Shell exploitation attempt dating to Oct. 17, 2026, in MadPot telemetry, four days before public disclosure." It also places proof-of-concept exploits in circulation from around 02:00 UTC on October 21, twelve hours before the PHP embargo lifted at 14:00 UTC. Its instruction is unambiguous: "Start investigations from the earliest known exploitation, not from the disclosure date. For PHP2Shell, investigate from at least starting on October 17th."
Guidance arrived in the wrong order for anyone trying to answer that. PHP shipped 8.5.12, 8.4.27, 8.3.36 and 8.2.35 on October 21; the fallout that day included a municipal web vendor pulling a platform offline, which is legible in the restore order on its own status page. That piece recorded that neither CVE was in KEV as of the October 23 release — true then, superseded on the 26th. CISA's SIGMA rule was published October 21 and last modified October 23. The KEV listing landed on the 26th with a deadline on the 29th, the three-day shape BOD 26-04 made standard.

Four branches, and the log each one reads
Read the rule, not the alert. CISA_SIGMA_261429_CVE_2026_109618-109619_PHP2Shell_TLP_CLEAR.yaml is a flat OR across four behavioural branches plus an indicator list, and each branch reads a different telemetry source:
- Web access logs.
POSTandindex.phpandPHPSESSIDandPHP_SESSION_UPLOAD_PROGRESS, plus one of a marker list that includesmultipart/form-data,B7kQpoc61,BNDRY12345and long runs of repeated characters. - Process-creation telemetry.
PHP_SESSION_UPLOAD_PROGRESSand one ofphp-cgi,apache2,httpd,php-fpm,mod-php, and one of twelve shell-and-tooling strings running from/bin/shandpowershelltocurl,wgetandwhoami. - PHP's own error log.
PHP Fatal error:andAllowed memoryandin Unknown. This is a memory-exhaustion artefact, and it is the only branch that fires on an attempt that failed. - Webroot file content.
<andphpandechoandsystemand($_GET['and>— a dropped shell, which patch-and-redeploy may already have deleted.
Most teams ship the first and, on a good day, the second. The third is the gap. A PHP-FPM pool writes to whatever error_log resolves to, which is usually a file on the web node, rotated locally and shipped nowhere, and it only exists at all if log_errors was on:
; pool.d/www.conf — set explicitly rather than inherited
php_admin_flag[log_errors] = on
php_admin_value[error_log] = /var/log/php-fpm/www-error.log
It is worth the effort precisely because it catches the attempts that did not work — on an internet-facing host, most of them. The cost is ingest volume: a PHP error log is overwhelmingly deprecation notices and warnings, so centralising it means paying for noise or writing a ship-side filter that keeps PHP Fatal error: and drops the rest. Process-creation telemetry costs an agent on hosts often built as disposable images with the agent deliberately left out.
Two things about the rule itself. Its logsource is product: cisa, a placeholder, so it will not convert cleanly to any real backend without you mapping fields by hand. And CISA states its own false-positive rate as "medium-high with some strings/branches," adding "use this rule in an infected environment/logs." It is a hunt rule, not a detection you deploy.
One correction before you tune on it: the indicator branch is not uniformly high-confidence. Its hashes and the three .st domains are, but AWS says of the IP addresses that they "include shared anonymization infrastructure and are not exclusive to this threat activity" and that organisations "should investigate any observations involving these addresses as opposed to blocking." A hit on one of those fourteen addresses is a lead, not a finding.
What to check this week
- For every internet-facing host that served PHP on October 17, confirm the web access log for that date is still queryable. Not the retention policy — the actual query, with a result.
- Run the same check against process-creation events from those hosts. On web nodes specifically, the usual answer is that the agent was never deployed there.
- Find where
error_logresolved to on each PHP-FPM pool, and whether anything from October 17 survives rotation. A node rebuilt during the October 21 patch window took that evidence with it. - Run the hash and domain indicators first, then the four behavioural branches, then the IP list last and as leads.
- Write down which of the three retentions did not reach October 17. That is a finding about your logging, and the one you can still fix before the next KEV entry carries this flag.
A version scan answers none of this. It tells you the host runs 8.3.36 today, not whether the host that ran 8.3.35 on October 17 kept the records that would say what happened to it.
North InfoSec runs AI-assisted penetration testing and security assessments, including evidence-readiness checks of the kind described above. northinfosec.com