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
#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.
I just discovered your website, you’re a beast! Thanks for sharing this