An internet-facing PHP system does not need to be well known to become a target. In our honeypot, one automated scanner moved from first contact to PHP2Shell-shaped exploitation traffic in 4 minutes and 22 seconds. It tested hundreds of paths, shifted from discovery into exploit probes, and then sent a concentrated series of crafted POST requests to the application.
The exploitation attempts did not produce verified execution.
That distinction is the most useful part of the story. Internet scanning is fast, broad, and cheap; reliable exploitation is a separate problem. Treating every suspicious request as a compromise creates noise, while relying on access logs alone can miss the transition to execution. Defenders need evidence that follows an attack from the request to the worker, operating system, and any outbound connection or persistence attempt.
For security leaders, the result supports three immediate priorities: patch exposed PHP systems, validate that execution-level telemetry is arriving, and assign containment ownership before the first probe. HTTP alerts establish targeting and intent; worker and host behavior establish whether the attempt changed the system.
This article describes what we observed during a small, instrumented honeypot experiment conducted from October 21 through October 26, 2026. It is not an estimate of global exploitation volume. It is a field report on attacker behavior, detection design, and the limits of HTTP-only conclusions.
Attack overview
The test environment included a persistent PHP decoy, short-lived public instances launched every 15 minutes, and a separate three-sensor cohort configured to match the profile in a public packet-to-process report of confirmed PHP2Shell execution: PHP 8.4.26, Apache mod_php, one prefork worker, a 128 MiB PHP memory limit, session upload progress enabled, and plaintext HTTP.
The isolated workloadsblocked web-worker egress, audited host behavior, forwarded evidence to Splunk and CloudWatch, and connected confirmed execution signals to automated containment. The exact-match cohort also retained packet evidence.
The clearest attack sequence came from one source during a 4-minute, 22-second window:
The scanner began with high-volume reconnaissance.
Ten seconds later, it tested its first exploit-oriented path.
Over the next several minutes, it requested hundreds of distinct paths associated with exposed configuration, common frameworks, development artifacts, and known vulnerabilities.
At 3 minutes, 29 seconds, it began a short burst of PHP2Shell-shaped POST requests to /index.php.
The sequence ended at 4 minutes, 22 seconds with no observed host execution.
The source sent more than 1,700 requests and touched more than 800 distinct paths. Approximately 98% of the activity was reconnaissance; the remainder included exploit probes and PHP2Shell candidates. Thirty PHP2Shell-shaped requests reached the application. None produced a successful process spawn, callback, webroot modification, or captured payload.

Figure 1. One source compressed reconnaissance, exploit-path testing, and PHP2Shell-shaped POST traffic into 4 minutes and 22 seconds. The sequence produced no verified execution.
Request speed, path breadth, deterministic ordering, and repeated user-agent behavior establish high-confidence automation. They do not reveal the scanner's software architecture or establish that an AI agent drove it.
What changed after the exact-match workloadswent live
Three workloadsmatching the PHP 8.4.26 single-worker profile received first contact 6 minutes 13 seconds, 8 minutes 44 seconds, and 9 minutes 58 seconds after exposure—an average of about 8.3 minutes. We added the cohort on October 26 to test how quickly newly exposed systems matching the publicly reported profile would be found.

Figure 2. All three exact-match workloadsreceived unsolicited contact within 10 minutes. Contact demonstrates reachability and scanning, not exploitation.
Those early contacts were probes, not a successful PHP2Shell chain. The workloadsreturned a mixture of HTTP 200, 400, and 404 responses. Packet evidence showed ordinary service identification and malformed-method testing. We did not observe the multipart upload sequence, memory-exhaustion behavior, worker reuse pattern, process execution, or outbound callback needed to support a successful-exploitation conclusion.
Three workloadscannot characterize the internet, and a quiet first hour does not demonstrate safety. The cohort shows only that newly exposed services can enter routine scanning traffic within minutes.
The wider rotating fleet continued to receive broad automated campaigns. From October 25 at 15:26 UTC through October 26 at 15:23 UTC, about 86% of roughly 2,100 classified events were reconnaissance and 9% were malicious. No requests in that fixed window matched our PHP2Shell classification. The malicious traffic instead concentrated on secret discovery and unrelated exploit paths.

Figure 3. Reconnaissance dominated the fixed 24-hour window. The malicious subset focused on secret discovery and unrelated exploit paths; none matched the local PHP2Shell classification.
Two bursts illustrate the behavior. One source requested 301 distinct paths in 63 seconds, including .env, Git metadata, backup files, WordPress configuration variants, Spring Boot actuator routes, and PHPUnit's historical eval-stdin.php path. Another covered 298 paths in 49 seconds. A separate tool identified itself as Go Web Pentest Tool while testing more than 100 paths in under 20 seconds.
This is a high-speed compatibility sweep, not careful target selection. A PHP server may receive probes for unrelated frameworks, repositories, secrets, and products in the same second.
What did not happen
No confirmed compromise appeared in the HTTP, process, network, file, and containment telemetry reviewed through October 26 at 15:30 UTC.
The host-level evidence was consistent across the permanent decoy, rotating instances, and the new exact-match cohort:
No successful web-worker shell or interpreter spawn was recorded.
No successful web-worker network connection was recorded.
No suspicious write to the exact-match web roots or monitored temporary paths was recorded.
No uploaded payload was captured.
No PHP2Shell-related CloudWatch alarm entered an alarm state; because those alarms treated missing data as non-breaching, this result was evaluated alongside the underlying host and application records rather than used as proof on its own.
No exact CISA campaign indicator matched from October 23 at 15:30 UTC through October 26 at 15:30 UTC.
Two network-connect events on the permanent decoy failed. Denied exact-match sensor events occurred during bootstrap, before exposure. We excluded these unsuccessful baseline events from attacker outcomes.
HTTP status codes were not treated as proof. A 200 can mean the decoy served bait; a 500 can reflect an application error or worker failure. Execution requires downstream evidence such as a worker-created process, network connection, file change, correlated crash, or containment action.
Detection lessons from the experiment
1. Build an evidence ladder, not one giant signature
We separated observations into four levels:
Contact: a public source reached the service.
Intent: the request targeted secrets, known exploit paths, or PHP2Shell-specific structure.
Effect: the PHP or Apache worker crashed, restarted, wrote a file, or attempted a new connection.
Execution: the web-worker identity successfully created a process or established an outbound session.

