File Inclusion

  • File inclusion vulnerabilities occur when a web application allows users to specify input that is used to determine which resource is shown on the page. If these functionalities are not securely coded, an attacker may manipulate these parameters to display the content of any local file on the hosting server.

  • Some file inclusion vulnerabilities allow only reading the content of the specified files, while others also execute the specified files. Some allow only local files, while others allow remote files as well.

  • Two common readable files that are available on most back-end servers are /etc/passwd on Linux and C:\Windows\boot.ini on Windows. These files can be used to test for file inclusion vulnerabilities.

  • In most cases, file inclusion vulnerabilities require using relative paths (Directory Traversal) (e.g., ../../../etc/passwd) instead of absolute paths, similar to a path traversal vulnerability.

  • A more advanced type of LFI attack is a Second Order Attack. This occurs when an attacker poisons a database entry with a malicious LFI payload and then accesses this payload later. For example, if a system allows users to download their profile pictures, an attacker could set their profile picture name to ../../../etc/passwd.

Basic Bypassing

  • Non-Recursive Path Traversal Filters: This is the most basic defense against file inclusion vulnerabilities. If the system finds ../ and replaces it with an empty string, it can be easily bypassed by using different payloads depending on the filtering mechanism (e.g., ../../, ....//, ....\/, etc.).

  • Character Restrictions: If characters like . and / are prevented, this can be bypassed by URL encoding the payload before sending it.

  • Approved Path Restrictions: If only files from a specific path (e.g., /languages/) are accessible, the attacker needs to identify the approved path and then start from there (e.g., /languages/../../../).

  • File Extension Restrictions: If only files with a certain extension (e.g., .php) are allowed, older versions of web servers may be vulnerable to null byte injections (e.g., /etc/passwd%00.php) or path truncation by adding multiple // or ././././ to truncate the extension at the end.

PHP Wrappers

  • PHP Wrappers allow access to different I/O streams at the application level, such as standard input/output, file descriptors, and memory streams. Attackers can utilize these wrappers to extend their exploitation attacks, read PHP source code files, or even execute system commands.

  • Filter Wrapper:

    • Can be used to base64 encode the content of a file, e.g., php://filter/read=convert.base64-encode/resource= (note that .php is appended by default).

    • To decode the base64 content: echo '<File-Base64>' | base64 -d

    • Note that to pass commands via a GET request, the vulnerable function must accept GET requests (i.e., use $_REQUEST). If it only accepts POST requests, the command can be placed directly in the PHP code, e.g., <?php system('id')?>.

  • Data Wrapper:

    • Allows the inclusion of external data, including PHP code. However, this requires the allow_url_include setting to be enabled in PHP configurations. Example: http://<Server-IP>:/index.php?language=data://text/plain;base64,&cmd=id

  • Input Wrapper:

    • Similar to the data wrapper, it includes external input and executes PHP code passed as POST data. It also requires allow_url_include to be enabled.

    • Note that to pass commands via a GET request, the vulnerable function must accept GET requests (i.e., use $_REQUEST). If it only accepts POST requests, the command can be placed directly in the PHP code, e.g., <?php system('id')?>.

  • Expect Wrapper:

    • Allows commands to be run directly through URL streams.

    • This is an external wrapper that must be manually installed and enabled on the server. Example: http://<Server-IP>:/index.php?language=expect://id

  • Zip Wrapper:

    • Executes PHP code within a zipped archive. This wrapper is not enabled by default and requires creating a PHP web shell, zipping it into an archive (e.g., shell.jpg), and then including it using the zip wrapper (e.g., zip://shell.jpg#shell.php).

Remote File Inclusion

  • In some cases, an application may allow remote files to be included via RFI. If the vulnerable function allows the inclusion of remote URLs, an attacker can host a malicious script and include it on the vulnerable page to execute malicious functions and gain remote code execution.

  • Most RFI vulnerabilities are also LFI vulnerabilities, as functions that allow remote URLs usually allow local ones as well. However, LFI vulnerabilities may not necessarily allow RFI.

  • For RFI, the allow_url_include setting must be enabled. However, including remote URLs is considered dangerous and is usually disabled by default. This setting can be checked through LFI by examining the configuration file.

  • To determine whether an LFI vulnerability is also vulnerable to RFI, try including a URL and see if its content is accessible. Start with a local URL to avoid being blocked by a firewall. Example: http://127.0.0.1:80/index.php

  • There are many methods we can devlier our payload once we identify a working RFI, for example, http, ftp, or smb.

  • If the vulnerable function allows code execution, the code within an uploaded file (e.g., image.jpg containing PHP code) will execute if included through the LFI vulnerability, leading to remote code execution.

Log Poisoning

  • Log poisoning involves writing PHP code into a log file by controlling a field, such as the User-Agent header, which gets logged. Once the log file is poisoned, it can be included through the LFI vulnerability to execute the PHP code.

  • PHP Session Poisoning: Involves manipulating the PHPSESSID session file to include malicious content, usually, stored in /var/lib/php/sessions/ on Linux and C:\Windows\Temp\ on Windows.

    • The name of the file that contains our user's data matches the name of our PHPSESSID cookie with the sess_ prefix.

    • First examine the PHPSESSID session file and see if it contains any data that contain input we provide/are able to change.

    • After identifying a changable variable, start injecting code to that variable and then using LFI access the log PHPSESSID session file to execute the code.

    • Note that to execute another command, the session file has to be poisoned with the web shell again, as it gets overwritten with each change. Ideally, we would use the poisoned web shell to write a permanent web shell to the web directory, or send a reverse shell for easier interaction.

  • Webservers like, Apache and Nginx maintain various log files, such as access.log and error.log, which can be poisoned. Once poisoned, we need to include the logs through the LFI vulnerability, and for that we need to have read-access over the logs. However, care must be taken, as logs can be large, and including them via LFI may cause performance issues or crash the server.

Automating Exploiting

  • Exploiting an LFI vulnerability may require custom payloads that match the specific configurations of the target system. When dealing with security measures like WAFs or firewalls, attackers must craft payloads to bypass these defenses. However, fuzzing tools can be used to test common LFI payloads, and specialized tools can automate testing for such vulnerabilities.

  • Hidden Parameters: Sometimes developers secure exposed parameters but overlook hidden ones, which can also be vulnerable. It is beneficial to fuzz for hidden parameters and test them.

  • We can test the parameters by also fuzzing them using a LFI wordlist.

  • Testing Parameters: Parameters can be tested using an LFI wordlist. For example, using ffuf to find the web root path: ffuf -w /opt/useful/SecLists/Discovery/Web-Content/default-web-root-directory-linux.txt:FUZZ -u 'http://<Server-IP>:/index.php?language=../../../../FUZZ/index.php' -fs <False-Size>

  • LFI Tools: LFISuite, LFiFreak, and liffy are common tools used for automating the LFI exploitation process.

File Inclusion Prevention

  • The most effective way to reduce file inclusion vulnerabilities is to avoid passing any user-controlled inputs into file inclusion functions or APIs. The page should dynamically load assets on the back-end, with no user interaction. If user input cannot be avoided, use a limited whitelist of allowed inputs and match each input to the file to be loaded, with a default value for all other inputs.

  • Directory Traversal Prevention: Use the programming language's or framework's built-in tools to extract only the filename and sanitize user input to recursively remove any attempts of directory traversal.

  • Configuration Best Practices:

    • Disable the inclusion of remote files globally.

    • Lock web applications to their web root directory, preventing access to non-web-related files.

    • Use Docker to isolate applications.

    • Implement a Web Application Firewall (WAF) as a hardening measure.

Last updated