Toxic | HackTheBox Web Challange

Bishal Ray -#GxbNt
5 min readJan 6, 2024

--

Toxic is a web challenge on HackTheBox. The author provides us with source code for this challenge, eliminating the need for enumeration.
It’s a one-page website with no functionality. So let’s jump directly to the source code and see what we have.

Examining The Source

The most important file seems to be index.php. Let’s analyze the code…

We can see that a cookie called PHPSESSID is being created using setcookie() in case it didn’t exist, the cookie’s value is being set to the base64 encoding of some serialized object called $page of type PageModel which has a property $file set to “/www/index.html”.
If the PHPSESSID cookie exists, its value is decoded using base64_decode() and then deserialized back to a PHP object value.

Let’s look at the PageModel class code to understand what’s happening.

We can see that when the unserialized object of type PageModel is getting destroyed, the file that the $file property points to (“/www/index.html” in this case) is included, which means that the content of index.html is being displayed in the browser and any PHP blocks contained within that file will be executed.
We know how index.html is being displayed when we visit the website. But wait a minute, notice that the name of the file being displayed (index.html here) is controlled by the user, since PHPSESSID’s value is controlled by the user. This is a Local File Inclusion vulnerability.

LFI vulnerability

We have to find the flag file and display its content. So let’s see how we can exploit this LFI vulnerability.

We can find the cookie by inspecting the webpage in the cookie section. Let’s decode the base64 encoded cookie value to get any lead.

The result is the serialized object of type PageModel set when the cookie was created.
To exploit LFI all we have to do is encode a new value for the cookie and change /www/index.html into the name of the file that we wish to display in the browser.

O:9:"PageModel":1:{s:4:"file";s:15:"/www/index.html";}

O:9:"PageModel":1:: This part indicates that the serialized data represents an object (O) of a class named "PageModel" with a class name length of 9 characters.

{s:4:"file";s:15:"/www/index.html";}: This part represents the properties of the object. It seems to have one property named "file" with a string value of "/www/index.html". Breaking it down:

s:4:"file": Indicates that the property name is "file", and it is a string with a length of 4 characters.

s:15:"/www/index.html";: Represents the value of the "file" property, which is a string with a length of 15 characters ("/www/index.html").

Let’s create a new PHPSESSID cookie with this newly encoded value to read a file /etc/passwd for a proof of concept.

I will be using Burp, we can also use the dev tool of the browser to change the cookie value.

We can get the content of the /etc/passwd file. So, it’s clear that It is vulnerable to LFI. To retrieve a flag, first, we have to locate the file containing the flag. To do this we need to escalate vulnerability from LFI to RCE.

LFI to RCE

The easiest way to find the flag file is to get RCE on the server rather than brute-forcing our way to it. The easiest way to get RCE from an LFI vulnerability is through log poisoning. Log poisoning is a technique used to execute code injected into a log file. But how are we going to inject code?? LFI allows us to read/execute a file on the server, not write one!!

To do this first we have to detect which web server is running to know which log file to poison and how to access it.

In the source code folder, there is a config folder. Inside it there is an nginx conf file, from it we are clear that it is running a nginx web server.

If the config file is not available, we can find the server by viewing the Response Headers from the dev tool. We can use Google to search the location of the Ngnix log file.

Let’s explore the Nginx log file …..

As we can see, the access.log file logs all accesses to files on the web server.
Now it’s time to poison that log file. Notice that the user-agent in the request crafted in burp is reflected in the access.log file, this might be a way to inject PHP code into the access.log file and have that code executed whenever the server includes (as stated earlier) that log file and send the content back to our browser.

Let’s try it does it work or not …

Boom! It worked. When we send the request with the crafted payload and analyze the response of the log file clearly, we can see that the directory inside the root is listed.

We can see a file called flag_XXXXX, those last 5 characters are random and thus they vary with each launched instance of this challenge on HackTheBox, that’s why brute-forcing the flag file name is inefficient.

To read a flag either we can use the LFI method using the PHPSESSID cookie or we can craft a payload and send the request to read a flag.

Got content of flag_7s9is !!!!!!!!!!!

--

--