I have read most of the PHP2Shell guidance that went out this week. It is good advice. Map your internet-facing assets. Patch the externally reachable systems first. Inventory every install including containers, CI runners and appliances. Where you cannot patch, follow the project's interim instructions. Put end-of-life branches behind a WAF or take them off the internet. Rebuild container images from updated base images.
Every one of those steps is correct and I would not remove any of them.
Now notice the shape. Six steps, and five of them are about stopping the next request. Detection, where it appears at all, is the last line — one sentence suggesting you alert when php-fpm or apache2 spawns a shell. Some of the guidance does not mention it at all.
I do not think that is carelessness. It is what happens when a remediation checklist is written by people whose product stops at remediation. The list reflects the capability of whoever wrote it, and detection is the step that gets compressed into a bullet because expanding it would mean admitting there is nothing in the box to help you do it.

For a normal critical vulnerability, prevention-first is the right sequence. The advisory lands, the patch lands with it, and if you move quickly you were probably never exposed. Detection is a reasonable afterthought because the window between disclosure and remediation was yours to control.
PHP2Shell did not work that way. The write-up leaked on 20 October. The fixed releases — 8.5.12, 8.4.27, 8.3.36 and 8.2.35 — shipped on 21 October. For roughly a day, a credible description of two unauthenticated remote code execution flaws was public and no fix existed. Nobody patched their way out of that window, because there was nothing to patch with.
So the question that matters is not only whether you are exposed now. It is whether anything happened during the day you could not have defended against, and during however many additional days it took your organization to actually get the update deployed and every worker pool restarted. For most estates that second number is considerably larger than the first.
A checklist that ends at "rebuild your images" answers the first question and leaves the second one entirely open. You finish the list, every item is green, and you still do not know.
.gif)
The usual response to "how do I know if I was hit" is to ask for indicators. Give me the hashes, give me the IP list, I will run them against my logs and tell you.
That does not work here. There are no published file hashes and no reliable attacker IP list. Reporting on exploitation is itself contested — watchTowr says its honeypot network observed exploitation on 21 October, Huntress reports no confirmed indicators of compromise, and at the time of writing it is not in CISA's KEV catalog. You cannot signature your way to an answer when there is no signature and the community cannot agree on whether the thing is being exploited at all.
What is left is behavior. A successful attack here looks like a PHP worker process doing something a PHP worker process has no business doing: spawning sh or bash or powershell, reaching for curl or wget or certutil, opening a reverse shell, running whoami from the web tier. That behavior is anomalous no matter which of the two bugs produced it, and no matter whether the leaked write-up described the mechanism correctly.
Writing that detection is not conceptually hard. Writing it, tuning it against your actual traffic so it does not drown the on-call in false positives from legitimate shell-outs, deploying it across the estate, and doing all of that inside the window where the evidence still exists in logs that rotate — that is the hard part. It is a week of engineering for most teams. It is a bullet point in everyone else's advice.
.gif)
We wrote the detection signature for PHP2Shell when it broke, and it is running for customers now.
I want to state that plainly, because it is the difference between advice and a deliverable. "Alert when php-fpm spawns a shell" is not a detection. It is a description of one. The detection is the artifact — the rule itself, tuned against real traffic so it does not bury an on-call engineer under every legitimate shell-out, deployed across an estate that has already been inventoried, and looking for the behavior rather than waiting on a hash that is never going to be published.
That artifact exists. Our AI agents are running it against customer environments today, hunting for a PHP worker doing something a PHP worker should never do.
Other vendors will tell you to patch. So will we — it is the same correct advice and we are not pretending otherwise. The difference is what happens after the patch, when the question becomes whether the window that opened before anyone had a fix was used against you. We can answer that. Most of the guidance published this week does not attempt it.
I want to be fair about why this keeps happening, because it is not unique to one vendor and it will happen again on the next advisory.
Prevention is legible. You can count patched hosts, you can put the number in a dashboard, and when the number reaches the total you are finished. Detection has no such endpoint. You deploy a rule, you tune it, you look, and a clean result is indistinguishable from not having looked carefully enough. It is harder to sell, harder to report on, and genuinely harder to build.
So it migrates to the end of the list, where it survives as a gesture. And on an ordinary CVE you can mostly get away with that. On one where the exploit details went public before the fix did, you cannot — because the prevention steps, however diligently executed, are addressing a window that already closed.
Patching tells you the door is shut. Only detection tells you whether anyone already walked through it.
Kai has the PHP2Shell detection signature and our agents are running it across customer estates. If you want to know whether the pre-patch window was used against you, ask.