# Testing for File Inclusion

## Summary

The File Inclusion vulnerability allows an attacker to include a file, usually exploiting a "dynamic file inclusion" mechanism implemented in the target application. The vulnerability occurs due to the use of user-supplied input without proper validation.

This can lead to something as simple as outputting the contents of the file, but it can also lead to:

- Code execution on the web server
- Code execution on the client-side such as JavaScript which can lead to other attacks such as cross site scripting (XSS)
- Denial of Service (DoS)
- Sensitive Information Disclosure

Local File Inclusion (LFI) is the process of including files that are already present on the server through exploitation of vulnerable inclusion procedures implemented in the application. For example, this vulnerability occurs when a page receives input that is a path to a local file. This input is not properly sanitized, allowing directory traversal characters to be injected (such as `../` -- see 4.5.1 [Testing Directory Traversal File Include](../05-Authorization_Testing/01-Testing_Directory_Traversal_File_Include.md)).

Remote File Inclusion (RFI) is the process of including files from remote sources through exploitation of vulnerable inclusion procedures implemented in the application. For example, this vulnerability occurs when a page receives input that is the URL to a remote file. This input is not properly sanitized, allowing external URLs to be injected.

In both cases, although most examples point to vulnerable PHP scripts, we should keep in mind that it is also common in other technologies such as JSP, ASP, etc.

## Test Objectives

- Identify file inclusion points.
- Assess the severity or potential impact of the vulnerabilities.

## How to Test

### Testing for Local File Inclusion

Since LFI occurs when paths passed to `include` statements are not properly sanitized, in a black-box testing approach, we should look for functionality that accepts file names/paths as parameters.

Consider the following example:

`https://vulnerable_host/preview.php?file=example.html`

This looks to be a promising place to try LFI. If the application does not select the appropriate page given in the `file` parameter and instead directly includes the input, it is possible to include arbitrary files from the server.

A typical proof-of-concept exploit would be to attempt to load the `passwd` file with:

`https://vulnerable_host/preview.php?file=../../../../etc/passwd`

If the above mentioned conditions are met, an attacker would see something like the following included in the response:

```bash
root:x:0:0:root:/root:/bin/bash
bin:x:1:1:bin:/bin:/sbin/nologin
daemon:x:2:2:daemon:/sbin:/sbin/nologin
alex:x:500:500:alex:/home/alex:/bin/bash
margo:x:501:501::/home/margo:/bin/bash
...
```

Even when such a vulnerability exists, its exploitation could be more complex in real life scenarios. Consider the following piece of code:

```php
<?php include($_GET['file'].".php"); ?>
```

Simple substitution with a random filename would not work as the postfix `.php` is appended to the provided input. In order to bypass it, a tester can use several techniques to get the expected exploitation.

#### Null Byte Injection

The `null character` (also known as `null terminator` or `null byte`) is a control character with the value zero present in many character sets that is being used as a reserved character to mark the end of a string. Once used, any character after this special byte will be ignored. Commonly the way to inject this character would be with the URL encoded string `%00` by appending it to the requested path. In our previous sample, performing a request to `https://vulnerable_host/preview.php?file=../../../../etc/passwd%00` would ignore the `.php` extension being added to the input filename, returning to an attacker a list of basic users as a result of a successful exploitation.

#### Path and Dot Truncation

Most PHP installations have a filename limit of 4096 bytes. If any given filename is longer than that length, PHP simply truncates it, discarding any additional characters. Abusing this behavior makes it possible to make the PHP engine ignore the `.php` extension by moving it out of the 4096 bytes limit. When this happens, no error is triggered; the additional characters are simply dropped and PHP continues its execution normally.

This bypass would commonly be combined with other logic bypass strategies such as encoding part of the file path with Unicode encoding, the introduction of double encoding, or any other input that would still represent the valid desired filename.

#### PHP Wrappers

Local File Inclusion vulnerabilities are commonly seen as read only vulnerabilities that an attacker can use to read sensitive data from the server hosting the vulnerable application. However, in some specific implementations this vulnerability can be used to upgrade the attack [from LFI to Remote Code Execution](https://www.corben.io/zip-to-rce-lfi/) vulnerabilities that could potentially fully compromise the host.

This enhancement is common when an attacker could be able to combine the [LFI vulnerability with certain PHP wrappers](https://www.netsparker.com/blog/web-security/php-stream-wrappers/).

A wrapper is a code that surrounds other code to perform some added functionality. PHP implements many [built-in wrappers](https://www.php.net/manual/en/wrappers.php) to be used with file system functions. Once their usage is detected during the testing process of an application, it's a good practice to try to abuse it to identify the real risk of the detected weakness(es). Below is a list with the most commonly used wrappers, even though you should consider that it is not exhaustive and at the same time it is possible to register custom wrappers that if employed by the target, would require a deeper adhoc analysis.

##### PHP Filter

Used to access the local file system; this is a case insensitive wrapper that provides the capability to apply filters to a stream at the time of opening a file. This wrapper can be used to get content of a file preventing the server from executing it. For example, allowing an attacker to read the content of PHP files to get source code to identify sensitive information such as credentials or other exploitable vulnerabilities.

The wrapper can be used like `php://filter/convert.base64-encode/resource=FILE` where `FILE` is the file to retrieve. As a result of the usage of this execution, the content of the target file would be read, encoded to base64 (this is the step that prevents the execution server-side), and returned to the User-Agent.

##### PHP ZIP

In PHP 7.2.0, the `zip://` wrapper was introduced to manipulate `zip` compressed files. This wrapper expects the following parameter structure: `zip:///filename_path#internal_filename`. The `filename_path` is the path to the malicious ZIP archive and `internal_filename` is the path of the malicious fi