Spot the Vulnerability LFI Code Challenge

  • Home
  • Spot the Vulnerability LFI Code Challenge
Spot the Vulnerability LFI Code Challenge
Spot the Vulnerability LFI Code Challenge
Spot the Vulnerability LFI Code Challenge
Spot the Vulnerability LFI Code Challenge
Spot the Vulnerability LFI Code Challenge

Introduction to Local File Inclusion (LFI)

Local File Inclusion usually referred to as LFI is not so common vulnerability that comes under web applications in which an attacker tricks the web application and tries loading local files of the application itself or the important local server files on which its hosted.

LFI is a critical web attack that if exposed can be crafted and further escalated to various other attacks like information disclosure, website defacing, remote code execution, or even Cross-site Scripting (XSS), reverse shell, and many others.

Without going deeper into let’s have a look at the following PHP code snippet. But if you want to learn in detail about LFI, RFI you can check our Workbook Resource > Web-app Pen-test.

LFI code snippet
Code Snippet

Understanding the LFI Challenge

The above code block is written in PHP language in which the developer tries to access a file within the application. We will visit the code line by line and then will try to exploit the written code and craft our payload for the attack.

Explanation

1. In the first line we can see a require statement means the block requires “constants.php” to execute.

2. On the next line a message is echoed.

3. Moving to next line is an if statement block is there and will execute only if get parameter are !==NULL.

4. In if statement block, we assign a variable named $file and provide a get parameter named file to it as a value.

5. Further we perform a regex replace on the value to filter and sanitize the user input for (directory traversal, null bytes, some important OS folders like etc, proc, C: etc.

6. On the next line we further replace Linux-based imp directory like etc and proc if the attacker manages to bypass our regex for further sanitation and assign the value to our $file variable.

7. We then trim the attacker’s crafted payload to a specific length which the attacker has assumed cause its value is taken from the constant name PARAM declared in “constants.php”.

8. After performing all sanitation, filtration and replace the code includes the file.

Exploiting code

First, let’s look at PHP preg_replace() behavior.

As per php.net preg_replace($pattern, $replacement, $subject) the method returns a new string with all matches of a pattern replaced by a replacement in the subject. The pattern can be a string or a Regexp, and the replacement can be a string or a function called for each match.

However, the above function only replaces all occurrences of a match. But preg_replace() also accepts some additional parameters which are:

  • int $limit=-1
  • int &$count=null

$limit parameter specifies the number of time replace to be done in the given input or we can say subject by default the value is -1 (recursively) and is passed as a positive integer. The next parameter is &$count of the replacement carried out which returns the value of the replacement done and is passed as a reference.

But unknowingly the developer used one of this parameter which if not specified default value is -1 considered means replace all matches. But in this case, it is not so having closer look you can see the value specified is 3 indicates only 3 matches will be replaced, and further the payload can be bypassed once the patterns are matched.

Which is exploitable!

Next, the next statement simply matches the pattern of strings that are, etc and proc throughout the payload which can be easily bypassed. But solving this challenge requires skill cause the attacker must craft a payload with minimum chars assuming the value for PARAM. Let’s craft our payload to pass to the input:

1. Assuming PARAM Value >=23

2. Assuming param Now we have got the flaw we will simply try to bypass the preg_replace() with

%1%1%1 minimum char’s payload to bypass the preg_replace()

3. The next str_replace() can be bypassed using the following minimum payload

/etceetctc/passwd

4. Final payload will look like

%1%1%1/etceetctc/passwd

The above solution mentioned is the best solution. We also received some more creative solution for our challenge one of the best solution which we liked the most was submitted by our winner Egidio Romano which was based on php Wrapper and the submitted payload was

php://php://php://php://filter/[CHAIN_HERE]/resource=php://temp

Mitigation

Mitigation will be like do not specify the limit parameter so PHP will consider its default value which is -1 and will recursively replace the patterns in the subject payload.

On string replacement, we can also include some important DIR like usr, proc, environ, etc equally important DIR’s. Or simply instead of blacklisting or replacing allow whitelisted DIR entries relating to the application.

We @SecurityBoat always thrive to create awareness for information security as we all know how much information security means in our today’s world. We always try to give our best for the sake of our community through various platforms and media handles. If you’re interested in more such challenges and awakening vulnerability issues in the cyber world irrespective of the domain please follow us and be a part of ours on our social handles.