phpMyAdmin 5.2.3 - Alta - Remota - SQLi - Identificatori non sanificati in Designer JSON
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-designer-json-sqli
Classe: SQLi Reach: Remoto
phpMyAdmin 5.2.3 (tag RELEASE_5_2_3, commit 962857e). L'AJAX del Designer save_setting_value esegue json_encode sul blob delle impostazioni e lo concatena in un UPDATE/INSERT con apici singoli sul link control-user. Lo username è escapato. Il JSON no. json_encode non esegue l'escape di un apice singolo.
Un utente autenticato invia in POST index.php?route=/database/designer con operation=save_setting_value e un apice in value. queryAsControlUser esegue poi quella stringa come control user di pma su pma__designer_settings. Quell'account è la configuration storage, non la SQL box dell'utente loggato. phpMyAdmin 6.x avvolge questo blob in quoteString su ControlUser. La 5.2.3 lo concatena ancora grezzo.
Le vecchie CVE del designer (2016-6616, 2019-11768, 2019-18622) riguardavano username / nome del database. Questo residuo è la colonna JSON settings_data.
| ID | nessuna CVE al momento |
| Classe | SQLi (control-user su pma__designer_settings) |
| Reach | Remoto (login autenticato via cookie; Designer + pma__designer_settings abilitati) |
| CWE | CWE-89 |
| CVSS | High: 8.1 CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N |
| Prodotto | phpMyAdmin |
| Affetto | 5.2.3 tag RELEASE_5_2_3 (962857e) |
| Auth | Login autenticato via cookie. Designer + pma__designer_settings abilitati. |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1:19220 |
Un utente phpMyAdmin autenticato che può aprire il Designer può iniettare SQL come control user su pma__designer_settings.
| Privilegio | Metodo / path | Provato in lab o dedotto |
|---|---|---|
| Rompere la stringa UPDATE/INSERT del control-user (integrità dell'SQL di pmadb) | POST index.php?route=/database/designer operation=save_setting_value con un apice in value | Provato in lab. General log: SET settings_data = '{"snap_line":"PMA-DESIGNER-JSON-SQLI-WITNESS'#" }' grezzo. quoteString assente |
Troncare il proprio settings_data in modo che non sia più JSON (integrità della propria riga) | Stesso POST; # commenta il resto dell'istruzione | Provato in lab. Il blob di appuser contiene il witness e non è JSON valido. Il salvataggio pulito grid-ok è sparito |
| Sovrascrivere le righe designer di altri utenti senza query impilate (integrità della riga della vittima) | Stesso # commenta WHERE username = '...' | Provato in lab. Il seed victim {"keep":"safe"} è diventato il blob witness troncato |
| Istruzioni extra come control user | Stesso sink se il link mysqli di controllo consente multi-query | Dedotto. Il default di mysqli::query è single-statement. Non abilitato qui |
Raggiungere altre tabelle pmadb (bookmarks, history, pma__userconfig) | Solo se sono possibili query impilate o un breakout di tipo write | Dedotto. Il control user in questo lab ha solo DML su phpmyadmin.* |
Chiusi su questo lab: accesso non autenticato, la SQL box dell'appuser autenticato (solo appdb; appuser non ha GRANT su phpmyadmin), OS shell e query impilate. La feature è no-op se pmadb / designer settings è disattivato (questo è un FAIL, non questo residuo).
Otto ricerche parallele nel sorgente di RELEASE_5_2_3. saveSetting concatena json_encode dentro '...'. Lo username è escapeString. La 6.x già applica quoteString a questo blob. La 5.2.3 no.
Vicoli ciechi: iniettare sullo username (è escapato); aspettarsi un #1064 (il # commenta il resto, quindi MySQL accetta l'UPDATE troncato); considerare provate le query impilate (il default di mysqli è single-statement).
python3 phpmyadmin-designer-json-sqli-Abraxas-Labs.py
oppure
cd lab
./run.sh
Solo loopback: http://127.0.0.1:19220. Immagini phpmyadmin:5.2.3 e mysql:8.0. Progetto Compose phpmyadmin-designer-json-sqli. Witness 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 sul blob JSON, come in RecentFavoriteTable::saveToDb() e in phpMyAdmin 6.x su questa colonna. Non inserire l'output di json_encode dentro un letterale SQL con apici singoli.
962857e)libraries/classes/Database/Designer/Common.php saveSettingControllers/Database/DesignerController.php POST operation=save_setting_valueGET|POST /database/designerGNU Affero GPL v3.0. Vedi LICENSE. Solo lab in loopback. Nessuna garanzia.