Skip to content

How web shells get planted: vulnerability classes

A conceptual map of the vulnerability classes that let attackers drop web shells — file uploads, RCE, file-write primitives, stolen admin access and more — with the defensive control for each.

Published on 8 min read

A web shell is a consequence. Before an attacker can place one, they need a way to get attacker-controlled content into a location the server will execute. This guide maps those routes at a conceptual level so you can prioritise controls and know where to look first during an investigation. It deliberately contains no exploit code.

The two preconditions

Every web shell deployment satisfies two conditions:

  1. Write — the attacker can create or modify a file (or register a module, or inject code into memory) on the server.
  2. Execute — the server will interpret that content as code when it is requested.

Defensive design is largely about breaking one of the two. If uploads land in a directory where scripts never execute, a write primitive alone is not enough. If the application runs from a read-only file system, an execution bug cannot easily persist as a file.

Vulnerability classes at a glance

ClassWhat goes wrong (conceptually)Primary control
Unrestricted file uploadApplication accepts a file with an executable extension or content and stores it under the webrootAllow-list types, store outside webroot, no-exec upload dirs
Remote code execution (RCE)Input reaches an interpreter, deserializer or command runnerPatching, input validation, safe deserialization, WAF virtual patching
Arbitrary file write / path traversalAttacker controls a path used for writing (export, log, archive extraction)Canonicalise paths, restrict write locations, least-privilege FS permissions
Server-side template injectionUser input is rendered as a template and evaluatedNever render user input as template source; sandbox engines
Authentication bypass in admin featuresAn admin endpoint that installs plugins, themes or edits files becomes reachable without authPatching, restrict admin interfaces to management networks
Stolen or weak admin credentialsLegitimate CMS or panel features (plugin upload, theme editor) are used as intended by an intruderMFA, disable in-app file editors, credential hygiene
Misconfigured HTTP methods / WebDAVPUT or WebDAV writes are allowed on executable pathsDisable WebDAV and PUT unless required; separate storage
Supply chainA compromised plugin, package or update ships the backdoorVendor vetting, integrity verification, dependency pinning
Chained edge-device bugsAuth bypass plus command injection in VPNs, gateways, file-transfer serversRapid patching, exposure reduction, integrity checking tools from vendor

Unrestricted file upload

This is the textbook case. An application offers an upload feature — avatars, attachments, résumé submissions — and fails to ensure the stored file cannot be executed. Typical weaknesses, described conceptually:

  • Deny-list filtering that blocks .php but not alternative extensions the server also maps to the interpreter (e.g. .phtml, .php5, .phar on some PHP setups, or .ashx/.asmx alongside .aspx on IIS).
  • Trusting client-supplied metadata such as the Content-Type header or a file name, rather than validating on the server.
  • Double extensions and parser discrepancies, where the application's validation and the web server's handler mapping disagree about what the "real" extension is.
  • Storing uploads inside the webroot under a predictable path, with the original file name preserved.
  • Archive extraction ("zip slip") where entries with ../ path components are written outside the intended folder.

The durable fix is architectural rather than a better filter: store uploads outside the webroot or in object storage, serve them through a handler that sets a safe Content-Type and Content-Disposition, rename files to random identifiers, and configure upload directories so the web server never executes scripts there. The hardening guide includes server configuration for nginx, Apache and IIS.

Remote code execution in the application or framework

When an attacker can execute code, writing a web shell is a one-step follow-up that converts a transient exploit into durable access. RCE classes that have repeatedly led to web shell deployment include:

  • Insecure deserialization — attacker-controlled serialized objects in Java, .NET (ViewState, BinaryFormatter) or PHP trigger gadget chains. .NET ViewState abuse becomes possible when the server's machine keys are leaked, which is why the 2025 SharePoint "ToolShell" campaign focused on stealing them.
  • Expression-language and OGNL injection in Java frameworks — the class behind the 2017 Apache Struts vulnerability exploited in the Equifax breach.
  • Command injection where input is concatenated into a shell command.
  • Server-side request forgery (SSRF) chained with internal APIs — the pattern behind the 2021 Exchange ProxyLogon and ProxyShell chains.

