Skip to content
KitploitKITPLOIT
OutilsExploitsBlog
Log in
Soumettre
OutilsExploitsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

FluxContactConfidentialité© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
phpmyadmin-vqb-xss — phpMyAdmin 5.2.3 - Élevé - À distance - XSS - Designer Visual Query Builder | Kitploit
Outils/GitHubGitHub/abraxas/phpmyadmin-vqb-xss
Analyse des VulnérabilitésExploitationExploitation d'Applications WebSécurité WebTests d'IntrusionLabs et Pratique
GitHubabraxas/phpmyadmin-vqb-xss

phpmyadmin-vqb-xss

phpMyAdmin 5.2.3 - Élevé - À distance - XSS - Designer Visual Query Builder

Voir le dépôt
4il y a 9 joursPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Abraxas Labs - phpmyadmin-vqb-xss

abraxaslabs.tech  ·  github.com/abraxas  ·  @abraxas_null  ·  [email protected]  ·  phpmyadmin-vqb-xss

Write-up : https://abraxaslabs.tech/research/phpmyadmin-vqb-xss

phpmyadmin-vqb-xss

Classe : XSS stocké Portée : Distante

phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin

js/src/designer/history.js construit l'historique des requêtes visuelles avec innerHTML. Les noms de colonnes passent par $('<div/>').text(...).html(). Les noms de tables, non. TableName autorise toujours < et >. Un compte à faibles privilèges disposant de CREATE TABLE sur une base de données partagée plante un identifiant HTML. Lorsqu'un utilisateur à privilèges plus élevés ouvre le Designer, getTableName() se trouve sur la page et DesignerHistory.display() l'écrit dans #ab.

Un XSS stocké dans l'origine phpMyAdmin. Même classe que PMASA-2025-1, fonctionnalité différente. Les en-têtes de check-tables étaient échappés. Ce chemin ne l'était pas.

IDpas encore de CVE
ClasseXSS stocké
PortéeDistante (CREATE TABLE authentifié ; la victime ouvre le Designer)
CWECWE-79
CVSSÉlevé : 8.0 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N
ProduitphpMyAdmin
Affecté5.2.3 tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
Authauthentifié. L'attaquant a besoin de CREATE TABLE sur une base de données que la victime ouvre dans le Designer
LicenceGNU Affero GPL v3.0
Lab127.0.0.1 uniquement

Ce qu'un attaquant peut faire

Plante un nom de table HTML, puis attend qu'un utilisateur à privilèges plus élevés ouvre le Designer sur cette base de données et affiche l'historique des requêtes visuelles.

PrivilègeMéthode / sinkReconnaissance / intégrité / disponibilitéProuvé en lab ou déduit
Injecter du balisage dans l'origine phpMyAdminDesignerHistory.display() concatène getTab() dans le innerHTML de #abIntégrité de l'origine de la victimeProuvé en lab. history.js en production sur phpmyadmin:5.2.3. <h3> contenait <i id="pma-vqb">
S'échapper d'un attribut table_name du designerdatabase_tables.twig small_tab_pref_1 utilise designerTable.getTableName()Reconnaissance du nom MySQL brut dans le DOM du DesignerProuvé en lab, lisible comme identifiant brut
Lire le cookie de session de la victime et le token CSRFScript de même origine une fois l'historique affichéReconnaissance de la session PMA de la victimeDéduit du XSS stocké dans l'origine PMA. Ce lab utilise un marqueur <i>, pas un script
Exécuter du SQL, gérer les utilisateurs, exporter, en tant que compte MySQL de la victimePOST /sql, /server/privileges, export avec tokenIntégrité de tout ce que ce compte MySQL peut toucherDéduit. Même classe d'impact que PMASA-2025-1
Modifier la 2FA / userconfigPOST /config/set en tant que la victimeIntégrité du magasin de préférences de la victimeDéduit. Reliquat connexe, pas ce lab

Écarté sur ce reliquat : accès non authentifié, RCE OS, et le chemin du bouton OK du VQB. .small_tab_pref_click_opt pré-échappe table_name et Twig l'échappe automatiquement à nouveau, donc ce clic alimente actuellement getTab() en entités. Ce n'est pas un correctif de history.js. Les cellules de colonnes restent échappées en texte (c<b id=pma-col>y, pas de nœud <b id="pma-col">).

Même version épinglée : reliquat WebAuthn CustomServer.

Comment je l'ai trouvé

J'ai épinglé phpMyAdmin RELEASE_5_2_3. PMASA-2025-1/2/3 sont déjà dans 5.2.2. Le Designer construit toujours l'historique VQB en HTML à la main.

js/src/designer/history.js (livré sous js/dist/designer/history.js) :

temp = historyArray[i].getTab();
str += '<h3 class="tiger"><a href="#">' + temp + '</a></h3>';
// ...
'<td width="175" style="padding-left: 5px">' + $('<div/>').text(historyArray[i].getColumnName()).html() + '<td>';

libraries/classes/Dbal/TableName.php vérifie uniquement que la valeur n'est pas vide, qu'elle fait au maximum 64 caractères et qu'elle n'a pas d'espace final. < et > sont légaux. MySQL les accepte dans un identifiant entre guillemets.

templates/database/designer/database_tables.twig copie designerTable.getTableName() dans table_name sur .small_tab_pref_1. La cellule d'option du VQB utilise une copie pré-échappée du même nom.

Fausses pistes déjà consignées : traiter l'attribut doublement échappé du bouton d'option comme le correctif (ce n'est pas le cas - small_tab_pref_1 expose toujours le nom brut, et history.js est le point de sink) ; considérer que le helper de colonne couvre les noms de table ; affirmer une XSS non authentifiée ; un reverse shell. Du théâtre.

Lab

python3 phpmyadmin-vqb-xss-Abraxas-Labs.py
# or: cd lab && ./run.sh

Ciblez uniquement http://127.0.0.1:19250. Images phpmyadmin:5.2.3 et mysql:8.0. Projet Compose phpmyadmin-vqb-xss. Playwright Chromium dans le service poc. La stack est démontée après l'exécution.

Deux utilisateurs, shareddb partagée. L'utilisateur à faibles privilèges creator exécute CREATE TABLE \tx` (`cy` INT). L'utilisateur à privilèges élevés victimse connecte à phpMyAdmin et ouvre Designer avecquery=1. Le fichier history.js actif est la copie issue du conteneur (h3-unescaped=yes, helper de colonne présent). Chromium appelle DesignerHistory.display()avec le nom de table issu degetTableName()` sur la page.

Résultat : le innerHTML de #ab h3.tiger est <a href="#">t<i id="pma-vqb">x</i></a>. Le texte de la td de colonne est c<b id=pma-col>y sans nœud b#pma-col.

SUCCESS phpmyadmin-vqb-xss h3-markup=yes col-escaped=yes how=live PMA-VQB-XSS-WITNESS

Le correctif

Échappez getTab() avec $('<div/>').text(temp).html() ou Functions.escapeHtml avant de concaténer dans le <h3>. Ne comptez pas sur le double encodage Twig d'un seul attribut. Conservez l'assistant de nom de colonne comme modèle.

Références

  • github.com/phpmyadmin/phpmyadmin tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
  • js/src/designer/history.js
  • libraries/classes/Dbal/TableName.php
  • Correctif voisin (pas ce chemin) : PMASA-2025-1 Check-tables headings
  • Même pin : PMA-5.2.3-WebAuthn-2FA
  • CWE-79

Licence

Télécharger l’outil