When a website lets users introduce some type of data, it might be open to a File Inclusion attack. This can grant a skilled hacker access to all the data on the web server.
Let’s learn how we can do it in our #FromZeroToHacker challenge.
Table of contents |
Introduction |
What I have learnt today? |
Stats |
Resources |
Introduction to File Inclusion
What’s File Inclusion?
In some web applications, they request access to files on a given system, including images, text, videos, and more. These requests are done via parameters: A string added to the URL used to retrieve data or perform actions.
For example, if we use Google search if we search for cars
, the URL would be something like https://www.google.com?search?q=cars
. q
being query
and cars
the word we are looking for.
Another scenario is where a user requests access to some files from a server.
First, the user sends an HTTP request to the server, asking for a file to display. https://www.example_website.com/get.php?file=userCV.pdf
would be the URL, where file
is the parameter and userCV.pdf
the required file.
Why do File inclusion vulnerabilities happen?
File inclusion vulnerabilities are commonly found when some webserver uses programming languages that are poorly written and implemented, such as PHP.
The main issue with FI, is the lack of proper input validation, letting the user write whatever they want, as it is not sanitized or validated properly, giving them control over the code.
What is the risk of File inclusion?
An attacker can leverage File inclusion vulnerabilities to have access to data, such as code, credentials o important files. Even more: If the attacker can write files to the server, File inclusion may be used in tandem to gain Remote Command Execution or RCE.
This allows attackers to remotely execute malicious code on a computer or server.
Path traversal
Path traversal, or Directory traversal, is a vulnerability that allows the attacker to read resources from a computer, such as local files on the server side. The attacker exploits this vulnerability by manipulating the web application URL to locate and access files or directories.
Path traversal occurs when the user’s input is passed to a function such as file_get_contents
in PHP.
The problem is not the function nor PHP, but that poor input validation or a lack of proper filtering lets the user navigate over the website via URL:
The principle is simple: Path traversal attacks takes advantage of moving the directory one step up using the double dots ../
. The attacker fins an entry point, in this example, get.php?file=
, then the attacker may send something as http://webapp.thm/get.php?file=../../../../etc/passwd
.
Without proper input validation, the web retrieves the content of other directories, as each ../
moves one directory until it reaches the root directory, then it changes it to /etc/passwd
, reading the passwd
file.
This is true in a Linux server, but we can attack a Windows server in the same fashion. If we want to access the boot.ini
file, the attacker should replace the URL like this: http://webapp.thm/get.php?file=../../../../boot.ini
.
Sometimes, developers will add filters to limit access to only certain files or directories. Here is a list of common OS files we can test:
/etc/isue
– Contains a message or system identification to be printed/proc/version
– Specifies the version of the Linux kernel/etc/passwd
– Has all registered user that has access to a system/etc/shadow
– Contains information about the system’s users’ passwordsC:\boot.ini
– Contains the boot options for computers with BIOS firmware
Intro to Local File Inclusion (LFI)
LFI attacks are mostly due to the developers’ lack of security awareness. For example, PHP functions such as include, require, include_once and require_once often contributes to vulnerable web applications. PHP is just an example, as ASP, JSP, and Node.JS frameworks, for example, also have their vulnerabilities.
Let’s see some example scenarios:
<?PHP include($_GET["lang"]); ?>
This code gets the value of ‘lang’ in the URL. http://webapp.thm/index.php?lang=EN.php
for the English version of the page, http://webapp.thm/index.php?lang=AR.php
for the Arabian version.
With no input validation, we could try to read the /etc/passwd
file on a Linux OS: http://webapp.thm/get.php?file=/etc/passwd
.
We can fix it with the following code:
<?PHP include("languages/". $_GET['lang']); ?>
Now, we only get the file if it is in the languages
folder, stopping our attack (by now 🙂 ).
Going deeper with Local File Inclusion (LFI)
If we try an invalid input, we get the following error:
Warning: include(languages/xxxxx.php): failed to open stream: No such file or directory in /var/www/html/THM-4/index.php on line 12
This error gives us important information: The language of the code is PHP, and there is an include
function that looks for files inside the languages
folder.
We entered xxxxx
as the name of the file in the URL, so it may add .php
at the end of the input.
Also, we can tell that the web server folder is /var/www/html/THM-4/
.
Knowing this, we reckon we may use the ../
trick 4 times to get to the root folder, then move to /etc/passwd
.
We try, and get the same error! Seems like we could move out the PHP directory, but remember that the function includes the .php
extension at the end. Pretty clever.
But we are cleverer. We can bypass this with the NULL BYTE, or %00
.
Using null bytes is an injection technique, where %00
or 0x00
is used to terminate strings, ending the string and not using the .php
extension.
Note: Null bytes injection was fixed in the PHP 5.3.4 version and above.
http://www.website.com/test.php?file=../../../../etc/passwd%00
But now the developer has decided to filter keywords, and the /etc/passwd
string is filtered!
We can use methods to bypass this, as always. Similar to cd ..
in Windows, we can use /etc/passwd/.
to move one step back, ignoring the filtering. /etc/passwd means ‘Read the file /etc/passwd’, something that is filtered. /etc/passwd/
means ‘Go to etc directory, then move to passwd directory, then go to the next directory’. /etc/passwd/.
means all that, but the dot tells ‘Go one step back’, leaving finally /etc/passwd
, but avoiding the filtering.
http://www.website.com/test.php?file=/etc/passwd/.
The web developer, tired of our multiple intrusions, has decided to finally use input validation and our little trick doesn’t work anymore.
Warning: include(languages/etc/passwd): failed to open stream: No such file or directory in /var/www/html/THM-5/index.php on line 15
If we pay attention to the error messages (something we should ALWAYS do), the code is replacing our ../
with an empty string. That’s why on the Warning we read includes//etc/passwd/.
: Each ”../
” is ignored.
But we can laugh at that, as we can double down and now using ....//.
If it replaces the first string of two dots with a slash, we send four dots and 2 slashes, removing the third and four dots and the first slash:
http://www.website.com/test.php?file=....//....//....//....//etc/passwd/.
We got them!
Now, as their last bullet on the chamber, they try to force us to use a folder such as http://www.website.com/test.php?file=files/EN.php.
To exploit this, we just include the folder, then our code: http://www.website.com/test.php?file=files/../../../../etc/passwd
Remote File Inclusion (RFI)
Remote File Inclusion or RFI, is a technique to include remote files into a vulnerable application. Like LFI, RFI occurs when improperly sanitizing user input, allows an attacker to inject an external URL into a include
function. This requires that the allow_url_fopen
is on.
RFI has a higher risk than LFI as it allows an attacker to gain Remote Command Execution or RCE (allowing an attacker to gain partial or full control of the server terminal) on the server. Other consequences of an RFI attack include:
- Sensitive Information Disclosure
- Cross-Site Scripting (XSS)
- Denial of Service (DoS)
An attacker needs to host the malicious file in an external server for a successful RFI attack. The malicious file is injected into the include function via HTTP requests, executing the content of the malicious file on the server:
In this example, the attacker injects the malicious URL (1). If there is no input validation, the malicious URL passes into the include function and the web server sends a GET request (2) to the malicious server, fetching the file (3).
The web app, then, includes the remote file into the include
function (4), executing the PHP file within the page and finally sending the execution content to the attacker (5), showing the Hello THM
message.
How to fix it?
As a developer, it is important to be aware of web vulnerabilities, how to find them, and prevention methods. To prevent File Inclusion we can:
- Keep the system and services updated to the last version
- Turn off PHP errors in production to avoid leaking the path of the app
- A Web Application Firewall (WAF) can mitigate web application attacks
- Disable PHP features that may cause file inclusion vulnerabilities, such as
allow_url_fopen
andallow_url_include
. - Analyze the web application and allow only protocols and PHP wrappers strictly needed.
- Never trust the user’s input. Validate everything.
- Implement whitelisting for filenames and locations, as well as blacklisting.
Summary
We have learnt a lot about File Inclusion vulnerabilities:
- Path Traversal, a vulnerability that lets us reach into the system resources by just manipulating the URL.
- Local File Inclusion, a way to also have our way with system resources by manipulating the users’ input.
- Remote File Inclusion, another way to manipulate the server, this time by forcing the web server to download a malicious file.
- Ways to solve File Inclusion vulnerabilities.
Stats
From 167.982th to 164.214th. Still in the top 8% in TryHackMe!
Here is also the Skill Matrix: