Local File Inclusion (LFI) vulnerabilities are common in web applications and frequently encountered during security assessments, and penetration tests. While the term is widely used, the underlying mechanism is often misunderstood. In particular, confusion usually arises around what it actually means to "include a file" and why this behavior becomes dangerous when combined with user-controlled input.

  1. What the include function really does in PHP ? In PHP, include() is used to load a file into a script at runtime. From a technical standpoint, this operation goes far beyond simply displaying a page. When PHP executes an include statement, it: - reads a file from the server's local filesystem - passes its content to the PHP interpreter - executes it in the context of the calling script this means the include file : - shares variables and scope - has access to the current session - executes with the permissions of the web server In other words, including a PHP file is equivalent to executing its code as part of the application itself.
  2. Why include is commonly used with parameters ? Modern web applications rely heavily on templates to avoid code duplication. A common pattern is to use a single entry point that loads different content based on user navigation. Example URL:
/index.php?page=about
#Typical server-side code
include("pages/" . $_GET['page'] . ".php"); 

For the developer's perspective : - page is a logical identifier ? - only predefined internal pages are expected to be loaded ? - the parameters is not seen as a free-form input ? This assumption is where the security issues begins.

3. The core issue: incorrect trust assumptions From a security perspective, one rule is fundamental: any data coming from an HTTP request is controlled by the user.. This includes:

  • GET parameters
  • POST parameters
  • cookies
  • URL path components

As a result, $_GET['page'] must always be treated as untrusted input. When such input is passed directly to include, the application effectively allows the user to influence which file the server loads from disk. The parameter no longer represents a "page"; it represents a file path.

4. What is then a FLI ? It's a vulnerability that allows an attacker to manipulate a file inclusion mechanism, force the application to load local files stored on the server, through user-controlled parameter that is not properly validate. Of course the "local files" refers to files that already exist on the servers such as : system files, config files, app source code, logs or internal resource. These files are normally inaccessible from the browser but become reachable indirectly through the inclusion mechanism. The include function is dangerous as it allows not only to read a file but execute it as well → if the included file contains PHP code, that code is executed in the application's context. Other function in PHP can be mentioned such as : - include_once() : allow read, execute - require()/require_once() : allow read and execute only - file_get_contents() : allow read - fopen()/file() : allow read only

5. What are the risks and impact of an LFI vulnerability ? - Exposure of sensitive configuration data - Leakage of credentials or secrets - Detailed reconnaissance of the server environment

6. Remediations The general principle is that user input should never directly control : file paths, inclusion mechanisms, and execution primitives. So the first step would be to never include raw user input, and to use a strict whitelisting.

Since we explained the nature of this attack, let's try to solve the challenges available on TryHackMe room! :)

Lab 1 : Since there's no input validation, there's no directory specified as well in the include function, so we just need to paste this in the URL : http://@ip/lab1.php?file=/etc/passwd

Lab 2 : In this scenario, the directory is specified as we can see only the pages in the directory "langages" can be called. After entering a random path, we can see an error message specifying for the right directory files to call.

Lab 3 : This is a new context where we do not have the source code, and should rely on error messages. The error message disclosed the directory path we are in /var/www/html/THM-4 , we now can just apply the same method as the first two labs relying on ../ However, we can notice that another error arise after using it, it's because the include function reads the input with .php at the end, so to bypass it we use the NULL BYTE at the end which is %00 in the URL (cf. picture) note : it has been patched with PHP 5.3.4

None

Lab 4 : the function we are talking about has been mentioned earlier :( I hope you checked what I wrote :(

Lab 6 : 1. The error when trying to access something gives you the directory lol 2. For the last question, instead of writing the path as we usually do it, we incorporate the last parameter as a path which will give us something like THM-profile/………………../etc/os-release (make sure to get the right number of ../ )

The last Task is related to the Remote File Inclusion — RFI The difference between the LFI and the RFI, is that the LFI counts Local files, while the RFI will include remote files into a vulnerable application. The attacker will inject an external URL into the include function, to be able to execute it the "allow_url_fopen" option needs to be on.