Safeguard
Security

PHP Webshells: How Attackers Plant Them and How to Detect One

A PHP webshell is a malicious script that gives an attacker remote control of your server. Here is how they get planted, what they look like, and how to find them.

Priya Mehta
Security Analyst
6 min read

A PHP webshell is a malicious PHP script that an attacker uploads to a web server to gain remote command execution and persistent control over the host. Once it is in place, the attacker can browse files, run system commands, pivot deeper into the network, and often maintain access long after the original vulnerability is patched. This guide explains how a PHP webshell gets planted, how to recognize one, and how to hunt for and remove it, from a defender's point of view.

How a webshell ends up on your server

A webshell is the payload, not the break-in. It gets planted after an initial foothold, and the foothold usually comes from one of a handful of familiar weaknesses:

  • Unrestricted file upload. An avatar or document upload that accepts a .php file and stores it inside the webroot is the classic path. If the server will execute what lives in the upload directory, the attacker just uploads a script and requests it.
  • Vulnerable plugins and CMS components. Outdated WordPress, Joomla, or Magento extensions are a constant source of upload and code-injection bugs.
  • Local or remote file inclusion. An include statement that trusts user input can pull in attacker-controlled content and execute it.
  • Compromised credentials. FTP, SSH, or admin-panel logins that get phished or brute-forced let an attacker drop a file directly.

The common thread is that untrusted content reaches a place where the PHP interpreter will run it.

What a webshell looks like

Webshells range from sprawling admin panels with file managers and database browsers down to a single line. The dangerous part is that the minimal ones are trivially small and easy to hide. Conceptually, the entire mechanism is this: take input from the request, pass it to a function that executes code or shell commands, return the output. A defender only needs to understand the shape, not deploy it.

The functions attackers lean on are a short, well-known list: eval, assert, system, exec, shell_exec, passthru, popen, proc_open, and the backtick operator. A dynamic variable function call, where the function name itself comes from the request, is another hallmark. Modern webshells also obfuscate heavily, chaining base64_decode, gzinflate, str_rot13, and hex escapes so the payload does not read as anything human.

How to detect a PHP webshell

Detection combines file-system hunting, log analysis, and behavioral signals. No single indicator is conclusive, so stack them.

Grep for dangerous function usage. Start with the obvious call sites across your webroot:

grep -rnE "eval|assert|system|exec|shell_exec|passthru|popen|proc_open" /var/www --include="*.php"

Expect false positives; legitimate code uses some of these. The point is to build a review list, not to auto-delete.

Hunt for obfuscation. Long base64 blobs, nested decode chains, and files that are almost all one packed string are red flags:

grep -rlnE "base64_decode|gzinflate|str_rot13" /var/www --include="*.php"

Check for anomalies in the filesystem. A .php file inside an uploads or cache directory, a file with a recent modification time that does not match any deploy, or a file whose name mimics a core file (wp-conf1g.php) all deserve a look. find /var/www -name "*.php" -newermt "-7 days" surfaces recently changed scripts.

Read the web server logs. Webshells get called. Look for repeated POST requests to an unusual single file, requests with cmd= or c= style parameters, or a lone endpoint receiving traffic from a suspicious IP. Access to a file that no page links to is a strong tell.

Use file integrity monitoring. If you have a known-good baseline of your application files, any deviation is immediately visible. This is the single most reliable detection method and the reason to establish a baseline before you need it.

Prevention beats cleanup

Removing a webshell without closing the door that let it in just invites a second one. Harden the pipeline:

  1. Store uploads outside the webroot and serve them through a handler that never executes them. If uploads must live under the webroot, disable PHP execution in that directory at the web-server level.
  2. Validate uploads by content, not just extension, and rename files to server-generated names.
  3. Keep the CMS, plugins, and PHP itself patched. Most webshell incidents trace back to a known, fixed vulnerability in a component. Scanning your dependencies with an SCA tool such as Safeguard flags those outdated components before an attacker finds them.
  4. Run PHP with least privilege so a webshell cannot read files the web user has no business touching.
  5. Deploy a web application firewall to filter obvious upload and injection attempts, and pair it with runtime testing. Our DAST product page covers how dynamic scanning catches the upload and inclusion flaws that lead to webshells in the first place.

If you find one: respond, don't just delete

Treat a discovered webshell as a confirmed breach. Preserve a copy for analysis, capture logs before they rotate, and assume the attacker created additional persistence (cron jobs, extra accounts, modified core files). Rotate every credential the server had access to. Then, and only then, remove the shell and patch the entry point. A rushed delete that skips scoping the compromise usually means you will be back in a week. The fundamentals of getting ahead of these components live in the Safeguard Academy.

FAQ

What is a PHP webshell used for?

It gives an attacker remote control of a compromised web server, including running system commands, reading and modifying files, accessing databases, and using the server as a launch point for further attacks inside the network.

How do I know if my server has a webshell?

Look for PHP files in upload or cache directories, recently modified scripts that do not match a deploy, heavy base64 or gzinflate obfuscation, and web server logs showing repeated POST requests to a single unusual file. File integrity monitoring against a known-good baseline is the most reliable method.

Can antivirus detect PHP webshells?

Server-side malware scanners and dedicated webshell detection tools catch known and heavily obfuscated shells, but custom or lightly modified ones can evade signature matching. Combine scanning with log analysis and integrity monitoring.

How do webshells usually get onto a server?

Through unrestricted file uploads, vulnerable CMS plugins, file inclusion bugs, or stolen FTP/SSH/admin credentials. The webshell is planted after an initial foothold, so closing the underlying vulnerability is essential to prevent reinfection.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.