
phpMyAdmin 5.2.3 – Hoch – Remote – verbleibend – setup/validate weiterhin erreichbar
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-setup-validate
Klasse: SSRF Reichweite: Remote
phpMyAdmin 5.2.3 (Tag RELEASE_5_2_3, Commit 962857e). setup/index.php bricht ab, wenn config.inc.php vorhanden ist. setup/validate.php nicht. Es lädt weiterhin unter $isMinimumCommon, holt sich ein CSRF-Token von der öffentlichen Login-Seite und ruft Validator::testDBConnection -> mysqli_connect mit Host, Port, Benutzer und Passwort aus dem JSON-Feld values auf.
Ein nicht authentifizierter Client ruft GET / auf, um ein Session-Cookie und Token zu erhalten, und sendet dann POST setup/validate.php id=Server mit selbst gewähltem Servers/1/host und Servers/1/port. Der phpMyAdmin-Host öffnet einen TCP-MySQL-Handshake zu dieser Adresse. Das ist SSRF über das MySQL-Protokoll: internes 3306, Credential Stuffing gegen einen internen Server, ein Port-Orakel aus Timing und mysqli-Fehlern. Es ist kein HTTP-Metadata-SSRF, es sei denn, etwas auf diesem Port spricht MySQL. hide_db interpoliert außerdem einen Benutzer-Regex in preg_match. Ich habe diesen ReDoS-Pfad in diesem Lab nicht ausgeführt.
Das offizielle phpmyadmin:5.2.3-Image löscht setup/. Dieser Überrest gilt nur, wenn dieses Verzeichnis noch im Web-Root liegt, was der übliche Überrest nach einer Installation ist. Das Lab stellt setup/ aus dem 5.2.3-Tarball wieder her, damit die Version zu RELEASE_5_2_3 passt.
PMASA-2016-44 / CVE-2016-6621 deckte einige Setup-SSRF ab. Die Prüfung „Setup deaktivieren, wenn Konfiguration existiert" wurde nie auf validate.php / config.php angewendet.
| ID | noch keine CVE |
| Klasse | SSRF (MySQL-Protokoll) |
| Reichweite | Remote (nicht authentifiziert, wenn setup/ noch über das Web erreichbar ist) |
| CWE | CWE-918 |
| CVSS | Hoch: 7.2 CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:L/I:L/A:N |
| Produkt | phpMyAdmin |
| Betroffen | 5.2.3 Tag RELEASE_5_2_3 (962857e) mit setup/ noch im Docroot |
| Auth | Nicht authentifiziert. CSRF-Token von der öffentlichen Login-Seite. Kein MySQL-Login. |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1:19230 |
Jeder, der einen zurückgebliebenen setup/-Baum erreichen kann, kann den phpMyAdmin-Host dazu bringen, eine TCP-Verbindung mit MySQL-Protokoll zu einem Host und Port seiner Wahl zu öffnen.
| Privileg | Methode / Pfad | Im Lab bewiesen oder abgeleitet |
|---|---|---|
| TCP vom PMA-Host zu Angreifer-Host:Port öffnen (Integrität des ausgehenden Verbindungsaufbaus; Recon dieses Ports) | Nicht authentifiziertes POST /setup/validate.php id=Server mit Servers/1/host + Servers/1/port plus einem Token aus GET / | Im Lab bewiesen. Orakel auf oracle:13306 protokollierte PMA-SETUP-VALIDATE-WITNESS vom PMA-Container |
| Bestätigen, dass die Setup-UI aus ist, während validate an bleibt | GET /setup/index.php | Im Lab bewiesen. Body enthält „setup is disabled" / configuration already exists |
| Fail closed ohne das CSRF-Token der Login-Seite | Derselbe POST, ohne token | Im Lab bewiesen. Null Orakel-Treffer |
| Port-/Credential-Orakel aus mysqli-Fehlern und Timing | Derselbe testDBConnection | Abgeleitet. Lab-Body war mysqli_connect(): (HY000/2006): MySQL server has gone away, nachdem das Orakel akzeptiert und dann geschlossen hatte |
| MySQL mit einem internen 3306 sprechen und übermittelten Benutzer/Passwort versuchen | Derselbe mysqli_connect | Abgeleitet. Nicht auf den Lab-db-Dienst gerichtet |
ReDoS über validateRegex, das Benutzer-Regex interpoliert | id=Servers/1/hide_db | Abgeleitet. Nicht ausgeführt |
In diesem Lab ausgeschlossen: HTTP-Metadata-SSRF (der Handshake ist MySQL, nicht GET /latest/meta-data), nicht authentifizierter PMA-Login, OS-Shell und der Setup-Wizard selbst (index.php bleibt deaktiviert). FAIL, wenn setup/ nicht bereitgestellt ist (Standard des offiziellen Images).
Acht parallele Quellcode-Suchen in RELEASE_5_2_3. setup/index.php hat den Fatal bei vorhandener Konfiguration. setup/validate.php nicht. setup/lib/common.inc.php setzt $isMinimumCommon und sucht nicht nach CONFIG_FILE.
Irrwege: das offizielle Image als diesen Überrest behandeln (es löscht setup/); POSTen ohne das Token der Login-Seite (null Orakel-Treffer); dies als HTTP-Metadata-SSRF behandeln (der Handshake ist MySQL).
python3 phpmyadmin-setup-validate-Abraxas-Labs.py
oder
cd lab
./run.sh
Nur Loopback: http://127.0.0.1:19230. Compose-Projekt phpmyadmin-setup-validate. Das Dockerfile stellt setup/ aus dem 5.2.3-Tarball wieder her und betreibt ein TCP-Orakel auf Port 13306. Witness PMA-SETUP-VALIDATE-WITNESS.
SUCCESS phpmyadmin-setup-validate how=live tcp=yes setup-index-disabled=yes PMA-SETUP-VALIDATE-WITNESS
Den Fatal file_exists(CONFIG_FILE) in setup/lib/common.inc.php einbauen, damit jedes Setup-Skript abbricht. testDBConnection-Hosts einschränken. Keine preg_match-Delimiter aus Benutzer-Strings bauen.
962857e)setup/index.php Fatal bei vorhandener Konfigurationsetup/validate.php ohne diese Prüfunglibraries/classes/Config/Validator.php testDBConnection / mysqli_connectGNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.