The Patch Window Is Gone: What PHP2Shell and Storm-0940 Tell Us About the Investigation Clock
PHP2Shell drew attack traffic before its patch shipped, and Storm-0940 reached privileged cloud access in under three hours. What that means for how fast investigations have to run.
What PHP2Shell and Storm-0940 tell us about the investigation clock
On Saturday, October 17, someone threw a PHP2Shell exploit attempt at an Amazon MadPot honeypot. The details would not leak until Tuesday. The CVEs and the patch would not go public until Wednesday. Whoever sent that request had working knowledge of an embargoed vulnerability four days before the rest of us knew it existed.
Then Wednesday got messy. One of the research teams that found the bugs accidentally posted a proof of concept video. The PHP project pushed its release a full day early. Attack traffic was already showing up six hours before the patch went public, and by the next morning Amazon was seeing payloads varied enough to conclude that several different actors were involved.
I have been doing this long enough to remember when "patch Tuesday" meant you had a week or two before anything serious showed up. That window did not shrink here. It went negative.
PHP2Shell is two memory safety flaws in the PHP runtime, CVE-2026-109618 and CVE-2026-109619, affecting mod_php and PHP-FPM in every version back to 5.4.0. Both teams that found them used frontier AI models to do it. A limited version of the flaw had been spotted in 2024 and written off as low impact. Nobody chained it until the models did. That is the part of this week that will repeat. Models are finding serious bugs in old, widely deployed code faster than the world can patch it, and every finding starts the same fire drill.
To be fair about the risk: most of the exploit code circulating publicly fails against a default PHP install, and confirmed compromises are still scarce. Broadly probed and broadly compromised are different claims, and right now the evidence supports the first. That offers less comfort than it sounds. The gap between a bug existing and attackers probing for it collapsed to days, and here it ran backward past disclosure. The only buffer left is the time it takes for a reliable weaponized chain to circulate, and nobody should plan on that being wide.
The other side of the same clock
The same day the patch shipped, Microsoft published its research on Storm-0940, a China aligned actor that Microsoft now assesses was behind the ConnectWise supply chain compromise. What stands out is the tooling. Since at least September, Storm-0940 has been running ARTEX, an open source agentic pen testing framework that chains LLM driven agents from reconnaissance through exfiltration with very little human involvement.
The numbers Microsoft published are the ones worth reading twice. Hundreds of organizations targeted across more than a dozen industries. Multiple cases where the time from initial targeting to privileged cloud access was under three hours. Against ConnectWise downstream tenants, the framework attempted sign ins to more than 2,250 tenants at a peak of 2,900 attempts per minute. Once it held stolen application credentials, the agents authenticated into Microsoft 365 environments without any interactive user sign in, then moved through Graph: reconnaissance, application credential changes for persistence, attempts to modify privileged roles.
Microsoft's own phrasing on what that does to a defender is blunt. The activity generates plenty of log data and plenty of alerts. The speed is what leaves very little time to respond and remediate in any coordinated way.
Put the two stories next to each other and you get the whole picture. AI found the bug. AI runs the campaign. The humans on the attacking side are now choosing targets and reviewing results, and the humans on the defending side are still opening consoles.
What "ready" means now
Every advisory this week says the same things: patch, hunt, review logs. The questions behind that advice have not changed. Are we vulnerable? Can we patch in time? Can we check for signs of compromise? What changed is how fast you have to get through all three, and how many systems you have to touch to do it.
Microsoft's response guidance for the ConnectWise exposure is a good example. It is solid advice, and following it means pulling sign in records, audit trails, and application telemetry from four to six different consoles, each with its own query language and its own retention. The clock started before you read it.
PHP2Shell is the same shape. You need a software inventory that catches PHP on managed servers and on the backup appliances, VoIP systems, and monitoring boxes that nobody patches because nobody can. You need process ancestry from your EDR: php-fpm or httpd or apache2 spawning sh, curl, wget, python. You need web logs for multipart POSTs carrying PHP_SESSION_UPLOAD_PROGRESS from unfamiliar sources. Princely Dmello has written up both PHP2Shell hunts for Defender, and the investigation that chains them to a verdict.
A clean process tree does not close the case. One of the two bugs can hand freed worker memory back to the client inside a PHPSESSID cookie without ever running code on the host. There is no child process, no dropped file, and nothing for an endpoint agent to see. That memory can hold session tokens, API keys, passwords, and TLS private keys from other requests. The traces, if there are any, live in web server, WAF, and CDN logs: odd multipart requests followed by memory limit errors, bursts of 500s, oversized PHPSESSID cookies. If an exposed host held secrets, assume they may be out, rotate them, and go look at where those credentials were used next. That last step is the one most teams skip, and it is what turns a server question into an identity investigation.
What I keep seeing in practice is that each of those checks is known to someone on the team. The senior analyst who lived through the last Exchange wave knows exactly what the web shell hunt looks like. The identity person knows which Entra audit operations matter after an OAuth app gets popped. The problem is that the knowledge lives in their heads, their saved queries, and a Slack thread from eight months ago, and when the next PHP2Shell drops on a Friday afternoon the person who knows is on PTO.
Where Command Zero fits
This is the problem we built Command Zero around, and this week is a clean example of why. Two things matter.
First, the investigation has to run where the data already lives. The Entra sign in logs, the Defender process events, the Purview audit trail, your EDR telemetry: none of that needs to be centralized before you can ask a question of it. Command Zero's federated model queries each source in place and brings the answers back together, so "which hosts spawned a shell from a PHP worker in the last ten days, and which of those also show session activity from outside our expected infrastructure" is a single investigation rather than a four console afternoon.
Second, the investigation pattern itself has to be captured as something executable. When your best analyst works through the response guidance and figures out the sequence of checks that produces a verdict in your environment, that sequence should become a Question anyone on the team can run next time. It walks the same evidence path, shows every piece of evidence it pulled, and lets a less experienced analyst reach the conclusion the senior person would have, with the reasoning visible the whole way through.
That last part is not a nice to have. When the adversary is an agent moving at 2,900 attempts per minute, the temptation is to answer with an autonomous agent of your own and let it make the calls. I think that is the wrong trade. You want the speed on the evidence gathering and the correlation, and you want a human looking at a transparent result before anyone starts revoking credentials and disabling applications. Microsoft's own advice this week includes "do not delete enterprise applications as the first response" for exactly this reason. Speed without visibility produces a different kind of incident.
This will not be the last one
The discovery rate for serious bugs in old code is climbing. One AI-driven bug hunting program reported hundreds of findings in its first week, and two teams found PHP2Shell independently with different model stacks. A cheap defensive version, a model checking every commit before it ships, will come. It will not help the PHP 5.4 install on a backup appliance that nobody is compiling anymore. The installed base of old code is where this week's problem lived, and it is where the next one will live too. Until that curve bends, the investigation clock is what you have to live with.
So the question for a security team is how long it takes, from the moment an advisory lands, to answer “are we exposed, did anything touch us, and what did it reach” with evidence you can show someone. If that number is measured in days of console hopping, this week was a warning. Treat it like one.
Related reading: Hunting ConnectWise and SkyKick app abuse in Microsoft 365 · Autonomous Investigation vs. Autonomous Response



