I was playing on an HTB machine when I discovered this bug. There is not that much information available out there on the internet on this bug. I am always how the box/machine was created, and how the creators configured everything, what packages they needed, what are the requirements for each package. I check out everything, If I have an ssh shell of root because I just don’t like a fake PTY shell. If I am logged in a box as root with SSH, I will check all the files used by creators. I start it by checking web configurations and files used in the web server  (generally in `/var/www/`)

I was doing the same thing this time (can’t reveal the box name since it is not retired) but I saw something unusual in those files. I know a little bit of PHP but I’m not any pro. So, like any other noob person, I went to php.net and I found that there is something really dangerous about this function.

The function was `extract` and it was controlled by the user ($_POST as the argument). so, before you we go more about extract, we need to understand what $_POST is.

An associative array of variables passed to the current script via the HTTP POST method when using application/x-www-form-urlencoded or multipart/form-data as the HTTP Content-Type in the request.

In easy words, it is a global array which contains all the data sent by the user in a POST request.

We can understand this by following the example script which is intentionally hosted on the PHP server:

#index.php
<?php
if($_SERVER['REQUEST_METHOD'] === "POST"){
  $o = $_POST['cmd'];
  echo "[+] Command recvd: ".$o;
}
?>

Now if I request the server (created with php -S 0.0.0.0:90) with the `cmd` POST parameter, I will receive the following result.

now we need to understand what does this `extract()` function does. I found this short explanation on php.net

extract — Import variables into the current symbol table from an array

and there is a warning right behind its explanation
Warning: Do not use extract() on untrusted data, like user input (e.g. $_GET, $_FILES).
that’s what made me think how dangerous this could be if I do so. In order to check it, I wrote this PHP script:
#index.php
<?php
$filename = "/root/flag.txt";
if($_SERVER['REQUEST_METHOD'] === "POST"){
  extract($_POST);
  echo '--------------------------';
  echo readfile($filename);
  echo '--------------------------';
}
?>

In the code above, you can see that there is a variable `$filename` and it is accepting a POST request. and if the request method is POST, it is executing the extract method with the argument $_POST which is an array containing the variables (names provided by the user) and their values.

$_POST[$filename => ''/etc/hosts', $magic => 'aabra_ka_daabra']

But when the PHP executes the `extract()`, it will create a variable out of the array ($_POST) which could be dangerous if the `extract()` overwrites the already existing variable and in our case, it does such thing.

It read the file save on `/root` when we didn’t send any malicious POST requests. now let’s just send it some POST request with filename a parameter (filename=/etc/passwd).

It should be pretty clear to you that you won’t use this function on user-controllable arrays like $GET, $_POST, $_FILE etc. and if you do, check your code if it can cause some attacker to read or execute code on your system.

 

1 COMMENT

LEAVE A REPLY

Please enter your comment!
Please enter your name here