
phpMyAdmin 5.2.3 - Alta - Remota - 2FA - config/set cancella l'autenticazione a due fattori
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · phpmyadmin-config-set-2fa
Write-up: https://abraxaslabs.tech/research/phpmyadmin-config-set-2fa
Classe: Privilegio residuo / step-up mancante Portata: Remota
phpMyAdmin 5.2.3 (RELEASE_5_2_3 / 962857e) - phpMyAdmin
POST index.php?route=/config/set scrive qualsiasi preferenza presente nella allowlist, incluso 2fa. UserPreferences::persistOption non esegue alcuna validazione. Settings -> Two-factor chiama ancora TwoFactor::check(true) prima di rimuovere il fattore. /config/set no.
Una sessione autenticata, oppure XSS/CSRF in grado di effettuare il POST del token della pagina, può inviare key=2fa e value=null. Il successivo login con password non richiede TOTP, WebAuthn o il prompt Simple. Rimozione duratura, non un salto valido per una sola richiesta.
| ID | nessuna CVE al momento |
| Classe | Privilegio residuo / step-up mancante |
| Portata | Remota (login autenticato tramite cookie; token CSRF richiesto) |
| CWE | CWE-620 |
| CVSS | Alto: 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 (962857e4f63d42e38f11ff4d63f5e722018add76) |
| Auth | login tramite cookie. Token CSRF richiesto. Completa XSS o CSRF verso una rimozione duratura del 2FA |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Rimuovere il 2FA da un account phpMyAdmin senza presentare TOTP, WebAuthn o il campo di conferma Simple. Il successivo login con password richiede solo la password. PMA completo come quell'utente MySQL (SQL, utenti, export).
| Privilegio | Metodo / percorso | Recon / integrità / disponibilità | Dimostrato in lab o dedotto |
|---|---|---|---|
Persistere 2fa a null e rimuovere il secondo fattore da pmadb | POST index.php?route=/config/set autenticato con key=2fa value=null più un token valido | Integrità dell'archivio delle preferenze | Dimostrato in lab. success:true, config_data di pmadb è diventato [] |
| Effettuare il login solo con password dopo quella scrittura | Nuova sessione cookie, stesso utente MySQL | Integrità del percorso di login | Dimostrato in lab. Nessun 2fa_confirm, accesso alla normale UI |
| Mantenere la sessione corrente mentre il 2FA scompare per i login successivi | Stesso handler; persistOption scrive nell'archivio, non nel flag two_factor_check attivo | Integrità delle sessioni successive | Dimostrato in lab. La sessione A è rimasta attiva. La sessione B aveva visto il 2FA. La sessione C no |
| Concatenare da XSS memorizzato o CSRF in grado di effettuare il POST con il token della pagina | Residui della stessa revisione, non di questo lab | Integrità del 2FA dopo un POST same-origin | Dedotto |
| Rimuovere il 2FA tramite Settings | POST /preferences/two-factor 2fa_remove=1 | Integrità del 2FA tramite la UI documentata | Dimostrato in lab come chiuso. Senza il fattore, PMA mostra la pagina di conferma e pmadb contiene ancora backend=simple |
Chiusi su questo residuo: accesso non autenticato, salto della password MySQL, RCE sul sistema operativo, lettura delle righe pmadb di altri utenti. Non mi è servito il residuo #1 (firma CustomServer). Non ho saltato la password MySQL.
Stesso pin: residuo WebAuthn CustomServer.
Ho bloccato la 5.2.3 dopo PMASA-2025-1/2/3. Autenticazione tramite cookie, pmadb pma__userconfig. Il lab abilita $cfg['DBG']['simple2fa'] solo affinché Impostazioni possa registrare il backend Simple senza una chiave hardware. TOTP e WebAuthn risiedono nella stessa chiave di preferenza 2fa.
SetConfigController accetta key e value JSON e chiama Config::setUserValue. UserPreferences::persistOption è documentato con "No validation is done!" apply() inserisce 2fa nella allowlist così la chiave non viene scartata come preferenza sconosciuta.
$result = $this->config->setUserValue(null, $key, json_decode($value));
json_decode('null') è null in PHP. persistOption('2fa', null, $default) quindi rimuove config_data['2fa'] perché anche il valore predefinito per quel percorso è null.
Settings -> Two-factor è il contrasto. TwoFactorController non eseguirà configure('') finché TwoFactor::check(true) non restituisce true.
Vicoli ciechi già registrati: considerare 2fa_remove nelle Impostazioni come la falla (richiede comunque il fattore); sostenere un accesso non autenticato; sostenere un salto della password MySQL; considerare questo come il residuo #1 (CustomServer); una reverse shell. Teatro.
python3 phpmyadmin-config-set-2fa-Abraxas-Labs.py
# or: cd lab && ./run.sh
Punta solo a http://127.0.0.1:19280. Compose del progetto phpmyadmin-config-set-2fa. Fissa RELEASE_5_2_3. run.sh copia o clona quel tag in lab/src/ per l'immagine. Lo stack viene smontato dopo l'esecuzione.
Le impostazioni hanno registrato Simple 2FA. Un secondo browser ha raggiunto la pagina 2fa_confirm. La POST 2fa_remove senza il fattore è rimasta sull'interfaccia di conferma e ha lasciato backend=simple in pmadb. La POST /config/set ha poi restituito success:true, pmadb è diventato [] e il login successivo è approdato alla UI normale.
SUCCESS phpmyadmin-config-set-2fa enroll=simple ui-remove-blocked=yes config-set-cleared=yes next-login-password-only=yes PMA-CONFIG-SET-2FA-WITNESS
Nega 2fa (e altre chiavi di autenticazione) su /config/set. Richiedi TwoFactor::check(true) prima di qualsiasi modifica al 2FA. Mantieni il percorso Settings come unico scrittore.
962857e4f63d42e38f11ff4d63f5e722018add76)libraries/classes/Controllers/Config/SetConfigController.phplibraries/classes/Config/UserPreferences.phpGNU Affero GPL v3.0. Vedi LICENSE. Solo laboratorio loopback. Nessuna garanzia.