PHP2Shell: A Detection and Incident Response Guide for Blue Teams
Your SOC receives an alert about an unusual request to a public-facing PHP application. The server returned an error, but a second alert shows the web server starting an unexpected shell. Did the request fail, or did the attacker get in?
The opening scenario and timeline are illustrative. Advisory information checked on 28 October 2026.
1. Understanding PHP2Shell
PHP2Shell refers to two critical vulnerabilities in PHP itself: CVE-2026-109618 and CVE-2026-109619. PHP is the software that runs server-side application code. Because these flaws affect that underlying software, updating WordPress, another application, or its plugins does not replace updating PHP.
Both vulnerabilities involve PHP handling memory incorrectly, but their timing differs. A worker is the process that handles incoming web requests:
- CVE-2026-109618: unsafe cleanup after a memory-allocation failure. PHP can stop while preparing internal request data, then treat that unfinished data as valid during cleanup. A demonstrated attack can execute code within a single request.
- CVE-2026-109619: stale state carried between requests. A worker can retain a reference to memory that has already been released. A later request handled by that worker can reach the stale state before PHP resets it.
For an analyst, that distinction changes the search window: inspect the suspicious request and earlier activity handled by the same worker, not just the final alert. PHP advisories
PHP confirms unauthenticated code-execution paths with the worker's permissions. Application files, database credentials, and other service-account data may be exposed; this does not automatically grant administrator access.
PHP identifies Apache deployments using mod_php as the highest demonstrated risk because a confirmed attack path runs before application code, including its login checks. Other deployments, including PHP-FPM, still need attention. The exact conditions differ, so do not assume every server is equally exploitable or that a login page makes it safe. PHP security guidance
2. Finding the Systems That Need Attention
Start with the PHP installation actually serving the application. A server can have several PHP versions installed, and the command-line version may differ from the one handling web traffic. Ask the service owner to confirm the running package and the application instances that use it.
PHP released these fixes for the original two vulnerabilities on 21 October:
| PHP branch | First fixed upstream release |
|---|---|
| 8.2 | 8.2.35 |
| 8.3 | 8.3.36 |
| 8.4 | 8.4.27 |
| 8.5 | 8.5.12 |
A distribution vendor may supply the fixes in a package with a different version number. Verify its advisory instead of relying only on a banner. For older, unsupported branches, confirm an applicable vendor fix or move to a supported release.
Prioritize internet-facing services and applications with access to sensitive data. Record the hostname, affected backend, PHP package, and service owner. If several servers sit behind a load balancer, check every server, not just the one that answered your first request.
There is also a separate 23 October follow-up, CVE-2026-115560. It affects applications that start with the php_binary or php_serialize session format, switch to php at runtime before starting the session, and have session upload progress enabled. PHP advises affected deployments to disable that feature while awaiting the next regular bugfix release. Have the application owner check these conditions; the original patch alone does not resolve this separate issue. PHP follow-up notice
3. Recognizing Activity Worth Investigating
What the threat reporting establishes
As of 28 October, PHP2Shell is more than a theoretical risk. The timeline also shows why an exposure count, an attack attempt, and confirmed execution must stay separate:
- 17 October — attempts before disclosure. AWS traced a MadPot honeypot attempt to this date, but could not establish whether the early attempts would succeed against real-world systems.
- 20–21 October — warning and fixes. PHP issued advance notice, then released the security updates on 21 October. AWS reports broader attempts after disclosure.
- 24 October — observed execution. Adel Karimi's honeypot report correlates exploit requests, memory disclosure, and Apache-parented shells. The targets used single-worker Apache
mod_php; this is evidence of successful honeypot exploitation, not proof of equivalent reliability across deployments. - 25 October — an attribution corrected. Unit 42 retracted its earlier PHP2Shell attribution for a government-agency incident because it could not confirm the initial-access mechanism.
- 26 October — known exploitation recognized. CISA added both CVEs to its Known Exploited Vulnerabilities catalog. Prioritize remediation; inclusion does not establish compromise of any particular server.
Unit 42 also reported over 22.6 million exposed instances potentially vulnerable in its telemetry. That is an exposure estimate, not a count of exploited systems. Wiz's follow-up describes failed chains in its own telemetry while recognizing successful exploitation on Karimi's honeypots. Different observations are compatible when builds, memory limits, and worker behavior differ.
Set the investigation window accordingly: review retained activity from at least 17 October for systems exposed then, and go earlier where evidence warrants. Do not treat disclosure day as the start of risk. Record retention gaps. AWS also cautions that some reported IPs are shared anonymization infrastructure: use matches as leads, not standalone attribution or blanket blocklists.
Turn the reporting into a log search
Start with reverse-proxy or web-server access logs, PHP error logs, and endpoint events. Investigate unusual POST requests or unexplained PHP-worker activity, then correlate the available records. Include multipart upload bodies and URL-encoded form submissions. Do not require a memory error, worker crash, restart, or particular HTTP status. PHP may parse input before application code runs, even on endpoints without an upload form.
Telekom observed URL-encoded probes and exploit-like payloads, but could not establish whether those payloads targeted either CVE. Treat them as hunting leads, not a PHP2Shell signature.
One useful lead is a PHP error containing Allowed memory size, exhausted, and Unknown on line 0. CrowdStrike describes this pattern in its research. Search your collected error logs for these phrases, then inspect nearby requests and host activity. Benign failures can produce the same message, so a match is a starting point, not a verdict. CrowdStrike research
Record the request time, method, path, source address, backend, and request identifier where available. Compare the traffic with the application's normal request behavior. If request bodies were not retained, record that gap; access logs may not contain enough detail to reconstruct the payload.
Neither HTTP 500 nor HTTP 200 establishes the outcome. For a web application firewall (WAF) alert, check whether it blocked the incoming request before it reached the server or only blocked the outgoing response. Blocking a response cannot undo code execution at the origin.
4. Connecting the Request to What Happened Next
Use the request time, backend, and request identifier to connect proxy, PHP, and endpoint events. Follow the worker's process identity where available; nearby timestamps alone do not establish a relationship.
This illustrative timeline assumes logs expose a request identifier and worker process ID (PID), and endpoint telemetry records process relationships. All times are UTC on the same day:
On small screens, swipe the table to view all columns.
| Time | Evidence | Investigative value |
|---|---|---|
| 10:14:02 | Access log: multipart POST to /index.php, backend web-02, request r-81, HTTP 500. |
Identifies the request and the server to investigate. |
| 10:14:02 | Error log: request r-81, Apache worker PID 4120, Allowed memory size ... exhausted ... Unknown on line 0. |
Connects the request to a startup-phase memory failure and a worker. |
| 10:14:03 | Endpoint event: worker 4120 starts /bin/sh, PID 4186. |
Gives you a child process and command line to examine. |
| 10:14:04 | Endpoint events: process 4186 writes /tmp/.cache.php and opens an outbound connection. |
Gives you a file and destination to preserve and investigate. |
The evidence is stronger because the identifiers connect the events, not because the timestamps are close. In real telemetry, also check process start times or unique process identifiers: operating systems can reuse PIDs.
Compare execution with the application's baseline: image converters and maintenance tools can be legitimate children. Check command lines, service accounts, and deployment changes with the application owner before concluding that activity is malicious.
Also examine unexpected files in web or upload directories, outbound connections, and access to application secrets. Not every attack launches a shell: PHP can read data within its existing process. No suspicious child process therefore does not rule out disclosure.
If you cannot link the request to host activity, report the impact as unresolved. If the command and file analysis establish unauthorized execution, escalate the compromise, but keep the entry point provisional until the evidence supports PHP2Shell specifically. Other web vulnerabilities can produce similar behavior.
5. Responding Without Losing the Evidence
When evidence points to compromise, involve the incident lead and service owner. Restrict or remove the affected backend from service under your response runbook. Identify the exact backend behind any load balancer so containment reaches the affected workload.
Where practical, preserve relevant requests, error logs, process details, suspicious files, and current connections before restarting workers. Do not let evidence collection delay stopping active harm. Record what you changed and when so the next responder can distinguish attacker activity from response actions.
Scope the incident around what the web-service account could access. That includes application configuration, database credentials, mounted storage, and cloud identities. Investigate persistence and rotate exposed credentials from a trusted system. If you cannot establish that the workload is clean, rebuild it from a trusted source. Updating PHP closes a vulnerability; it does not remove an existing backdoor.
For remediation, install the fixed runtime or vendor backport and restart or replace the affected workers. In a container deployment, roll out the updated image and confirm that old containers are gone. Disabling session upload progress can reduce specific attack paths, but it is not a replacement for the update. Apply settings before request processing and follow PHP's current guidance.
6. What to Check Today
Use these five questions to turn the investigation into an actionable handover:
- Exposure: Which backends serve PHP, who owns them, and which running packages contain the fixes?
- Evidence: Can you connect suspicious requests to PHP errors and worker activity? Record any missing logs or identifiers.
- Impact: What execution, file access, or outbound activity is confirmed, and what remains unexplained?
- Remediation: Were all workers restarted or replaced, was the October 23 follow-up checked, and do logins and uploads still work?
- Ownership: Who is handling containment, credential rotation, and unresolved investigation tasks?
Your next step: pick one internet-facing PHP service and work through the five questions above with its owner. Record the evidence, assign unresolved actions, and set a review time. Keep the runtime is patched separate from the compromise investigation is resolved: a successful update answers the first; your evidence must answer the second.