
phpMyAdmin 5.2.3 – Hoch – Remote – verbleibend – isSuperUser-Prüfung übersprungen
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-issuperuser
Write-up: https://abraxaslabs.tech/research/phpmyadmin-issuperuser
Klasse: Privilegien-Rest Reichweite: Remote
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
DatabaseInterface::isSuperUser() ist keine SUPER-/SYSTEM_USER-Prüfung. Es ist SELECT 1 FROM mysql.user LIMIT 1. Jedes Konto, das mysql.user lesen kann, wird für den Rest der Sitzung als Superuser zwischengespeichert. $cfg['AllowUserDropDatabase'] ist standardmäßig auf false gesetzt. DestroyController, SqlController, ImportController und die Datenbankseite nehmen alle die isSuperUser-Abkürzung um dieses Flag herum.
Eine Umgehung der phpMyAdmin-Richtlinie, kein neues MySQL-Privileg. SELECT auf mysql.user plus DROP und kein SUPER reicht aus, um über PMA zu droppen.
| ID | noch keine CVE |
| Klasse | Privilegien-Rest |
| Reichweite | Remote (authentifizierter Cookie-Login als MySQL-Konto) |
| CWE | CWE-863 |
| CVSS | Mittel: 6.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L |
| Produkt | phpMyAdmin |
| Betroffen | 5.2.3 Tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| Auth | authentifizierter Cookie-Login als MySQL-Konto |
| Lizenz | GNU Affero GPL v3.0 |
| Lab | nur 127.0.0.1 |
Ein angemeldetes MySQL-Konto, das mysql.user lesen kann (typisches Backup-/Monitoring-SELECT) plus DROP, ohne SUPER, wird als phpMyAdmin-Superuser behandelt.
| Privileg | Methode / Sink | Recon / Integrität / Verfügbarkeit | Im Lab nachgewiesen oder abgeleitet |
|---|---|---|---|
Umgehung von $cfg['AllowUserDropDatabase']=false und Anzeige von Drop auf der Datenbankseite | GET index.php?route=/server/databases | Recon der Drop-UI | Im Lab nachgewiesen. bulkActionDropButton / selected_dbs[] vorhanden für selectuser; fehlend für plaindrop |
| Löschen einer Datenbank über den PMA-Destroy-Handler | POST index.php?route=/server/databases/destroy selected_dbs[]=dropme ajax_request=true | Integrität / Verfügbarkeit dieser Datenbank | Im Lab nachgewiesen. JSON success:true, "1 database has been dropped successfully." dropme weg |
Ausführen von DROP DATABASE aus der SQL-Box | POST index.php?route=/sql sql_query=DROP DATABASE \dropme_sql`` | Integrität / Verfügbarkeit dieser Datenbank | Im Lab nachgewiesen. Datenbank weg. Negativkonto erhält "DROP DATABASE statements are disabled." |
Freischalten anderer PMA-Bildschirme, die auf isSuperUser() beschränkt sind | Privileges, replication, status, user groups, engines, binlog, variables | Recon / Integrität dieser Bildschirme | Abgeleitet aus den Aufrufstellen. Nicht ausgeführt |
Lesen von mysql.user | MySQL-SELECT, das PMA als SUPER-Orakel verwendet | Recon des Katalogs, den PMA fälschlich für SUPER hält | Im Lab nachgewiesen. Diese Berechtigung ist es, die der Rest fälschlich für SUPER hält |
In diesem Lab ausgeschlossen: echtes MySQL-SUPER (SHOW GRANTS bleibt USAGE + Tabellen-DROP + SELECT auf mysql.user). FILE, GRANT OPTION, Shutdown und ALL PRIVILEGES werden nicht gewährt. Ein Konto mit DROP, aber ohne SELECT auf mysql.user, kann über PMA weiterhin nicht droppen. Dies ist kein neues MySQL-Privileg und kein RCE.
Gleicher Pin: WebAuthn CustomServer leftover.
I habe phpMyAdmin RELEASE_5_2_3 gepinnt. Privilegien-Gates, die wie SUPER klingen sollten, sollten wie SUPER aussehen. Dieses hier sieht wie ein Katalog-SELECT aus:
$result = $this->tryQuery('SELECT 1 FROM mysql.user LIMIT 1');
$isSuperUser = false;
if ($result) {
$isSuperUser = (bool) $result->numRows();
}
SessionCache::set('is_superuser', $isSuperUser);
Gates, die dieses Flag im Zusammenhang mit AllowUserDropDatabase (Standard false) verwenden:
Controllers/Server/DatabasesController.php is_drop_allowedControllers/Server/Databases/DestroyController.php (AJAX destroy)Controllers/Sql/SqlController.php / Sql::hasNoRightsToDropDatabaseControllers/Import/ImportController.phpControllers/Database/OperationsController.phpBereits dokumentierte Fehlwege: echtes MySQL SUPER zu behaupten; ein Konto, das nur DROP darf, als den Bug zu behandeln (dieses Konto ist die Negativkontrolle); dies zu RCE aufzublähen; eine Reverse Shell. Theater.
python3 phpmyadmin-issuperuser-Abraxas-Labs.py
# or: cd lab && ./run.sh
Ziel nur http://127.0.0.1:19270. Images phpmyadmin:5.2.3 und mysql:8.0. Compose-Projekt phpmyadmin-issuperuser. $cfg['AllowUserDropDatabase']=false. Der Stack wird nach dem Lauf abgebaut.
selectuser hat SELECT auf mysql.user sowie DROP auf dropme / dropme_sql, kein SUPER. plaindrop hat nur DROP auf nodropme. Die Datenbanken-Seite zeigt Drop für selectuser an. POST /server/databases/destroy löscht dropme. POST /sql mit DROP DATABASE dropme_sql wird ebenfalls ausgeführt. plaindrop erhielt weiterhin das Error-JSON von destroy und „DROP DATABASE statements are disabled“ von /sql.
SUCCESS phpmyadmin-issuperuser drop-ui=yes destroy=ok sql-drop=ok grants-no-super=yes mysql.user-select=yes neg-drop-ui=no neg-destroy=denied PMA-ISSUPERUSER-WITNESS
Teste echtes SUPER / SYSTEM_USER über INFORMATION_SCHEMA oder SHOW GRANTS. Behalte ein separates Flag „kann mysql.user lesen“ für die UI bei, die diesen Katalog tatsächlich benötigt. Cache kein Katalog-SELECT als Superuser.
962857e4f63d42e38f11ff4d63f5e722018add76)libraries/classes/DatabaseInterface.php isSuperUser()GNU Affero GPL v3.0. Siehe LICENSE. Nur Loopback-Lab. Keine Gewährleistung.