FILE INCLUSION

File Inclusion Vulnerabilities is a vulnerability that often affects web applications when a user is allowed to requests files with poor input sanitation or validation. This becomes a risk if the attacker is able to read, edit, or create files on the server.


Web applications can be written to request files on a system, such as images or text files, via parameters. Parameters are query parameter strings attached to the URL that can be used to retrieve data or perform actions based on user input. See below for a breakdown of the essential parts of a URL. In this example the user is requesting a file called userCV.pdf via a GET request.


File inclusion vulnerabilities occur when a web application is poorly written. The main area of concern where user input is not sanitized or validated when they user controls them. For example, an attacker could visit http://webapp.tbh/get.php?file=userCV.pdf and if there is no authentication that the user who requested the file is allowed the file (for example needing to be logged in) then this is a vulnerability.

Path Traversal or Directory Traversal

Path Traversal or Directory Traversal is a web application vulnerability where an attacker is able to read operating system resources, for example the /etc/passwd file. Path traversal vulnerabilities occur when the user's input is passed in to a function such as file_get_contents in PHP. More indo on file_gets_content can be found here.

Below is an example of a path traversal vulnerability, where instead of requesting the userCV.pdf file, the attacker has instead used the URL to perform a path traversal attack (also known as a dot-dot-slash) which takes advantage of the ability to traverse the system directory and access operating system files.

Local File Inclusion (LFI)

Local File Inclusion (LFI) attacks against we applications are often due to a developers lack of security awareness. With PHP, poorly implemented functions such as include, require, include_once and require_once often create vulnerabilities.


For example, the below piece of PHP code receives the language via a GET request. If the HTTP request is sent as htpp://webapp.thm.index.php?lang=EN.php then it will return the English file. 



In theory, if there is no input validation, then an attacker can instead request any file that the server has. For example http://webapp.thm/get.php?file=/etc/passwd would return the /etc/passwd file. In this instance /etc/passwd can be accessed because there was no directory specified in the include function and there was no input validation.

In the below code, the developer used the include function to call PHP pages only in the languages directory and only with lang parameters.


However, due to there being no input validation, the attacker can replace the lang input with other payloads, such as /etc/passwd. For example, the payload would look like http://webapp.thm/index.php?lang=../../../../etc/passwd. This is because the PHP code has "placed" itself in the languages directory and needs to be navigated out of.


In the previous examples, I had access to the source code, however in the below examples I will not and I will need to use error messages in order to understand how the data is being processed. In this example, we input http://webapp.thm/index.php?lang=THM in order to try and revieve an error message. 

From the below error message, I am able to determine that the command looks like: include(languages/THM.php). If we compare my URL input to the code snippet below, we can see that .PHP is being added at the end of the entry and that languages are stored in the languages directory. 

The error message also tells us that the full web application directory path is /var/www/html/THM-4.


To exploit this, we need to use the dot-dot-dash trick. We know the path used 4 ../ because of the error message disclosing the path /var/www/html/THM-4. However, the input http://webapp.thm/index.php?lang=../../../../etc/passwd does not work and we receive the following error:


It seems we could move out of the PHP directory, but the include function reads the input with .php at the end, which tells us that the developer specifies that the file type to be able to included in the function. 

To bypass we can use the null byte %00 in the URL to get the include function stop reading any further than the null byte. This works because a string is always ended with a null byte in order to signify that it is the end of the string.

NOTE: the null byte %00 vulnerability is fixed and no longer working with PHP 5.3.4 and above.

In the below example, I have used to the local file inclusion vulnerability to access /etc/passwd by using the null byte to bypass the requirement that the include function needs its arguments to end in .php.


In the below example, the developer has filtered keywords to avoid disclosing sensitive information. There are two possible methods for bypassing this filter. First by using the null byte %00 eg.http://webapp.thm/index/php?lang=/etc/passwd%00, or the current directory trick at the end of a filtered keyword /. eg.http://webapp.thm/index/php?lang=/etc/passwd/.. This works because whilst cd .. will move a user back one directory, cd . will use the current directory and because the string does not match the filtered string, it can bypass it




In the following examples the developer has started to use input validation by filtering some keywords. If we try http://webapp.thm/index/php?lang=../../../../etc/passwd we get the following error: 


If we check the warning message, we can see that include(languages/etc/passwd) we can see the absents of any ../, which indicates that the ../ is being filtered. We can attempt to bypass this by replacing the ../ with ....// because if the filters are not properly configured, they will remove the elements of the substring as seen below:



In the below example I have used this vulnerability in order to bypass string filtering:




If the developer has forced the include function to read from a defined directory, then we will need to include that directory in the payload. For example http://webapp.thm/index/php?lang=languges/EN.php would need to include the languages directory in the payload. The payload would be: http://webapp.thm/index/php?lang=languages/../../../../etc/passwd. See the below example:



Remote File Inclusion (RFI)

Remote File Inclusion (RFI) vulnerabilities have a higher risk than local file inclusion as they may allow the attacker to gain Remote Command Execution (RCE) on the server. Other consequences of an RFI are:
  • 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. The malicious file is the injected in to the include function via HTTP requests and the malicious file is executed on the application server. See the image below.



To test this vulnerability, I made a payload that would just echo some text. I then hosted a HTTP server on my machine.



I then accessed file.txt by using my machine's HTTP server as part of the payload. This file was then executed by the include function on the targets server.

By using the below PHP code and executing the command as per the above example, I was able to use RCE to get the host name.



Challenge

Here I am challenged to find file inclusion vulnerabilities.

Her I have changed the request method from GET to POST in order to request the /etc/flag1 file using Burp Suite from the webserver.




This POST request then returned the contents of /etc/flag1 as below:




For the next task, I am greeted with this page at the target web app. Upon examination of the GET request in Burp Suite I could see that the cookies were setting the type of user accessing the web page. I first tried changing this to Admin and it allowed me to log in as Admin.

We can see here that include is appending .php to the end of my cookie payloads. I can circumvent this filtering by adding %00 to the end of my payloads so the PHP reads it as the end of a string.




Rather than continuing to try and use the cookie to log in as Admin, I instead input the location of the flag. I could tell how many directories I needed to go back as the current directory was displayed to me on the previous error message.






For the final task, I tried inputting the directory I was looking for in the URL and was returned an error. I can see at the bottom that I was returned Failed opening 'etcflag.php' which is my input, but stripped of any special characters and numbers.



As per the hint in the THM room, I have looked up $_REQUESTS and found that it accepts both POST and GET requests. It is possible that only the GET request method is being filtered and therefore rejected by $_REQUESTS so I will change the request method to POST in Burpsuite.

More information on $_REQUESTS can be found here: https://www.w3schools.com/php/php_superglobals_request.asp



Here we can see that by using the POST method I have successfully bypassed filtering that was applied to the GET method. However, we can still see that .php is still being appended to the payload, so I will use the Null Byte trick and try again.




The Null byte trick seems to have worked and we were able to get the final flag.


Comments

Popular posts from this blog

STARTUP

NMAP POST PORT SCANS

BURPSUITE IN-DEPTH