Figure 4. The observed sequence established contact and intent, but the reviewed telemetry did not verify downstream effect or execution.
That separation makes alerts explainable. A request for PHPUnit's historical eval-stdin.php path is an attempt, not proof that PHPUnit exists. A structured multipart request can establish higher-confidence intent, but a new shell, interpreter, downloader, or network connection under the web-worker identity is the execution evidence that should page an analyst.
2. Correlate the request with the worker
PHP2Shell is not well served by access logs alone. Defenders need request context and, where possible, the worker or process identifier. Error logs should preserve memory-exhaustion and child-process events, while host telemetry correlates them with process, network, and file activity.
The question is not whether every out-of-memory error is exploitation. It is whether an anomalous request immediately preceded a worker state change or an action that worker should never perform.
3. Tune public rules to the telemetry you actually have
CISA's PHP2Shell Sigma rule is marked test and explicitly warns of medium-to-high false-positive potential. Its logic includes HTTP structure, PHP error branches, process behavior, command strings, infrastructure, and public campaign indicators. Treating every keyword as an independent critical alert would produce noise.
Our implementation separated exact intelligence matches, structured HTTP attempts, PHP failure signals, and host-confirmed behavior. Generic command strings were not critical without the required process or request context.
4. Preserve artifacts, but scope packet capture carefully
Full packet capture helped validate what reached the exact-match workloadswhen access-log parsing was incomplete. It also exposed an instrumentation hazard: a broad tcp port 80 capture on all interfaces can collect the host's own link-local metadata and management traffic, not just inbound honeypot requests.
Before continuing full packet capture, research workloadsshould capture on the intended external interface and direction, exclude link-local and management destinations, encrypt stored evidence, restrict bucket access, and define short retention. Existing captures should be treated as sensitive until they have been reviewed, sanitized, or expired. Payload collection should be minimized to the evidence required for the research question. The capture system itself must not create a new source of sensitive data.
5. Monitor the monitoring
The exact-match cohort produced packet and access evidence, but missing method and path extractions reduced request-level attribution and classification quality.
Telemetry health needs its own alerts: last event received, field-extraction coverage, clock skew, forwarding status, packet-export success, disk usage, and the difference between “zero detections” and “no data.” A quiet execution panel is only reassuring when the underlying audit source is demonstrably alive.
Containment and validation
The workloadsused defense in depth because a successful research honeypot should collect evidence without becoming an attacker platform.
The PHP worker used a read-only webroot, restricted temporary storage, reduced Linux capabilities, resource limits, and blocked outbound connections. Audit rules watched process, network, and file activity. CloudWatch alarms and Lambda kill switches could stop a sensor on confirmed host behavior.
These controls do not patch PHP and should not be presented as a production alternative to upgrading. The PHP project states that fixed releases are PHP 8.2.35, 8.3.36, 8.4.27, and 8.5.12, and that updating is the only complete solution. In the honeypot, the controls existed to limit harm after an intentionally vulnerable process was exposed.
A representative validation plan for defenders is straightforward:
Confirm that PHP and Apache access, error, and process telemetry arrive in the SIEM.
Generate a benign multipart request containing the same observable fields your detection uses, without reproducing the memory-corruption chain.
Verify that the request is classified as a test and linked to the correct worker or host.
Run an authorized host-level simulation that makes a web-worker test identity attempt a denied process or network action.
Confirm that the high-severity alert, containment workflow, and evidence preservation all fire as designed.
Keep detection validation separate from exploitation testing. A safe detection test proves the pipeline works. It does not prove the target is exploitable or patched.
The operating model matters as much as the rule logic. Application owners should own patching and exposure reduction. Detection engineering should own request-to-host correlation and telemetry-health checks. Incident response should own the execution threshold, evidence preservation, and containment workflow. Each control should have a named owner and a repeatable test proving that it works.
What the first five days mean
Attack automation compressed discovery, enumeration, exploit selection, and delivery into 4.4 minutes, while reliable exploitation remained the harder step.
For defenders, the response cannot depend on noticing a suspicious request and then beginning an investigation from scratch. By that point, the scanner may already have tested hundreds of paths and moved into payload delivery. The request, host, and containment controls described above should already be tested and ready.
Our evidence supports three conclusions: newly exposed PHP services are discovered within minutes; broad scanners mix reconnaissance, secret hunting, and exploit probes; and only correlated worker and host evidence can distinguish PHP2Shell-shaped traffic from successful compromise.
We have not observed a successful PHP2Shell exploit in this environment. That is a result, not a guarantee. The workloads remain online, and the evidence threshold remains the same: a crafted request is an attempt; host behavior is the proof.
Ready to see Aviatrix in action?
Get a personalized live demo walkthrough or explore our latest deep-dive cloud threat research intelligence.



