githubEdit

lfi-file-inclusion

Local File Inclusion (LFI)

In modern web application, in order to generate dynamic content, developers uses parameter page loading like index.php?page=about. where index.php sets static content and pulled the dynamic content specified in the parameter, which may be read from a file called about.php.

How to find LFI vulnerability

We should look for such URLs which take filename as parameters http://vulnerable_site/preview.php?file=example.html

Bypass methods overview

Link of techniques

Testing_for_Local_File_Inclusionarrow-up-right

Null byte Injection

If .php extension is appended we can use Null byte Injection

http://vulnerable_host/preview.php?file=../../../../etc/passwd%00

PHP file limit of 4096 bytes

  • PHP drops when the given filename is longer than the length. When this happens not error is triggered

  • Use Unicode encoding

  • Use Double encoding

PHP wrappers add some functionality and Remote Code Execution:

PHP filters:

This wrapper can be used to get content of a file preventing the server from execution php://filter/convert.base64-encode/resource=FILE

PHP Zip:

  • It is used to manipulate zip compressed files

  • It can be used to upload file and bypass extension restriction

  • zip:///filename_path#internal_filename

PHP data:

It take base64 encoded content data://text/plain;base64,PD9waHAgcGhwaW5mbygpOyA/Pg==

PHP expect:

It is not enabled by default, provides access to processes expect://command

Using double string (….//)

LFI can lead to:

  • Source code disclosure

  • Sensitive data exposure

  • Remote code execution

Example of vulnerable code

A website may have a ?language GET parameter, if a user change language from the drop-down menu, the ?language parameter would change as well. In such cases, changing the language my change the directory where the web app is loading the pages.

Read/write functions:

Functions
Read
Execute
Remote URL

PHP

include()/include_once ()

✔️

✔️

✔️

require()/require_once()

✔️

✔️

file_get_content()

✔️

✔️

fopen()/file()

✔️

NodeJS

fs.readFile()

✔️

fs.sendFile()

✔️

res.render()

✔️

✔️

Java

include

✔️

import

✔️

✔️

✔️

.NET

@Html.Partial()

✔️

@Html.RemotePartial()

✔️

✔️

Response.WriteFile()

✔️

include

✔️

✔️

✔️

File Disclosure

Web application preventions

Common files to read

Back-end Scenarios (it depends upon the web server coding style)

  1. When the whole user input is include (include($_GET['language']);) Absolute path /etc/passwd

  2. When the only string appended [parm value] (include("./languages/" . $_GET['language']);) Relative path ../../etc/passwd

  3. Filename prefix is used (include("lang_" . $_GET['language']);) Relative path ../../etc/passwd

  4. Appended extensions (include($_GET['language'] . ".php");) Absolute path /etc/passwd

  5. Advance attack (second-order attacks)

    • This attack occurs many web applications functionalities may be insecurely pulling file from the back-end server based on user-controlled parameters.

    • When a web application tries to download our avatar through URL like /profile/$username/avatar.png

Basic Bypasses

Non-recursive path traversal filters:

One of the most basic filters against LFI is a search and replace filter, where it simply delete substring of (../) to avoid path traversal. Example: $language = str_replace('../', '', $_GET['language']);

How do I bypass it

This filter is not recursively deleting ../ string we can use double string ….// ….//

Encoding:

URL encoding

Approved paths:

Only accepts specific paths under, let's say, ./language directory How do I bypass it We may start our payload with the approved path, and then use ../ to go back to the root directory and read the file we specify ?language=./language/../../../etc/passwd

Combine any two or more bypass techniques

Appended extension

We may not be able to bypass it, there are couple of techniques but they only works with PHP version before 5.3/5.4 Path truncation: In earlier version of PHP, strings have maximum length of 4096 characters, due to limit of 32-bit systems. Any text after the max length will be ignored. Linux general, also disregard multiple slashes in the path. Payload:

Null bytes

PHP version before 5.5 were vulnerable to null byte injection, anything after a null byte (%00) will not consider. (This is how strings are store in low-level memory, null byte indicate the end of string in memory) /etc/passwd%00.php

PHP filters

PHP filters are a type of PHP wrappers, where we can pass different types of input and have it filtered by the filter we specify. These filters/wrappers can used to read restricted source code or local files.

Input filters

Filter wrapper has several parameters:

  • Resource

  • Read

  • e.g., php://read/.

Different types of filters

  • String filters

  • Conversion filters

  • Compression filters

  • Encryption filters

Fuzz for PHP files (first step)

  • FUZZ for different available PHP pages

  • Dir: directory-list-2.3-small.txt

  • URL: http://target/FUZZ.php

  • Obtain a list of files to read e.g. config.php

Standard PHP inclusion (LFI with appended PHP extension)

If we try to access config file as it just a configuration. it is executed and not show in the html page, so we will use PHP base64 wrapper/filter to encode the file content and show on the browser instead of execute.


Remote file Inclusion (RFI)

RFI is usually disabled by default as it dangerous practice. Any remote URL inclusion in PHP would require the allow_url_include settings to be enabled.

Verify RFI

  • In this page

    • RCE > check php configuration > check

It is always best practice to start with local file e.g. http://<SERVER_IP>:<PORT>/index.php?language=http://127.0.0.1:90/index.php

[[CPTS Notes/04 Web Exploitation/LFI/RCE|RCE with RFI]]


Automated Scanning

It is essential to understand how LFI & RFI attacks work and how we can manually craft advanced payloads and use custom techniques to reach remote code execution.

Fuzzing parameters

Fuzz for exposed parameters

Most Popular LFI parametersarrow-up-right

LFI wordlists

LFI-seclistsarrow-up-right LFI-jhaddixarrow-up-right

Once we have identified payloads, we should manually test them to verify that they works as expected.

Fuzzing server files

Depending on our LFI situation, we may need to add a few back directories(eg. ../../../../).

Server Webroot

  • Wordlist for Linux

  • Wordlist for windows

  • We can also use LFI-Jhaddix.txt file here

Server logs/configurations

  • I need to able to identify the correct logs directory to be able to perform the log poisoning attacks.

  • We may use LFI-Jhaddix.txt file

  • After the scan is complete and got results

  • Try to access files

LFI tools

File Inclusion prevention

  • Do not include user controlled input into any file inclusion function.

  • Prevent directory traversal by using programming language built-in tools to pull only the filename.

  • Sanitize user input to recursively remove any attempts to traversing directories.

  • Web server configuration (allow_url_fopen and allow_url_include to off)

  • Install web application firewall (WAF)

Last updated