Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

FeedsContactoPrivacidad© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
phpmyadmin-vqb-xss — phpMyAdmin 5.2.3 - Alta - Remota - XSS - Generador de consultas visuales Designer | Kitploit
Herramientas/GitHubGitHub/abraxas/phpmyadmin-vqb-xss
Análisis de VulnerabilidadesExplotaciónExplotación de Aplicaciones WebSeguridad WebPruebas de PenetraciónLabs y Práctica
GitHubabraxas/phpmyadmin-vqb-xss

phpmyadmin-vqb-xss

phpMyAdmin 5.2.3 - Alta - Remota - XSS - Generador de consultas visuales Designer

Ver Repositorio
3hace 8 díasAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir

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

Clase: XSS almacenado Alcance: Remoto

phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin

js/src/designer/history.js construye el historial de consultas visuales con innerHTML. Los nombres de columna pasan por $('<div/>').text(...).html(). Los nombres de tabla no. TableName todavía permite < y >. Una cuenta con pocos privilegios con CREATE TABLE sobre una base de datos compartida planta un identificador HTML. Cuando un usuario con más privilegios abre el Designer, getTableName() está en la página y DesignerHistory.display() lo escribe en #ab.

Un XSS almacenado en el origen de phpMyAdmin. Misma clase que PMASA-2025-1, funcionalidad distinta. Los encabezados de check-tables estaban escapados. Esta ruta no lo estaba.

IDaún sin CVE
ClaseXSS almacenado
AlcanceRemoto (CREATE TABLE autenticado; la víctima abre el Designer)
CWECWE-79
CVSSAlto: 8.0 CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:U/C:H/I:H/A:N
ProductophpMyAdmin
Afectado5.2.3 tag RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
Autenticaciónautenticado. El atacante necesita CREATE TABLE sobre una base de datos que la víctima abra en el Designer
LicenciaGNU Affero GPL v3.0
Laboratoriosolo 127.0.0.1

Qué puede hacer un atacante

Plantar un nombre de tabla HTML y luego esperar a que un usuario con más privilegios abra el Designer sobre esa base de datos y renderice el historial de consultas visuales.

PrivilegioMétodo / sinkReconocimiento / integridad / disponibilidadProbado en laboratorio o inferido
Inyectar marcado en el origen de phpMyAdminDesignerHistory.display() concatena getTab() en el innerHTML de #abIntegridad del origen de la víctimaProbado en laboratorio. history.js en vivo sobre phpmyadmin:5.2.3. <h3> contenía <i id="pma-vqb">
Escaparse de un atributo table_name del designerdatabase_tables.twig small_tab_pref_1 usa designerTable.getTableName()Reconocimiento del nombre MySQL en bruto en el DOM del DesignerProbado en laboratorio, legible como el identificador en bruto
Leer la cookie de sesión de la víctima y el token CSRFScript del mismo origen una vez que se renderiza el historialReconocimiento de la sesión PMA de la víctimaInferido a partir del XSS almacenado en el origen de PMA. Este laboratorio usa un marcador <i>, no un script
Ejecutar SQL, gestionar usuarios, exportar, como la cuenta MySQL de la víctimaPOST respaldado por token a /sql, /server/privileges, exportIntegridad de todo lo que esa cuenta MySQL pueda tocarInferido. Misma clase de impacto que PMASA-2025-1
Cambiar 2FA / userconfigPOST a /config/set como la víctimaIntegridad del almacén de preferencias de la víctimaInferido. Resto hermano, no este laboratorio

Descartado en este resto: acceso no autenticado, RCE del SO y la ruta del botón OK del VQB. .small_tab_pref_click_opt pre-escapa table_name y Twig lo autoescapa de nuevo, así que ese clic actualmente alimenta entidades a getTab(). Eso no es una corrección de history.js. Las celdas de columna siguen escapadas como texto (c<b id=pma-col>y, sin nodo <b id="pma-col">).

Mismo pin: resto de WebAuthn CustomServer.

Cómo lo encontré

Fijé phpMyAdmin RELEASE_5_2_3. PMASA-2025-1/2/3 ya están en 5.2.2. El Designer sigue construyendo el HTML del historial del VQB a mano.

js/src/designer/history.js (distribuido como 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 solo comprueba que no esté vacío, máximo 64, sin espacio final. < y > son legales. MySQL los acepta en un identificador entre comillas.

templates/database/designer/database_tables.twig copia designerTable.getTableName() en table_name sobre .small_tab_pref_1. La celda de opción de VQB usa una copia preescapada del mismo nombre.

Falsos caminos ya registrados: tratar el atributo del botón de opción con doble escape como la solución (no lo es - small_tab_pref_1 sigue exponiendo el nombre sin procesar, y history.js es el sink); tratar el helper de columna como si cubriera los nombres de tabla; afirmar XSS no autenticado; una reverse shell. Teatro.

Laboratorio

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

Dirígete solo a http://127.0.0.1:19250. Imágenes phpmyadmin:5.2.3 y mysql:8.0. Proyecto de Compose phpmyadmin-vqb-xss. Playwright Chromium en el servicio poc. El stack se desmonta tras la ejecución.

Dos usuarios, shareddb compartida. El usuario de bajos privilegios creator ejecuta CREATE TABLE \tx` (`cy` INT). El usuario de mayores privilegios victiminicia sesión en phpMyAdmin y abre Designer conquery=1. El history.js en vivo es la copia del contenedor (h3-unescaped=yes, el helper de columna presente). Chromium llama a DesignerHistory.display()con el nombre de tabla degetTableName()` en la página.

Resultado: el innerHTML de #ab h3.tiger es <a href="#">t<i id="pma-vqb">x</i></a>. El texto del td de la columna es c<b id=pma-col>y sin ningún nodo b#pma-col.

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

La solución

Escapa getTab() con $('<div/>').text(temp).html() o Functions.escapeHtml antes de concatenar en el <h3>. No confíes en la doble codificación de Twig de un atributo. Mantén el helper de nombre de columna como el modelo.

Referencias

  • github.com/phpmyadmin/phpmyadmin etiqueta RELEASE_5_2_3 (962857e4f63d42e38f11ff4d63f5e722018add76)
  • js/src/designer/history.js
  • libraries/classes/Dbal/TableName.php
  • Parcheado cercano (no esta ruta): encabezados de Check-tables de PMASA-2025-1
  • Mismo pin: PMA-5.2.3-WebAuthn-2FA
  • CWE-79

Licencia

GNU Affero GPL v3.0. Consulta LICENSE. Solo para laboratorio de loopback. Sin garantía.

Descargar herramienta