Overview
Command Injection (also known as Remote Command Execution or RCE) is a critical security vulnerability that allows attackers to execute arbitrary operating system commands on the server running the application. In this attack scenario, the vulnerable application acts like a pseudo system shell, executing commands specified by the attacker with the same privileges and environment as the web service.Impact
Successful command injection can allow attackers to:- Execute any command available to the web server user
- Read, modify, or delete sensitive files
- Install malware or backdoors
- Pivot to other systems on the network
- Completely compromise the server
- Exfiltrate data from the system
Root Cause
Command injection attacks occur due to lack of proper input validation on data that gets passed to system command execution functions. User-controllable input from forms, cookies, HTTP headers, and other sources can be manipulated by attackers to inject additional commands.Platform Differences
The syntax and available commands differ between operating systems:- Linux/Unix: Uses shells like bash, sh, zsh
- Windows: Uses cmd.exe or PowerShell
Objective
Remotely find out:- The username of the web service on the operating system
- The hostname of the machine
Security Levels
- Low
- High
- Impossible
Vulnerability Analysis
The low security level has no input validation whatsoever. User input is passed directly to theshell_exec() PHP function, allowing complete command injection.Vulnerable Code
whoami # Command substitution&& and ;, but there are many other command chaining operators available.Why It’s Still Vulnerable
- Blacklist approach is fundamentally flawed (you can’t block everything)
- Only blocks TWO operators:
&∧ - Doesn’t block:
|,||,`cmd`,$(cmd),&(on Windows) - Single-pass filter (doesn’t prevent double encoding)
Bypasses
Since the filter only removes&& and ;, you can use:- Pipe operator
|:
- OR operator
||:
- Command substitution:
- Backgrounding (Linux):
Show Hint
Show Hint
The developer blocked
&& and ;, but those aren’t the only ways to chain commands in a shell.Think about other operators. What about piping? What about backgrounding commands? What about command substitution?Show Spoiler
Show Spoiler
Example payload: The hint in the help file mentions “backgrounding the ping command”, referring to the
127.0.0.1 | whoamiThe pipe operator | is not in the blacklist, so it passes through.Other working payloads:& operator.Testing Methodology
Manual Testing
- Test basic command chaining:
whoami
127.0.0.1 $(whoami)
whoami.127.0.0.1
$(whoami).127.0.0.1
Defense Strategies
Primary Defenses
-
Avoid System Commands Entirely
- Use native language features instead of shell commands
- PHP has
filter_var($ip, FILTER_VALIDATE_IP)for IP validation - Use libraries instead of system tools when possible
-
Input Validation (Whitelist)
Additional Defenses
- Use escapeshellcmd() and escapeshellarg()
What Doesn’t Work
- Blacklisting special characters: Too many bypasses
- Filtering specific operators: New operators always exist
- String replacement: Can be bypassed with encoding
- Client-side validation: Easily bypassed
