phpMyAdmin 5.2.3 - Alta - Remota - SQLi - Identificadores no saneados en Designer JSON
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-designer-json-sqli
Clase: SQLi Alcance: Remoto
phpMyAdmin 5.2.3 (tag RELEASE_5_2_3, commit 962857e). El AJAX del Designer save_setting_value aplica json_encode al blob de ajustes y lo concatena en un UPDATE/INSERT entre comillas simples sobre el enlace del usuario de control. El nombre de usuario se escapa. El JSON no. json_encode no escapa una comilla simple.
Un usuario autenticado envía por POST index.php?route=/database/designer con operation=save_setting_value y una comilla en value. queryAsControlUser ejecuta entonces esa cadena como el usuario de control de pma contra pma__designer_settings. Esa cuenta es el almacenamiento de configuración, no la caja SQL del usuario autenticado. phpMyAdmin 6.x envuelve este blob en quoteString sobre ControlUser. 5.2.3 todavía lo concatena en crudo.
Los CVE antiguos del designer (2016-6616, 2019-11768, 2019-18622) eran de nombre de usuario / nombre de base de datos. Este remanente es la columna JSON settings_data.
| ID | sin CVE todavía |
| Clase | SQLi (usuario de control sobre pma__designer_settings) |
| Alcance | Remoto (login autenticado por cookie; Designer + pma__designer_settings habilitados) |
| CWE | CWE-89 |
| CVSS | Alto: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Producto | phpMyAdmin |
| Afectado | 5.2.3 tag RELEASE_5_2_3 (962857e) |
| Auth | Login autenticado por cookie. Designer + pma__designer_settings habilitados. |
| Licencia | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1:19220 |
Un usuario autenticado de phpMyAdmin que pueda abrir el Designer puede inyectar SQL como el usuario de control sobre pma__designer_settings.
| Privilegio | Método / ruta | Probado en lab o inferido |
|---|---|---|
| Romper la cadena UPDATE/INSERT del usuario de control (integridad del SQL de pmadb) | POST index.php?route=/database/designer operation=save_setting_value con una comilla en value | Probado en lab. General log: SET settings_data = '{"snap_line":"PMA-DESIGNER-JSON-SQLI-WITNESS'#" }' en crudo. quoteString ausente |
Truncar el propio settings_data para que deje de ser JSON (integridad de la propia fila) | Mismo POST; # comenta el resto de la sentencia | Probado en lab. El blob de appuser contiene el testigo y no es JSON válido. El guardado limpio grid-ok ha desaparecido |
| Sobrescribir las filas del designer de otros usuarios sin consultas apiladas (integridad de la fila de la víctima) | El mismo # comenta WHERE username = '...' | Probado en lab. La semilla victim {"keep":"safe"} se convirtió en el blob testigo truncado |
| Sentencias adicionales como el usuario de control | Mismo sink si el enlace mysqli de control permite multi-query | Inferido. Por defecto mysqli::query es de una sola sentencia. No habilitado aquí |
Alcanzar otras tablas de pmadb (bookmarks, history, pma__userconfig) | Solo si son posibles consultas apiladas o un breakout de tipo escritura | Inferido. El usuario de control en este lab solo tiene DML sobre phpmyadmin.* |
Descartado en este lab: acceso no autenticado, la caja SQL del appuser autenticado (solo appdb; appuser no tiene GRANT sobre phpmyadmin), shell del SO y consultas apiladas. La funcionalidad no hace nada si pmadb / designer settings está desactivado (eso es un FAIL, no este remanente).
Ocho búsquedas paralelas en el código fuente de RELEASE_5_2_3. saveSetting concatena json_encode dentro de '...'. El nombre de usuario pasa por escapeString. 6.x ya aplica quoteString a este blob. 5.2.3 no.
Caminos equivocados: inyectar en el nombre de usuario (está escapado); esperar un #1064 (el # comenta el resto, así que MySQL acepta el UPDATE truncado); dar por probadas las consultas apiladas (el valor por defecto de mysqli es una sola sentencia).
python3 phpmyadmin-designer-json-sqli-Abraxas-Labs.py
o
cd lab
./run.sh
Solo loopback: http://127.0.0.1:19220. Imágenes phpmyadmin:5.2.3 y mysql:8.0. Proyecto de Compose phpmyadmin-designer-json-sqli. Testigo PMA-DESIGNER-JSON-SQLI-WITNESS.
SUCCESS phpmyadmin-designer-json-sqli version=5.2.3 how=live raw-concat=yes truncated=true sql-error=false quoteString=no PMA-DESIGNER-JSON-SQLI-WITNESS
quoteString(..., ControlUser) / escapeString sobre el blob JSON, igual que RecentFavoriteTable::saveToDb() y phpMyAdmin 6.x en esta columna. No coloques la salida de json_encode dentro de un literal SQL entre comillas simples.
962857e)libraries/classes/Database/Designer/Common.php saveSettingControllers/Database/DesignerController.php POST operation=save_setting_valueGET|POST /database/designerGNU Affero GPL v3.0. Ver LICENSE. Solo lab en loopback. Sin garantía.