In this post, we’ll be exploring a technique to enumerate Linux processes through a web application vulnerable to LFI (Local File Inclusion).
File inclusion vulnerabilities allow attackers to read arbitrary files from local or remote systems and include the contents of the files in the web server’s response.
A Vulnerable Web App
We’ll use a simple php script to simulate a vulnerable web application. As shown in the following code, the include
statement is used to copy into the lfi.php
page, the contents of the file passed to the lang
variable:
1
2
3
4
<?php
if(isset($_GET['lang'])){
include($_GET['lang']);
} ?>
The following image shows a request/response to our web application, using the vulnerable parameter lang
to read the /etc/passwd
file:
The Proc File System
On Linux, the /proc
directory contains one subdirectory for every process running on the system. These subdirectories are named after each process ID number (PID) that is active.
Inside the PID subdirectories, we’ll find several files with information related to the running process. For example, to get the command-line arguments used to start a service, we can read the cmdline
file inside the corresponding subdirectory. In the following image, 915
is the PID for the Apache server process:
A full list of these files and it’s purpose can be found here.
Enumerating PIDs with Ffuf
We’ll create list with the numbers from 1 to 5000, and fuzz the PIDs with ffuf
. Since all requests returns a 200
status code, we’ll use the -fw 1
switch to filter responses with less than 2 words:
1
2
for i in $(seq 1 5000); do echo $i >> pid.txt; done && \
ffuf -c -w pid.txt:FUZZ -u http://10.0.0.19/lfi.php?lang=/proc/FUZZ/cmdline -fw 1
Now we can read the cmdfile
of any of the found PIDs. In the following example, we’ve discovered that on PID 4406
, the user rgivens
is running a bind shell on port 65534
:
Pythonizing the Process
I’ve created a python script to automate the process and write the contents of the extracted PID files into an output file for offline review. You can download the script here.
The parameters passed to the script are:
URL | The web application URL including the vulnerable parameter. |
Max PID Count | The maximum number of PIDs to try starting from 1. |
Proc File | Name of the file we want to read from inside the PID subdirectory. |
Output File | Name of the output file. |
Here's a snippet replicating the attack with the Python script:
Remediation
When used properly, file inclusion is a feature and not a bug. But poor implementation turns it into a critical vulnerability. Some general recommendations developers can use to prevents LFI attacks include:
- Implement a Web Application Firewall (WAF).
- Never trust user input, and make sure to implement proper input validation against file inclusion.
- Implement whitelisting for file names and locations as well as blacklisting.