Patching is the primary control. Because exploitation of newly disclosed bugs in internet-facing products often begins within days, treat edge-facing CVEs listed in CISA's Known Exploited Vulnerabilities catalogue as emergency changes, and assume compromise if a server was exposed and unpatched during a known exploitation window.

Arbitrary file write and path traversal

Some vulnerabilities do not give code execution directly but let an attacker control where data is written. Conceptually:

  • An export or backup feature writes a file whose path or name is attacker-influenced. ProxyShell used exactly this: a mailbox export was directed to a path under the IIS webroot with an .aspx extension.
  • A logging feature writes attacker-controlled strings into a file that is later included or executed ("log poisoning").
  • A path traversal in an upload or extraction routine escapes the intended directory.

Controls: canonicalise and validate every file path against an allow-listed base directory, run the application under an identity that cannot write to its own code directories, and monitor those directories for change.

Abuse of legitimate admin features

Many CMS and hosting platforms let administrators install plugins, upload themes or edit template files from the browser. With a stolen admin password — from phishing, credential stuffing or reuse — an intruder needs no vulnerability at all. The resulting file is created by the application itself, so it looks "legitimate" in file-system telemetry.

Controls:

Platform featureHardening
In-browser theme/plugin file editorDisable it (for example, WordPress supports DISALLOW_FILE_EDIT and DISALLOW_FILE_MODS in wp-config.php)
Plugin/extension installationRestrict to a deployment pipeline; make code directories read-only at runtime
Admin loginEnforce MFA, restrict by network, rate-limit and alert on new admin sessions
Admin accountsReview regularly; alert on newly created administrators

Misconfigured HTTP methods and WebDAV

If WebDAV authoring or the HTTP PUT method is enabled on a path that also executes scripts, an attacker can simply upload a file. This is less common on modern stacks but still appears on legacy IIS and Tomcat deployments (Tomcat's readonly default servlet parameter exists precisely to prevent it). Audit enabled methods and remove authoring modules you do not use.

Edge appliances and file-transfer products

A recurring theme since 2021 is exploitation of appliances and managed products with web front ends: VPN gateways, application delivery controllers, managed file-transfer servers and collaboration suites. Publicly reported examples include Citrix NetScaler (CVE-2023-3519), Progress MOVEit Transfer (CVE-2023-34362) and Ivanti Connect Secure (CVE-2023-46805 chained with CVE-2024-21887), all of which saw web shells or web-based implants deployed. These systems:

  • are exposed to the internet by design;
  • often do not support third-party EDR agents;
  • may run a vendor-controlled OS where defenders have limited visibility.

Controls are therefore procedural: minimise exposure of management interfaces, subscribe to vendor advisories, apply mitigations immediately, and run vendor-provided integrity checking tools after any critical advisory — then assume compromise and investigate if the device was exposed during the exploitation window.

Supply chain and deployment pipeline

A web shell can arrive through a trusted channel: a backdoored plugin from a compromised developer account, a tampered package, or a CI/CD pipeline with weak access control. Here the "vulnerability" is trust. Controls include pinning and verifying dependencies, reviewing third-party plugins before installation, restricting who can publish to production, and comparing deployed code against the repository.

Prioritising controls

If you can only do a few things, these break the largest number of routes:

  1. Patch internet-facing software fast, with emergency handling for known-exploited CVEs.
  2. Make code directories read-only to the runtime identity; deploy only through a pipeline.
  3. Never execute from upload directories, and preferably keep uploads out of the webroot entirely.
  4. Protect admin interfaces with MFA and network restrictions.
  5. Monitor for new executable files in web-served paths — covered in file integrity detection.

Using this map during an investigation

When you find a web shell, the vulnerability class often determines where evidence of initial access lives:

Suspected routeWhere to look first
File uploadApplication upload logs; web logs for the upload endpoint just before the shell's creation time
RCE / deserializationWeb logs for unusual requests to the vulnerable endpoint; application error logs; process creation by the worker around creation time
Arbitrary file writeLogs of the export/backup feature; the process that wrote the file
Admin abuseAuthentication logs for admin logins; CMS audit logs
Edge applianceVendor integrity-check output; appliance logs forwarded to your SIEM

The forensic investigation guide walks through that pivot in detail.

Related guides