Introduction
Disclosures of breaches often include mention of a “web shell” to further attacker ends. As one example, the Clop ransomware group (also known as 'Lace Tempest,' TA505, and FIN11) has used web shells as part of their attack chains in both the Kiteworks Accellion FTA breach1 of 2020 and the plethora of breaches related to Progress Software’s MOVEit software2 in 2023.
This article will lay out what web shells are, their capabilities, the advantages and disadvantages they provide attackers, and how organizations may be able to protect themselves against this post-exploit activity3.
What Is a Web Shell?
A web shell is a file that will be parsed and executed as code by a webserver, which sends the results of back to the originator of the web request. They are written in web programming languages such as PHP, Java, Perl and others. In this sense they are the same as the legitimate programs that power the dynamic websites we use every day.
The difference is that they are designed to give their users a means of executing arbitrary commands on the webserver. They are placed on the webserver without the permission of the owners of the site. A web shell may be considered an illicit script which intentionally introduces a command injection vulnerability4 for the benefit of an attacker.
How Do Web Shells Work?
Most programming languages used on the web allow for the running of system commands and external processes via various functions, such as “system()” or “exec()”. This is not by itself a vulnerability, but if an attacker can control the parameters passed to the function, a “command injection vulnerability” occurs.
The same functions can be used in an attacker-controlled script, and in this case, the command injection is intentional. The script will present a means by which an attacker can pass arguments in and have them executed on the target host.
For example, if an attacker were to place a file with PHP code on a PHP-supporting website, a request with proper parameters could be made to execute on the target.
The following is an example web shell, written in PHP:
<!DOCTYPE html>
<html>
<head>
<title>example webshell</title>
</head>
<body>
<?php
system($_GET['cmd']);
?>
</body>
</html>
Assuming this script was placed in the web root directory of example.com, a request to “https://example.com/example_webshell.php?cmd=ls” would execute the “ls” command on the host and return results.
This will pass whatever text is sent in the “cmd” parameter to the PHP system() function, which runs the provided string as a command via a “shell” program on the server, such as “bash” or “zsh” on Linux, or “cmd.exe” on Windows.
In the example request above, the “cmd” parameter contains “ls”, a valid shell command to list the files in the current directory on the server which in this case is the contents of the web root directory.
Other commands may of course be run, which allows attackers to read files, navigate the file system, start processes, and possibly other things, all with the privilege level of the web server process.
While the above example is perhaps the most minimal web shell that the author could think of, there are quite sophisticated ones available from many sources. Kali Linux, a popular penetration testing distribution, provides fourteen different examples, written in the PHP, perl, jsp, cfm, aspx, and asp languages. A quick search of Github showed 1,808 repositories that contain the words “web shell” somewhere in their description or title. Any reasonably competent programmer in a web language would be able to code their own without too much effort.
Web Shell Capabilities
Of the 14 web shells packaged with Kali Linux, which we can take as a somewhat representative example, the following capabilities were present.
- Command execution on both Windows and Linux platforms
- File upload
- File download
- Archive creation and download
- Database query execution
- Database table dumping
- Executing code to create a network connection back to an attacker-controlled machine (a “reverse shell”)
This list, however, is by no means comprehensive. An attacker with knowledge of the target system and a specific agenda would likely customize their web shell towards those ends, with their capabilities limited only by their skill, the commands available to them on the target, and the permissions of the web server process.
Attacker Advantages and Disadvantages
Why would an attacker use a web shell? First and foremost, not every vulnerability is a one-shot, Remote Code Execution (RCE) vulnerability. Frequently, a successful attack involves leveraging several vulnerabilities to achieve the desired outcome.
In the case of web shells, they are frequently used to go from a Local File Inclusion (LFI) vulnerability to having the ability to run commands on the system. From there, depending on attacker objectives, further reconnaissance can be done, or further exploits deployed to elevate privileges, pivot, and maintain persistence.
Additionally, web shell traffic appears to be legitimate website traffic; a client requests a URL, and a response is returned. Further, as most sites now run HTTPS/TLS, this traffic is also encrypted. Finally, HTTP is by far the most used protocol, and any site with a lot of traffic will have many thousands of requests per second that would need to be inspected to detect malicious activity. These facts, taken together, mean that unless a defender is carefully inspecting the URL requested, the contents of the request and response, and the presence of malicious files in their web application directories, there’s a good chance attacker activity will go unnoticed.
Finally, a capable web shell can be constructed from the many examples available by attackers with limited skills, and can be just as effective as more difficult, high-end techniques like custom shellcode and sophisticated malware.
The disadvantages are few, but not to be discounted entirely. Antivirus and IDS vendors do inspect traffic and files and have signatures that can match commonly encountered web shells. It is relatively easy to detect if new files have been placed in web directories. Even so, with a modicumof effort, web shells can be changed and obfuscated to avoid signature-based detection, and in many cases, web directory changes are monitored for only periodically, giving the attacker a window of opportunity before detection occurs.
Detection and Defenses
As we have already mentioned above, the main line of defense is detecting suspicious web traffic, URL parameters, and suspicious URLs. Directory content monitoring is also a good approach, and some programs exist which can detect changes to monitored directories immediately and roll back changes automatically.
Additionally, some defensive tools allow for the detection of anomalous process creation.; In this case, the invocation of a shell by a webserver would be caught and alerted on. More sophisticated approaches involve the explicit allow-listing of subprocesses and blocking of any that don’t match that list. These approaches are an excellent solution if, for some reason, your webserver needs to spawn subprocesses. However, it should be noted that for a skilled programmer in a web language, there’s very little that can’t be accomplished using the language’s common features, without having to execute system commands.
Conclusion
Despite their simplicity, web shells are a common way for attackers to gain the ability to run commands on a server and avoid detection by hiding in the “noise” of normal web traffic. They are very customizable and flexible tools requiring modest technical skills. For a targeted organization, they can be devastating, leading to data exfiltration, installation of malware, and further reconnaissance of their environment by attackers.
We recommend that companies running dynamic websites use all the tools at their disposal to detect and mitigate web shells, paying special attention to the contents of storage accessible by their webservers. Secure coding practices which aim to eliminate an attacker’s ability to upload malicious content are an absolute requirement, addressing as they do the most common means by which attackers install web shells in the first place. In-depth monitoring of webserver process creation, as well as requested URLs and parameters, and even the content delivered by the webserver to client, are all excellent methods of detection.