Remote code execution (RCE)
What is remote code execution?
Remote code execution (RCE) is a vulnerability that lets a malicious hacker execute arbitrary code in the programming language in which the developer wrote that application. The term remote means that the attacker can do that from a location different than the system running the application. Remote code execution is also known as code injection and remote code evaluation.
|Scope:||may appear in all computer software|
|Technical impact:||command shell access|
|Worst-case consequences:||full system compromise|
|Quick fix:||do not evaluate code based on user input|
How does code injection/remote code execution work?
RCE vulnerabilities may appear in any type of computer software, in almost every programming language, and on any platform. There are RCE vulnerabilities, for example, in standalone Windows applications written in C#, web applications and APIs written in PHP, mobile applications written in Java, and even in operating systems themselves.
Other vulnerabilities may lead to remote arbitrary code execution. For example, buffer overflow vulnerabilities in languages such as C/C++ may allow the attacker to execute arbitrary code within the application. Deserialization vulnerabilities may also allow attackers to provide a payload that, when deserialized, includes code that the application executes. There are even known cases of SQL injection and cross-site scripting (XSS) vulnerabilities leading to remote code execution in a vulnerable application.
Some RCE attacks may happen after a delay. For example, the application may first store the RCE payload in a configuration file and only execute it later, maybe even multiple times. This type of RCE vulnerability is called a stored RCE.
Note that RCE/code injection is often confused with OS command injection. In the case of RCE, executed code is in the language of the application and runs within the application context. For OS command injection, the attacker executes an operating system command. Also, note that while the term code injection is preferred by OWASP and defined in CWE-94, the term remote code execution is much more widespread.
RCE vulnerabilities in web applications
If the developer allows a function such as eval to process unsanitized user input, a malicious attacker may be able to inject code by including it in user input. Examples of user-controllable inputs include text from web forms, the content of HTTP headers, files uploaded by the user, or even modified cookies.
Example of a web remote code execution attack
Below is a simple example of PHP source code with code injection vulnerabilities (RCE) and a code injection attack vector on applications that include this code.
<?php eval("echo ".$_GET["user"].";"); ?>
The developer assumes that the user will only provide a valid user name as the parameter of a URL:
As a result, the application evaluates the parameter value as code:
and prints out the name of the user.
The attack vector
The attacker may inject malicious code by entering a semicolon followed by the payload. The semicolon makes the eval function process the remainder of the payload as if it was a new instruction in PHP:
As a result, the eval function executes the code:
Potential consequences of a web RCE attack
Remote code execution is one of the highest severity vulnerabilities because RCE cyberattack consequences are virtually unlimited, especially in the case of web applications.
The most common way that attackers follow up on exploiting web RCE vulnerabilities is by installing web shells. Such an RCE exploit payload includes code that allows the attacker to obtain shell access on the target machine in order to run system commands. The shell may be a reverse shell, which allows the attacker to avoid most firewalls.
The web shell has the same privileges as the web server, which are usually limited. However, once the attacker has access to the shell on the remote machine, they may try to find other vulnerabilities and use privilege escalation (privilege elevation) to obtain root access.
If successful, the attacker will have unlimited access to the target machine and may follow up with any of the following common types of attacks:
- Ransomware or other malware: The attacker may install a ransomware agent on the machine, which will then use other methods to spread to other assets owned by the victim.
- Cryptocurrency mining: Attackers often install cryptocurrency miners on compromised machines. Mining consumes your computing resources to provide cybercriminals with funding for more malicious activities.
- Sensitive data theft: The attacker may use privilege escalation to access SQL database servers containing sensitive data such as credit card numbers.
Examples of known RCE vulnerabilities
- CVE-2021-44228 (Log4Shell) in Apache Log4j 2.x (followed up by CVE-2021-45046 and a CVE-2021-45105 denial of service vulnerability) is an example of an RCE in a non-web application. This Log4j vulnerability, which does not require the attacker to have any authentication, affects multiple Log4j versions and resides specifically in the JndiLookup class of this popular open-source logging library. Many popular apps and services were initially found to be vulnerable to it, including Steam, Apple iCloud, Minecraft, and more.
- CVE-2021-1844 in Apple iOS, macOS, watchOS, and Safari is another example of an RCE in an operating system module. If a victim uses a vulnerable device to visit a URL controlled by the attacker, the operating system will execute a malicious payload on that device.
- CVE-2020-17051 in Microsoft Windows NFSv3 is an example of an RCE in an operating system module. An attacker may connect to a vulnerable NFS server and send a payload that the target endpoint will then execute.
- CVE-2019-8942 in WordPress 5.0.0 is an example of an RCE in a popular web application. An attacker can execute arbitrary code within WordPress by uploading a specially crafted image file that contains PHP code in its Exif metadata.
How to detect RCE vulnerabilities?
The best way to detect RCE vulnerabilities depends on whether they are already known or unknown.
- If you only use commercial or open-source software and do not develop software of your own, it may be enough to identify the exact version of the system or application you are using. If the identified version is susceptible to RCE, you can assume that your software is vulnerable. You can identify the version manually or use a suitable security tool, such as a software composition analysis (SCA) solution for web applications or a network scanner for networked systems and applications.
- If you develop your own software or want the ability to potentially find previously unknown RCE vulnerabilities (zero-days) in known applications, you must be able to successfully exploit the RCE vulnerability to be certain that it exists. This requires either performing manual penetration testing with the help of security researchers or using a vulnerability scanner tool that can automatically exploit web vulnerabilities. Examples of such tools are Invicti and Acunetix by Invicti. We recommend using this method even for known vulnerabilities.
How to prevent RCE vulnerabilities in web applications?
If you must use the eval function with untrusted data (direct or indirect user input) and there is no way to achieve your application goal without evaluating user input, you must accept the risk that your code will be susceptible to remote code execution attacks. Even with the best input sanitization, attackers might always find a way to get through.
While you cannot fully avoid RCE vulnerabilities in such cases, you can minimize the risk of attacks and mitigate their consequences by using proper input/output data validation and sanitization based on whitelists (not blacklists).
How to mitigate RCE attacks?
Possible methods to mitigate RCE attacks will vary depending on the type of vulnerable software:
- In the case of custom software, such as web applications, the only way to permanently mitigate the RCE is to eliminate evaluation functions that process user-controlled input from your application code.
- In the case of known RCEs in third-party software, you must check the latest security advisories for a fix and update to a non-vulnerable version (usually the latest version).
- In the case of zero-day RCEs in third-party software, you can only rely on temporary WAF (web application firewall) rules for mitigation. However, this only makes the RCE harder to exploit and does not eliminate the root cause of the problem.
Frequently asked questions
What is a remote code execution vulnerability?
Remote code execution (RCE) vulnerabilities in web applications let the attacker execute arbitrary code on the web server hosting the web application. A good example of remote code execution is Log4Shell, an RCE vulnerability in Apache Log4j.
How dangerous is an RCE vulnerability?
Successful exploitation of an RCE vulnerability in a web application can let the attacker execute any code and execute commands on the web server. The attacker can, for example, exploit an RCE vulnerability to install a web shell on the web server and continue the attack from there.
How to detect remote code execution vulnerabilities?
Dynamic application security testing (DAST) tools are the best way to detect remote code execution vulnerabilities in web applications. They provide the best coverage and some of them, like Invicti, are able to prove that the vulnerability is real and not a false positive.