It is quite rare for a modern web application with an active user base to not have a file upload function. The ability for users to upload files to a web server has become an integral part of interacting with web applications, whether that is uploading a profile picture, submitting a resume to a job board website, or providing identification documents for a background check. There are many use-cases for the file upload feature and a significant number of different file types that users can upload to a web server. However, a web application with weak file upload protections may introduce severe vulnerabilities to the web server, namely Remote Code Execution (RCE). For instance, file uploads designed without the proper safeguards may permit an attacker to upload a web shell, resulting in a complete compromise of the application and its related systems.
What is a Web Shell?
A web shell is a malicious segment of code written in common back-end programming languages that attackers upload to a web server to provide a shell-like interface that grants remote access and code execution on the underlying host. Web shells are becoming increasingly popular due to how easily they can be obtained and how effective they are for cybercriminals. In fact, there are a number of publicly available web shells written in different programming languages that anyone can download and use to attack your web application. According to Microsoft’s Detection and Response Team, there has been a steady increase in the use of web shells in attacks worldwide, with the latest Microsoft 365 Defender data showing an acceleration of its use every month from August 2020 to January 2021. On average, 140,000 instances of this attack vector were registered on servers, doubling the 77,000 monthly average seen in 2020.
What is Remote Code Execution?
Remote Code Execution, also known as Arbitrary Code Execution, is one of the most dangerous web application vulnerabilities. This type of vulnerability allows a threat actor to execute commands with system-level privileges or the low privileges of the www-data user via a web shell. In most cases, the attack vector for RCE involves uploading a file that the webserver can interpret and execute as code on the back-end, which is highly probable if the file extension is .php or .asp. In general, file types stored on a file system cannot be executed unless they have been granted executable permissions. However, some operating systems often treat programs with PHP file extensions as automatically executable and will run them without executable permissions. This behaviour is especially true for web servers that run on Unix operating systems, where PHP programs can be executed without setting the execute bit.
Impact and Risk
After a successful web shell upload, an attacker now has a permanent backdoor into the compromised computer running the webserver and access to any information stored on it. Furthermore, this initial foothold can be used as a persistent access point for lateral movement across the organization’s network, collecting credentials and other sensitive data in the process. Even more troubling is that the absence of malware detection may allow an uploaded web shell to remain undetected, giving adversaries the ability to exfiltrate data over a significant period of time. According to CISA, the consistent use of web shells by Advanced Persistent Threat (APT) and criminal groups has led to many cyber incidents.
Web applications with insecure file upload functionalities provide an attack surface for bad actors to upload web shells that can cause considerable impact and often go undetected. Therefore, it is critical to implement robust and effective measures to prevent attackers from bypassing the defence mechanisms that are supposed to protect your file upload system.
The following security controls are recommended to defend your application from web shell attacks:
File type restriction and malware detection – Restrict uploading of file types based on business requirements; only permit necessary file types to be uploaded. In addition to restricting file types, the files uploaded by end-users should only be stored in directories scanned by antivirus and have code execution disabled.
Employ both client and server-side validation – Implementing client-side validation ensures that application users can only upload permitted file types (e.g., .jpeg). However, an attacker can bypass client-side validation by changing the filename extension of a PHP file to JPEG and masquerade it as an innocuous image file when it is indeed a web shell. Fortunately, this attack will fail if server-side validation is enabled and has more rigorous checks to verify that the file is allowed and does not contain malicious code.
Create random file name– Ensure the uploaded files are not stored where users can directly access them by creating an unpredictable filename. For example, use the MD5 algorithm to generate a hash of the filename plus the upload time.