HTB Business CTF 2021 — Time

Hack The Box (HTB) hosted its very first “corporate only” CTF this past weekend which is called HTB Business CTF 2021.

Hackthebox Business CTF 2021

My friend invited me to join their team. So without further ado, let's get into it.

Challenge: Time

Category: Web

Get the current date and time, anytime, anywhere!

I notice that it changed when I click the What’s the date? menu.

Since it's a web challenge, I thought of a possible code injection vulnerability.

They provided a source code:

├── challenge
│ ├── assets
│ │ └── favicon.png
│ ├── controllers
│ │ └── TimeController.php
│ ├── index.php
│ ├── models
│ │ └── TimeModel.php
│ ├── Router.php
│ ├── static
│ │ └── main.css
│ └── views
│ └── index.php
├── config
│ ├── fpm.conf
│ ├── nginx.conf
│ └── supervisord.conf
├── Dockerfile
└── flag

First, I checked the directory structure, so it's MVC since we have controller, model, and views folders.

Second, I checked the Dockerfile and build it inside my machine, and examine what is the docker image, command used and where’s the flag located.

FROM debian:buster-slim

# Setup user
RUN useradd www

# Install system packeges
RUN apt-get update && apt-get install -y supervisor nginx lsb-release wget

# Add repos
RUN wget -O /etc/apt/trusted.gpg.d/php.gpg
RUN echo "deb $(lsb_release -sc) main" | tee /etc/apt/sources.list.d/php.list

# Install PHP dependencies
RUN apt update && apt install -y php7.4-fpm

# Configure php-fpm and nginx
COPY config/fpm.conf /etc/php/7.4/fpm/php-fpm.conf
COPY config/supervisord.conf /etc/supervisord.conf
COPY config/nginx.conf /etc/nginx/nginx.conf

# Copy challenge files
COPY challenge /www

# Setup permissions
RUN chown -R www:www /www /var/lib/nginx

# Copy flag
COPY flag /flag

# Expose the port nginx is listening on

# Populate database and start supervisord
CMD /usr/bin/supervisord -c /etc/supervisord.conf

I found that the flag is located in /flag path, but they provided a sample flag inside their source code:

Next is I checked controllers/TimeController.php

class TimeController
public function index($router)
$format = isset($_GET['format']) ? $_GET['format'] : '%H:%M:%S';
$time = new TimeModel($format);
return $router->view('index', ['time' => $time->getTime()]);

This indicated that the Controller called/created the object TimeModel, so I checked the models/TimeModel.php

class TimeModel
public function __construct($format)
$this->command = "date '+" . $format . "' 2>&1";

public function getTime()
$time = exec($this->command);
$res = isset($time) ? $time : '?';
return $res;

I found $this->command = “date ‘+” . $format . “‘ 2>&1”;

This means that we need to inject command (command injection vulnerability)

We can break out the string by adding a single quote (‘) and add a semi-colon(;)

I make an easy request using Burpsuite:

/?format='; cat ' ../flag 

Gotcha, I found a flag!!!

Co-Founder of Kalasag and Project Access Granted Society. A Certified Ethical Hacker,EC-Council Certified Incident Handler and Certified Blockchain Developer.