“RCE” Primer: Remote Code Execution
Research / Posted March 23, 2021
Introduction / Background
Internet-enabled applications such as web application (HTTP) servers, domain name (DNS) and email (SMTP) servers operate on the basis of a client-server model in which clients (typically customers and other end users) send requests for content, data or information to servers, via a locally installed agent (e.g. a web browser in the case of web applications). The requested content resides in storage as data on deployed servers (either physical or virtual) that are located in data centres, colocation facilities, server rooms/server farms and public cloud infrastructure.
In order to serve responses to clients, some minimal amount of processing and calculation is needed on the server’s part to process the request to perform actions such as process metadata contained in the request, and to make logic-based decisions on what data to include in the response, or to check access to the resource requested. Webservers, email servers and other network-accessible servers used in modern e-commerce are therefore not “dumb” storage devices, but typically highly performant and complex computing devices that house a significant amount of code devoted to handling and processing requests from clients or peer server devices. This code is layered as in any computer on top of a “stack” of software and hardware in layers from the application down to the operating system and finally hardware.
Since all computer code is essentially processed by the server’s processing architecture (CPU) as a string of 1s and 0s, there is (by default) no distinction at the lowest level between “code” and “data” unless specific protection measures are applied.
Remote Code Execution (RCE)
Remote code execution (RCE) is the term used to describe the execution of arbitrary code on a system where the attacker does not have direct access to the console. Any vulnerability that allows an attacker to execute code or commands on remote systems where this was not intended can be said to result in RCE. However typically it is possible to send data to a server in such a way that the server becomes confused on the boundary between (untrusted and user-derived) data that it has been sent in a request and the (trusted and deployed on the server) code that it executes to handle requests – effectively a remote user is able to send (usually malicious) code to the server that is then natively executed on that server in a trusted environment as if it had been deployed to the server by its owner from a trusted source.
Remote or arbitrary code execution relies at an architectural level on the ability to specify control over an item known as the instruction address register, instruction pointer or program counter of a running process. The instruction pointer points to the next instruction in the process that will be executed. Being able to inject data into the contents of the instruction pointer therefore gives control over which instruction is executed next. In order to execute arbitrary code, RCE exploits inject code that changes the instruction pointer to have it point to the injected code rather than the next instruction in memory. The injected code will then automatically get executed.
Data Execution Prevention (DEP) exists to try and enforce a distinction between code and data at the operating system level – which can be effective for some RCE types in compiled languages – but is completely ineffective for vulnerabilities such as deserialisation (described in detail later in this article) in interpreted languages.
Remote Code Execution Example
When a webserver receives a request from a client, code is executed to handle the request using the data contained in the request as parameters that influence the response that is sent. For example, in the case of a web request, in requesting the URL http://www.example.com?user=1&page=7 a parameter of “1” has been passed in for the userID which is used as part of an operating system command. If instead of a simple “1” (data – in this case an integer) a remote user is instead able to send in a parameter that breaks out of the intended context and influence the command executed by the server, then remote code execution has occurred.
For example injecting “meta” characters (such as backslashes (\), ampersands (&), dollar ($), back ticks (`), and semi-colons(;)) in the parameter which will be embedded without sanitisation in an operating system command can allow us to execute our own commands.
The above is just one very specific example, but RCE can exist within any server technologies where client requests are submitted by end users – web servers, email (SMTP, POP3, and IMAP) servers, file transfer servers, DNS servers, NTP servers, and many more.
Other variants are described down in this article under the “Attack Vectors and Variants” section
Impact of Remote Code Execution
Remote Code Execution has the ability to impact all three key security concerns relating to an operating webserver:
- Data Confidentiality – the remote user could instruct the server to execute code to retrieve any data it contains (even if the user would not typically be able to access that data) such as other user’s sensitive data;
- Data Integrity – the remote user could instruct the server to modify data records that they should not be able to (for example rewrite their bank balance); and
- System & Data Availability – the remote user could simply send a command for the server to execute that simply wipes all its data, or shuts the server down (if combined with a privilege escalation vulnerability, typically).
In addition to these three immediate concerns, a malicious attacker who gains remote access to a server in this way can convert an immediate breach into an ongoing security concern in which a remote attacker, rather than performing an immediately malicious action to cause immediate or opportunistic harm or damage that reveals their presence, instead chooses to use the access gained to remain undetected for an extended period, while leveraging the access to gain more serious long-term access. This is the approach often favoured by an Advanced Persistent Threat (APT). This typically involves installing a backdoor for ongoing access even in the case that the vulnerability allowing initial access (for example RCE) is fixed, as well as using the compromised server to perform onward attacks known as pivot (or lateral) attacks to other servers. They may also seek to escalate the privilege level of their current access and give themselves time to probe the server and exfiltrate higher value data.
Attack Vectors & Variants
RCE vulnerabilities are all based on code that permits a confusion between handled data and executed code, but variants (not covered in detail in this article) may include buffer overflows and deserialization vulnerabilities (there are other, less common types also):
- Buffer overflow – memory partitions known as buffers are used to contain set (pre-determined) amounts of data. When programs do not include bounds-checking on received input (e.g. when 60kb of data is sent by a user and then written to a buffer designed to hold only 50kb of data) then the input exceeds the allocated memory space. In this scenario, the buffer is said to overflow and, if vulnerable, an application may overwrite memory in adjacent buffers. Those buffers could have held important data, which is now overwritten (affecting data integrity). Alternatively, those buffers could also have held control instructions telling the processor what to do next – if a user can replace their contents with their own control instructions then they have successfully performed an RCE attack.
- Deserialization – Data represented by objects such as JSON must be serialized (converted into binary) in order to be transmitted over a network. To utilise this data, a receiving program must then deserialise it, converting it back into an object that the application can process. By manipulating the serialised data that is submitted to an application as part of an HTTP request, malicious users can produce altered objects that cause the program to execute unintended programming upon deserialisation.
- SQL Injection – This is entire vulnerability category of its own involving the unsafe concatenation of user input into SQL queries, however it may be possible to leverage it to achieve RCE utilising database features such as xp_cmdshell on Microsoft SQL Server.
How can AppCheck Help?
AppCheck can help screen for known and vendor-published remote code execution vulnerabilities in underlying operating systems, applications and web server software hosted on a given server; as well as detecting previously-unknown RCE vulnerabilities in deployed in-house code, from first-principles deduction.
AppCheck draws on checks for known vulnerabilities in vendor devices and installed utilities and software from a large database of published vulnerabilities known as CVEs. AppCheck also scans web applications for injection vulnerabilities from first principles, discovering potential injection points that may indicate a lack of input sanitisation which could lead to remote code execution.
The AppCheck Vulnerability Analysis Engine provides detailed rationale behind each finding including a custom narrative to explain the detection methodology, verbose technical detail, and proof-of-concept evidence through safe exploitation.
AppCheck is a software security vendor based in the UK, offering a leading security scanning platform that automates the discovery of security flaws within organisations websites, applications, network, and cloud infrastructure.
As always, if you require any more information on this topic or want to see what unexpected vulnerabilities AppCheck can pick up in your website and applications then please get in contact with us: firstname.lastname@example.org
Get started with Appcheck
No software to download or install.
Contact us or call us 0113 887 8380