LFI allows you to include files through a web server; however, specific injections of parameters in the URL string can lead to other files being called, if not used properly. A basic LFI file looks like the following:

   <?php
   $file = $_GET['file'];
   if(isset($file))
   {
       include("pages/$file");
   }
   else
   {
       include("index.php");
   }
   ?>

A legit referral would look like this: example.com/index.php?file=services.php. It searches the current directory and does not induce upper directory levels. This is the safe approach and should be a standard that you use.

There is also the malcreant approach: example.com/index.php?file=../../../etc/passwd. What this does is show all the passwords (in hash form) that are found on a nix-running system. The malcreant would then be able to crack these passwords and get file access.

However, PHP includes an amazing function called str_replace(), which takes three arguments: The value to replace, what to replace it with, and what string we’re dealing with. Naturally, we can remove all the ‘up directory’ symbols as follows:

   <?php
   $file = str_replace('../', '', $_GET['file']);
   if(isset($file))
   {
       include("pages/$file");
   }
   else
   {
       include("index.php");
   }
   ?>

There is also the option to exclude the request altogether:

if (strpos($file,'../') !== false) {
    echo 'Invalid Request.';
}

The PHP parser only detects the given utf-8 value, so how about if we use hexadecimal as follows?

example.com/index.php?file=..%2F..%2F..%2F/etc/passwd

The following would avoid our current security plans because hexadecimal is not parsed when it meets the PHP script, but is parsed by the client’s browser.

The best way to avoid this exploit is to not use LFI unless you absolutely have to and it cannot be done any other way,
~!Donovan

Advertisements