.jpg)
Web Shell Detection and Investigation
A web shell is one of the few intrusion artifacts most SOCs can already see. The events that expose one, a web server worker starting a command interpreter or a new script file appearing in a directory the server executes from, are collected by default in most Windows environments and by any mainstream EDR. Visibility is rarely what blocks these cases.
What blocks them is volume of a specific kind. Deployment pipelines and administrative tooling produce those same two events every week, and separating one from the other takes provenance and request history that is not included with the alert. So investigating it properly means gathering that context from four different systems, every time. That’s why a real web shell can survive even when a detection rule fired correctly, and if your alert triage queue already runs hot, the investigation bottleneck can easily hide a real threat in the noise.
What this means is that a web shell is easy to detect and hard to confirm.
What a Web Shell Is and Why Attackers Still Rely on Them
A web shell is a script placed on a compromised web server that gives an attacker command execution through ordinary HTTP requests. MITRE ATT&CK catalogs the technique as T1505.003, Server Software Component: Web Shell. China Chopper is the archetype, a server-side component that fits in a single line of ASPX or PHP and has anchored intrusions for more than a decade and still appears in current incident reporting.
The technique persists because the economics favor the attacker on every axis. A web shell runs inside a legitimate process, the web server itself, so process-level allowlisting rarely objects. Its traffic is inbound HTTPS to a server whose job is receiving such requests, so beacon-hunting network detections have nothing to find. A file-based web shell survives reboots and credential resets. For an attacker holding unauthenticated remote code execution, a web shell converts a single exploit into persistent access, which is why it's often part of serious compromises of internet-facing applications. Prophet AI tracks the chains that end this way in its emerging threat research.
{{ebook-cta}}
The Exploit Classes That End in a Web Shell
The pattern repeats across vendors and years, and reading four cases together is more useful for identifying patterns and more resilient detection opportunities.
- Microsoft Exchange, ProxyShell (2021). CVE-2021-34473, CVE-2021-34523, and CVE-2021-31207, exploited in the wild from August 2021 and added to CISA's Known Exploited Vulnerabilities catalog on November 3, 2021, the day the catalog launched. Mandiant documented China Chopper and Godzilla-derived shells written into *inetpub\wwwroot\aspnet_client*, followed by credential theft with Mimikatz, extraction of NTDS.dit and the SYSTEM hive, and tunneling tools for onward access.
- Atlassian Confluence (2022). CVE-2022-26134, an OGNL injection, added to KEV on June 2, 2022. Volexity found the BEHINDER in-memory shell alongside China Chopper and a custom uploader at confluence/noop.jsp, then attempts to alter web access logs so the requests that installed them would not be recoverable.
- Progress MOVEit Transfer (2023). CVE-2023-34362, exploited as a zero-day before the May 31 patch and added to KEV on June 2, 2023. CISA and the FBI documented LEMURLOOT deployed as human2.aspx, named to sit beside the legitimate human.aspx, and used to enumerate the database, retrieve Azure Blob Storage credentials, create and delete administrative accounts, and exfiltrate files.
- Ivanti Connect Secure (2024). CVE-2023-46805 chained with CVE-2024-21887, both added to KEV on January 10, 2024, the day of disclosure. Volexity documented GLASSTOKEN web shells plus modified Perl and CGI components, including a modified JavaScript file on the login page that harvested credentials, and changes to the appliance's own Integrity Checker Tool so periodic scans would not flag the tampering.
Two things generalize. The initial vulnerability may differ, but the post-exploitation artifact does not, which is why detection effort spent on the web shell outlives patching cycles. And deploying the shell is rarely the objective. In three of the four cases above the attacker used it to reach credentials or key material, which means removing the file is not the same as containing the breach.
How to Detect Web Shells: The Telemetry That Gives Them Away
Most environments already collect what this requires, so web shell detection is usually a configuration and rule-writing exercise rather than setting up new data sources or detection tools. There are four useful signals, and correlating across them identifies a shell.
- Process lineage. A web server worker spawning a command interpreter is the highest-fidelity signal available: w3wp.exe or httpd launching cmd.exe, powershell.exe, or /bin/sh. Web workers render pages and have no routine reason to start shells. The signal is high precision, but not high recall: a shell that executes .NET or PHP code in-process never spawns a child, so an empty process tree does not clear a host.
- File writes to web-served paths. A new .aspx, .ashx, .jsp, or .php file appearing in a served path, written by the web process itself or by an account with no history of writing there.
- Web log anomalies. POST-heavy traffic to a URI with no browsing history, requests carrying no referer, rare user agents, and a first-seen resource that immediately starts receiving parameters. These signals may appear sometimes in isolation in normal traffic; but all four together, linked to the same URI do not.
- Configuration and secret access. Reads of web.config, MachineKey material, connection strings, or credential files shortly after a file write to a served directory. This is the step that expands the breach beyond a single compromised host.
The event sources are ordinary. On Windows systems, process creation with command lines comes from Sysmon Event ID 1 or Windows Event 4688 with command-line auditing enabled, and from any mainstream EDR. File creation in served paths comes from Sysmon Event ID 11 or object-access auditing scoped to the webroot. IIS and reverse-proxy logs cover the request side, and they are often the only record old enough to establish when a URI first appeared, so their retention window constrains the investigation more than most teams expect. Ninety days of process telemetry against thirty days of web logs means the question that decides the case cannot be answered.
Organizations with limited investigation resources try to encode the sequence rather than the individual events: a write, then requests to the written file, then child processes, then configuration reads. But this is a common Detection engineering mistake. Although legitimate activity almost never reproduces that order end to end, reducing false positives, attack behavior is hardly predictable to that level, so small variations in the attacker methods can make these overly tuned detections miss the real threat, becoming a risky false negative case.
Why Web Shell Detections Produce So Many False Positives
A release pipeline writes new .aspx files into a served directory. An administrative script spawns a shell from a web context. A monitoring agent reads web.config on a schedule. A rule written on any one of those behaviors fires on all of it. The resulting noise is an accurate description of how web servers are operated, which is why tuning alone never removes it.
That leaves teams with a detection that produces many false positives, but occasionally the only warning they will get. The common responses, in addition to the aggressive tuning mentioned above, are to lower its severity, route it to a queue nobody works on, or close its alerts on pattern recognition. The third one is how a real shell gets missed by an analyst who has correctly closed forty benign versions of the same alert. Deliberate alert tuning, with documented suppression logic and avoiding excessive sequence prediction, is defensible. The habit of closing what looks familiar is where alert fatigue turns into missed intrusions, and it leaves no record anyone can audit afterward. Even if not ideal, detections with high recall but with limited precision are necessary to detect behavior in a less prescriptive manner that will not fall to false positives. The key to work with such detections is to increase the investigation throughput, so all the alerts, including the expected false positives, can be properly investigated in reasonable time and without relying on human eyes for every small detail.
Investigating a Suspected Web Shell Alert
When one of those signals fires, the questions have a natural order, and running them in order is what separates a defensible determination from a guess.
Start with provenance. Which process wrote the file, under which account, at what time, and what request arrived immediately before the write. IIS logs, file-creation events, and process telemetry answer this together. The answer resolves most benign cases quickly: a file written by the deployment service account at a time matching a change record, with no later requests from outside the estate, is explainable in minutes.
Then establish request history. Every request to that URI since it was created, the source addresses, the methods, and whether any request predates your earliest known exploitation date for the relevant vulnerability. This is where log retention decides the outcome.
Then execution. What child processes the worker spawned, what commands ran, what those commands touched. The same evidence discipline you would apply to EDR alerts applies here, with the web request as the additional pivot.
Then scoping, which matters most and gets skipped most often. What credentials could the application pool identity reach. Whether MachineKey or other secret material was read. Whether other servers show the same write pattern or the same request pattern.
Document each question, the query that answered it, and the evidence, in that order.
When the Answer Is Inconclusive
Not every suspected shell resolves cleanly. Consider a file with no matching change record, written by an account that should not have written it, on a host whose web logs rolled over two weeks ago. It cannot honestly be called benign, and calling it malicious without evidence is a different kind of failure.
The defensible output is an inconclusive determination with a containment decision attached, rather than a benign close reached by exhaustion. Time-box the open questions. Isolate the host or restrict the suspect URI while they close. Record which evidence was unavailable and why, because that record is what tells you to extend log retention before the next one. A determination someone else can re-derive from its evidence trail holds up months later in front of an insurer or a regulator. A fast close does not.
Hunting for Web Shells When No Alert Fired
Patching closes the obvious doors for the next attacker, but says nothing about whether someone walked through them earlier. For any vulnerability with an exploitation window that opened before you patched, a retrospective sweep is part of remediation rather than an optional follow-up. This is hunting in the by-exclusion mode: assume compromise, then try to prove absence.
The hypothesis is concrete. Enumerate every script file in web-served directories across the fleet and diff against known-good deployment manifests, then run provenance analysis on anything unexplained. Sweep web logs for published indicators, for POSTs to the vulnerable endpoint, and for requests to any first-seen script resource inside the exposure window. Check for secret-material access events and for changes to scheduled tasks, service accounts, or Group Policy in the same period.
Writing that hypothesis takes a sentence. Two costs follow it, and they are what stalls hunting programs. The first is translation: expressing one hypothesis as working queries against web server logs, EDR process telemetry, file-creation events, and directory-service audit data, each with its own query language, field names, and retention window. The second is disposition: a fleet-wide sweep of served directories returns hits, most of them explainable, and every one costs an analyst the same provenance work described above. Those two costs are what to weigh when evaluating threat hunting tools, because a tool that only helps you ask the question leaves the expensive half on your team.
Web shells recur, so a one-time sweep is worth converting into a scheduled hunt. Threat hunting with AI changes the cost of asking the same disciplined questions on a cadence and of clearing the benign hits they return. For most mid-sized environments, a quarterly fleet-wide sweep of served directories, tightened while a campaign against software you run is active, is a defensible starting rhythm.
Containment and Hardening After a Confirmed Web Shell
Removal is the smallest step. Rotate whatever the shell could read, such as MachineKey values on every server, and rotate any credentials the application pool identity could reach. Audit the intrusion window for persistence created through other means: scheduled tasks, new service accounts, modified Group Policy Objects, and altered access logs, since log tampering appeared in the Confluence case above.
Then reduce the next attacker's room. Restrict write permissions on served directories wherever the application tolerates it, alert on script-file creation in those paths as a standing detection, and accept that keeping it will require the investigation discipline described here. A detection you keep and work is worth more than a stricter one you turn off in six weeks.
The ToolShell Chain as a Worked Example
ToolShell cases exploiting CVE-2026-58644 in on-premises SharePoint Server follows the pattern closely enough to be useful as a reference. An unauthenticated request to the ToolPane endpoint triggers deserialization of untrusted data and yields code execution as the SharePoint application pool identity. A web shell named spinstall0.aspx is written to the LAYOUTS directory. The shell then reads ASP.NET MachineKey material from web.config, which lets an attacker forge valid payloads against any server in the farm without touching the original file again.
That third stage is why the containment advice above insists on key rotation. An investigation that finds and removes spinstall0.aspx, and stops there, has closed one file and left the farm reachable. The full anatomy, the published indicators, and the retrospective hunt for that specific chain are covered in the SharePoint zero-day writeup.
The next case will involve a different vulnerability. The web shell and the investigation steps described above will be the same. If a retrospective sweep of your own servers is on the list, see how Prophet AI Threat Hunter runs it.
Insights
Prophet Security Quarterly Threat Report
The attack patterns seen most across customer environments, and why some of those attacks succeeded where others were blocked.



