6

Let's assume there is this code for including other php files from user input (yes, I know it's a bad choice):

$input = addslashes($_GET["input"]);

if (strpos($input, '../') === false) {
    include_once('/path/to/php/files/'.$input);
} else { echo('Invalid parameter!'); }

This code adds slashes to single and double quotes, and then check for ../ in the string, and if it does not find it, includes the file.

Assuming that the hacker has written some code to include to other folder, and the hacker needs to access that file with ?input=../../folder/extcode, can there be a vulnerabillity here?

3
  • 1
    Maybe LFI is still possible using base64, or url-encoding...
    – game0ver
    Nov 4, 2018 at 9:55
  • 1
    @MoonsikPark Are you sure that include_once("..\\..\\folder\\extcode") (what you get after addslashes) doesn't actually work on Windows? The Windows command line is kind enough to just collapse \\ into \, would not surprise me if PHP does the same. Unfortunately, I don't have a PHP installation on Windows to test this on.
    – Anders
    Nov 5, 2018 at 9:44
  • @Anders Neither do I. Think it will work though.
    – user186505
    Nov 5, 2018 at 14:00

3 Answers 3

5

This code is vulnerable to LFI when running on Windows systems, because those systems will accept a path containing a directory traversal which uses backslashes (like \..\..\).

2

What you are trying to block is a LFI, but I think you are still vulnerable. This kind of scenarios are usually potentially vulnerable to LFI and RFI.

It seems your code is not vulnerable to RFI because of the local path prefix. (Link to both LFI and RFI: https://en.wikipedia.org/wiki/File_inclusion_vulnerability).

Just for clarification, on RFI the attacker will try to include a remote file using a payload like http://evilsite/evil.php and as you can see it doesn't contain '../' on it. To be protected of this, you should configure on your php.ini the allow_url_include and be sure that it is off. Otherwise you could be be hacked using RFI depending of the input. So it's a good practice to set this off if not needed.

Talking about LFI I think your code is not safe. Ok you are blocking strings like '../' but maybe the attacker could encode it someway to bypass your protection. As @game0ver said in a comment, the attacker could use base64 or url-encoding and maybe more. Be careful!

So, summarizing. You are NOT vulnerable to RFI but, YES you are probably vulnerable to LFI.

11
  • 1
    How would an RFI work on OPs sample code? There's a local path prefix.
    – Arminius
    Nov 4, 2018 at 10:20
  • Oops, maybe you are right... I'll edit my answer just to talk about the risks of RFI... but I still think it could be vulnerable to LFI. Thanks for the hint. Nov 4, 2018 at 10:31
  • @OscarAkaElvis as you said, I think it's still exploitable through url/base64 encoding... I think it's worth testing. Also an RFI is unlikely to happen, but it's possible an attacker to use PHP wrapper functions and achieve RCE, rare but happens.
    – game0ver
    Nov 4, 2018 at 10:38
  • 4
    How would this be exploitable with base64 or URL encoding? For that to happend, there would need to be something in the include function that decodes, but to my knowledge there isn't.
    – Anders
    Nov 4, 2018 at 10:56
  • 1
    @game0ver No, because strpos also recieves the URL-decoded version. What's important here is that strpos and include see the same string. If it is vulnerable, what would an exploit look like?
    – Anders
    Nov 4, 2018 at 12:43
2

RFI and LFI

Unfortunately, this does not appear to be directly exploitable. As discussed elsewhere in comments, RFI is not possible because of the prefix, and LFI is not possible in linux because (I believe) there isn't any way to escape the strpos via encoding. PHP would automatically decode any URL encoded strings before placing it into the $_GET super variable, and any encoding that didn't trigger the strpos search also wouldn't register as a forward slash for the purposes of the include call (at least, I couldn't find any successful attack vectors). Keep duskwuff's answer in mind though - LFI is possible here on windows.

Alternate attacks

However, that doesn't mean that it can't help. In particular, open includes like this are the sort of vulnerability that let's you make a smaller vulnerability much bigger. The immediate thought that comes to mind is to check if this website has an image upload function anywhere. If so, and you know where the images are saved, you can try embedding valid PHP in the EXIF data of a jpg image which you then upload to the server. Normally such code is not exploitable, because you don't have anyway to run your PHP on the server. But, with an open include like this, you can upload your file and then use this weakness to run it (since the uploaded file will most likely exist inside /path/to/php/files the lack of a fully qualified LFI vulnerability won't matter). From there you can do whatever you want.

Using user-input to build an include path is almost always a bad idea, and is rarely necessary. Even if there isn't an immediate weakness, that doesn't mean it can't help you when exploiting other ones.

Better security

I think it's worth taking a minute to explain how something like this should be secured. It's hard to give an exact solution without more context, but usually something like this can be broken down into a more secure two-step process:

  1. Use realpath to let the system resolve all directory-traversal attempts and get a final absolute path
  2. Make sure that the final absolute path lives in a safe directory for you to include files from, or explicitly white-list against a list of safe includes

You never want to let the user include an arbitrary file. Figure out exactly what file is going to be included as a result of their user input, and filter that through a whitelist. That is the only way to do this securely.

You must log in to answer this question.