Wednesday, April 11, 2018

Command Injection (I): Attacking unsanitized PHP files


- Layout for this exercise:

1 - Command Injection attack

- The goal of this exercise is to perform a Command Injection attack from the attacker Kali Linux against the victim Ubuntu.

- Command injection is an attack in which there is an execution of arbitrary commands on the host operating system via a vulnerable application:

- Command injection attacks are possible when an application passes unsafe user supplied data (forms, cookies, HTTP headers etc.) to a system shell. 

- The attacker-supplied operating system commands are usually executed with the privileges of the vulnerable application. 

- Command injection attacks are possible largely due to insufficient input validation.

2 - Unsanitized PHP file

- First of all, let's start the XAMPP server on Ubuntu:

- In this exercise we take for granted that at the victim machine's web server there is a ci.php file that is vulnerable to Command Injection due to improper input validation.

- This file can be found on the victim's web server either due to poor programming practice or due to a backdoor download by an unsuspecting user:

- Opening ci.php:

- The file is simple, it consists of just a PHP script embbeded into an HTML page. 

- The PHP script defines a comand $command and then executes it with the PHP function passthru(), useful when binary data needs to be passed directly back to a browser.

- $command is composed of two concatenated subcommands : first, ls -alh displays the content of the path passed as parameter; second, the superglobal variable $_REQUEST takes as input the non sanitized parameter 'path'

3 - Launching Command Injection attacks

- Now, from Kali let's run ci.php at the browser. The result is the path of the web server where ci.php is located:

- Changing to path=/home:

- Going to the user roch's Desktop with path=/home/roch/Desktop:

- So far, we have performed a kind of attack similar in some way to a Directory or Path Traverse attack. 

- However, using the ; separator, other commands can be concatenated from the attacker's browser, for instance ping:

- Also, the command cat can be used to open content of compromising files:

- Establishing a persistent connection with ncat

- Now let's perform a more dangerous attack by establishing a persistent connection with ncat

- Forcing remotely the server to run a listening session on port 4444 and executing a shell (-e /bin/bash):

- Let's notice that the web server starts listening for a connection:

- Finally, the attacker launches a connection to the server's IP and port 4444 what results in the remote execution of shell commands:

5 - Uploading/Downloading files from/to the attacker Kali to/from the victim Ubuntu

- As a complement of last attack, using ncat the attacker is able to upload and download files, and more types or remote interaction through the victim's shell.

5.1) Uploading files from Kali (attacker) to Ubuntu (victim)

- Crafting the URL at the attacker Kali's browser, the injected command forces the victim to listen on port 4444 the arrival of a file, what will be called webshell.php:

- Kali has got a dangerous PHP webshell script what wants to upload to the victim Ubuntu, actually to the web server htdocs folder:

- Now, Kali sends the PHP script to the victim who is listening on port 4444:

- The transaction is successful, and now the victim's web server folder has beed uploaded with a dangerous PHP script what could be used for further attacks:

5.2) Downloading files from Ubuntu (victim) to Kali (attacker)

- Preparing the attacker Kali to receive a file on port 4444 and naming it redbud.jpeg:

- Crafting the URL at the attacker's browser, the injected command forces the victim to send the .jpeg picture to the attacker who is listening on port 444::

- The transaction attack is successful:

- Launching another attack, let's prepare again the attacker to receive a text file, and naming it secret:

- Crafting the URL at the attacker's browser, the injected command forces the victim to send the text file to the attacker who is listening on port 4444:

- The transaction attack is again successful:

6 - Filtering with str_replace()

- With the purpose of sanitizing the input parameter let's rename to ci_f1.php and perform some alterations to the orignal PHP script:

- The new file uses the function str_replace() replacing ; and invalidating any command injection using that character.

- Using ci_f1.php:

- Now the character ; as a  separator is not valid any more to launch a command inject attack:

- However, alternative characters could be used to bypass this filter, so using str_replace() is not a very powerful solution, because so many characters should be banned in the same way than ;  what would make the coding task bothersome.

- For instance using the character pipe | the ping command injection attack is still successful:

7 - Filtering with escapeshellarg() / escapeshellcmd()

- The PHP function escapeshellarg() adds single quotes around a string and quotes/escapes any existing single quotes allowing to pass a string directly to a shell function and having it be treated as a single safe argument:

- This function should be used to escape individual arguments to shell functions coming from user input. 

- Altering ci.php with escapeshellarg() and renaming to ci_f2.php, the $_REQUEST['path'] function is sanitized with escapeshellarg():

- Using ci_f2.php:

- Now no Command Injection attack is successful because the input parameter is being validating correctly:

- By the way, the function escapeshellcmd() could be used in a similar way than escapeshellarg():

- escapeshellcmd() escapes any characters in a string that might be used to trick a shell command into executing arbitrary commands. 

- This function should be used to make sure that any data coming from user input is escaped before this data is passed to the exec() or system() functions, or to the backtick operator.

- Following characters are preceded by a backslash: &#;`|*?~<>^()[]{}$\, \x0A, \xFF.

- ' and " are escaped only if they are not paired.

- In Windows, all these characters plus % and ! are replaced by a space instead.