
phpMyAdmin 5.2.3 - Élevée - À distance - résiduel - vérification isSuperUser ignorée
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-issuperuser
Classe : Résidu de privilège Portée : Distante
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
DatabaseInterface::isSuperUser() n'est pas une vérification SUPER / SYSTEM_USER. C'est SELECT 1 FROM mysql.user LIMIT 1. Tout compte capable de lire mysql.user est mis en cache comme superutilisateur pour le reste de la session. $cfg['AllowUserDropDatabase'] vaut false par défaut. DestroyController, SqlController, ImportController et la page des bases de données empruntent tous le raccourci isSuperUser autour de ce drapeau.
Un contournement de politique phpMyAdmin, pas un nouveau privilège MySQL. SELECT sur mysql.user plus DROP, et pas de SUPER, suffit pour Drop via PMA.
| ID | pas encore de CVE |
| Classe | Résidu de privilège |
| Portée | Distante (connexion authentifiée par cookie en tant que compte MySQL) |
| CWE | CWE-863 |
| CVSS | Moyen : 6.3 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:L/A:L |
| Produit | phpMyAdmin |
| Affecté | 5.2.3 tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| Auth | connexion authentifiée par cookie en tant que compte MySQL |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
Un compte MySQL connecté capable de lire mysql.user (typiquement un SELECT de sauvegarde/surveillance) plus DROP, sans SUPER, est traité comme un superutilisateur phpMyAdmin.
| Privilège | Méthode / sink | Reconnaissance / intégrité / disponibilité | Prouvé en lab ou déduit |
|---|---|---|---|
Contourner $cfg['AllowUserDropDatabase']=false et voir Drop sur la page des bases de données | GET index.php?route=/server/databases | Reconnaissance de l'interface Drop | Prouvé en lab. bulkActionDropButton / selected_dbs[] présents pour selectuser ; absents pour plaindrop |
| Supprimer une base de données via le gestionnaire destroy de PMA | POST index.php?route=/server/databases/destroy selected_dbs[]=dropme ajax_request=true | Intégrité / disponibilité de cette base de données | Prouvé en lab. JSON success:true, « 1 database has been dropped successfully. » dropme disparue |
Exécuter DROP DATABASE depuis la zone SQL | POST index.php?route=/sql sql_query=DROP DATABASE \dropme_sql`` | Intégrité / disponibilité de cette base de données | Prouvé en lab. Base de données disparue. Le compte négatif reçoit « DROP DATABASE statements are disabled. » |
Déverrouiller d'autres écrans PMA conditionnés par isSuperUser() | Privilèges, réplication, statut, groupes d'utilisateurs, moteurs, binlog, variables | Reconnaissance / intégrité de ces écrans | Déduit des sites d'appel. Non exercé |
Lire mysql.user | SELECT MySQL que PMA utilise comme oracle SUPER | Reconnaissance du catalogue que PMA confond avec SUPER | Prouvé en lab. Ce grant est ce que le résidu confond avec SUPER |
Fermé sur ce lab : vrai SUPER MySQL (SHOW GRANTS reste USAGE + DROP de table + SELECT sur mysql.user). FILE, GRANT OPTION, shutdown et ALL PRIVILEGES ne sont pas accordés. Un compte avec DROP mais sans SELECT sur mysql.user ne peut toujours pas supprimer via PMA. Ce n'est pas un nouveau privilège MySQL et pas une RCE.
Même pin : WebAuthn CustomServer leftover.
J'ai épinglé phpMyAdmin RELEASE_5_2_3. Les barrières de privilèges qui parlent comme SUPER devraient ressembler à SUPER. Celle-ci ressemble à un SELECT de catalogue :
$result = $this->tryQuery('SELECT 1 FROM mysql.user LIMIT 1');
$isSuperUser = false;
if ($result) {
$isSuperUser = (bool) $result->numRows();
}
SessionCache::set('is_superuser', $isSuperUser);
Barrières qui prennent ce drapeau autour de AllowUserDropDatabase (false par défaut) :
Controllers/Server/DatabasesController.php is_drop_allowedControllers/Server/Databases/DestroyController.php (destroy AJAX)Controllers/Sql/SqlController.php / Sql::hasNoRightsToDropDatabaseControllers/Import/ImportController.phpControllers/Database/OperationsController.phpFausses pistes déjà consignées : prétendre à un vrai SUPER MySQL ; traiter un compte DROP-only comme le bug (ce compte est le contrôle négatif) ; gonfler cela en RCE ; un reverse shell. Du théâtre.
python3 phpmyadmin-issuperuser-Abraxas-Labs.py
# or: cd lab && ./run.sh
Cible uniquement http://127.0.0.1:19270. Images phpmyadmin:5.2.3 et mysql:8.0. Projet Compose phpmyadmin-issuperuser. $cfg['AllowUserDropDatabase']=false. La stack est démontée après l'exécution.
selectuser a SELECT sur mysql.user plus DROP sur dropme / dropme_sql, pas de SUPER. plaindrop a DROP sur nodropme uniquement. La page des bases de données affiche Drop pour selectuser. POST /server/databases/destroy supprime dropme. POST /sql avec DROP DATABASE dropme_sql s'exécute aussi. plaindrop a toujours reçu le JSON Error de destroy et « DROP DATABASE statements are disabled » de /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
Tester le vrai SUPER / SYSTEM_USER via INFORMATION_SCHEMA ou SHOW GRANTS. Conserver un drapeau séparé « peut lire mysql.user » pour l'interface qui a réellement besoin de ce catalogue. Ne pas mettre en cache un SELECT de catalogue comme superutilisateur.
962857e4f63d42e38f11ff4d63f5e722018add76)libraries/classes/DatabaseInterface.php isSuperUser()GNU Affero GPL v3.0. Voir LICENSE. Lab en boucle locale uniquement. Aucune garantie.