2

Is it possible to read any file (not only those with the extension .html) from the server in the following script?

<?php
echo file_get_contents($_GET['display'].'.html');
?>

I know about wrappers (php://, file://, etc.) but achieved not too much.

I'm eager to hear all the possible vectors of attack.

The PHP configuration is default: allow_url_fopen On, and let's assume the version is >= 7.0, so null character %00 doesn't work.

Martin
  • 22,212
  • 11
  • 70
  • 132
terjanq
  • 301
  • 1
  • 3
  • 13
  • What is "display" variable? – Andreas Jan 27 '18 at 08:43
  • It's the variable attacker can control via GET request... `http://example.com/script.php?display=[something_evil]` – terjanq Jan 27 '18 at 08:45
  • I saw the comment that you do this to exploit. How? What is your plan? If you file_get_contents a PHP file you will not get the code, only the output of the PHP. – Andreas Jan 27 '18 at 08:52
  • So do you need to just access a file that you can't normally access, or do you need to be able to access an arbitrary file? – David A Jan 27 '18 at 08:52
  • If this is the duplicate then with it: https://stackoverflow.com/questions/12731547/can-an-appended-file-suffix-to-a-parameter-for-file-get-contents-be-bypassed But the post is from 2012, and the proposed vendor doesn't work anymore. @DavidA I'm wondering if I could for example read `/etc/passwd`, by trying something like: `php://filter/resource=file:///etc/passwd`, but the appended suffix is breaking the expression – terjanq Jan 27 '18 at 09:02
  • If the filename passed via $_GET contains a null byte, then yes, it is possible to exploit and access any file - [null byte injection](http://projects.webappsec.org/w/page/13246949/Null%20Byte%20Injection) - which bypasses the appended extension – Mark Baker Jan 27 '18 at 09:15
  • This doesn't even need null bytes to become a catastrophe quickly ... As you say, allow_url_fopen is on, so I can make your site make a request to any http(s) URL of my choosing, and have it output the response to the user of your site ... hello XSS old friend. And appending .html is not going to stop me from including any URL I like, even ones I don't have control over - easily countered by ending the URL I feed your script so that it becomes `...&needlessquerystringparameter=.html` or `.../evil.js#.html` – CBroe Jan 27 '18 at 10:14
  • That's exactly what my idea is about. But as long as *removing* .html suffix in ULR is quite easy, exactly as you have shown, exploiting `file_path` is a bigger challenge. `Null byte injection` doesn't work for recent php version. – terjanq Jan 27 '18 at 11:31

3 Answers3

1

No, that will only ever read files ending in '.html', but that doesn't necessarily mean that it's secure! Generally, the more that you can sanitise and restrict the input, the better.

Also, for anyone planning to use file_get_contents like this, it's always good to remember that when serving from file_get_contents, you can serve files that are not normally accessible - either due to server configuration, e.g. .htaccess, or file permissions.

David A
  • 415
  • 1
  • 4
  • 13
1

As @David said, this will only get files ending in '.html', but its not a good practice, if you have html folder and you want the user to get only files from that folder , you shouldn't do that, by using this method a hacker can access any .html file in your server, not just the ones you want him to see.

My suggestion is that if you have a specific folder that you want user to be able to get files from, scan the directory and check for the file name.

Here's an example:

<?php 

$paths = scandir('/html');

$file  = isset($_GET['display']) : $_GET['display'] ? null;

if(!$file) 
{
 die('no display provided');
}

$html = '';

foreach($paths as $path) {

   if($path !== '.' && $path !== '..' && $path === $file.'.html') {
     $html = file_get_contents($path);
   }
  
}


echo $html;

?>
Xiddoc
  • 3,369
  • 3
  • 11
  • 37
azjezz
  • 3,827
  • 1
  • 14
  • 35
0

Exploidale as proxy:

http://example.com/script.php?display=https://hackme.com/passwords%3Extension%3D

echo file_get_contents("https://hackme.com/passwords?Extension=.html")

Your IP will be logged on hackme.com machine and return some passwords (when lucky).