Oct 28, 2026 · 5 min read

Checking whether php2shell hit you takes three log sources

CISA php2shell hunt rule has four branches across three log sources, and the PHP error log is the one most teams never ship

Article header: Checking whether php2shell hit you takes three log sources

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.

Timeline of the php2shell sequence: October 17, 2026, Amazon Threat Intelligence observes an exploitation attempt in MadPot telemetry. October 21, proof-of-concept exploits circulating by 02:00 UTC, PHP embargo lifts at 14:00 UTC and 8.5.12, 8.4.27, 8.3.36 and 8.2.35 ship, CISA publishes its SIGMA hunt rule. October 23, the rule is last modified. October 26, CISA adds CVE-2026-109618 and CVE-2026-109619 to KEV with forensicTriage set to Yes. October 29, the KEV remediation deadline. The lookback starts four days before public disclosure and twelve days before the KEV deadline.

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. POST and index.php and PHPSESSID and PHP_SESSION_UPLOAD_PROGRESS, plus one of a marker list that includes multipart/form-data, B7kQpoc61, BNDRY12345 and long runs of repeated characters.
  • Process-creation telemetry. PHP_SESSION_UPLOAD_PROGRESS and one of php-cgi, apache2, httpd, php-fpm, mod-php, and one of twelve shell-and-tooling strings running from /bin/sh and powershell to curl, wget and whoami.
  • PHP's own error log. PHP Fatal error: and Allowed memory and in Unknown. This is a memory-exhaustion artefact, and it is the only branch that fires on an attempt that failed.
  • Webroot file content. < and php and echo and system and ($_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

  1. 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.
  2. 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.
  3. Find where error_log resolved 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.
  4. Run the hash and domain indicators first, then the four behavioural branches, then the IP list last and as leads.
  5. 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

← All articles