
SQLite 3.53.4 CLI - Alta - Locale - Command injection - recover dump emette uno schema ostile come comando dot
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-cli-recover
Write-up: https://abraxaslabs.tech/research/sqlite-cli-recover
Classe: Command injection Portata: Locale
La CLI .recover di SQLite 3.53.4 (b09c88c) stampa un sqlite_schema.sql ostile come successivo dot-command. recoverOneStmt prepara solo la prima istruzione. Un CREATE TABLE inserito più una .shell su nuova riga vengono comunque scritti. La pipe di ripristino documentata la esegue con l'UID dell'operatore.
printSchemaLine di .dump è della stessa classe di emissione. Non è libsqlite3. Non è --safe. L'oracolo è l'echo di una stringa witness.
| ID | nessuna CVE al momento |
| Classe | Command injection (emissione dello schema da CLI .recover / .dump) |
| Portata | Locale (la vittima esegue la pipe di ripristino documentata; UI:R) |
| CWE | CWE-78 |
| CVSS | Alto: 7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| Prodotto | SQLite (CLI sqlite3) |
| Affetto | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69) SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc |
| Auth | la vittima esegue sqlite3 hostile.db .recover | sqlite3 restored.db |
| Licenza | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1:18930. Witness SQLITE-CLI-RECOVER-WITNESS. |
Inserire un primo CREATE valido più una .shell successiva in sqlite_schema.sql. Una vittima che ripristina quel db in un secondo sqlite3 esegue il dot-command con il proprio UID.
L'inserimento è un file .db. L'azione della vittima è la pipe di ripristino documentata, non una riga go incollata e non un --safe disattivato per errore. .shell è system(). L'oracolo del lab è l'echo di una witness. Non una reverse shell.
Venti ricerche nel codice sorgente della 3.53.4. La ricerca dedicata a recover ha definito recoverOneStmt un prepare limitato alla prima istruzione e si è fermata lì. Ciò che resta è il percorso di stampa: recoverSqlCb emette comunque il testo aggiuntivo. Fare il pipe di quello script è il modo in cui sqlite.org ti dice di ripristinare.
Vicoli ciechi già registrati: considerare il prepare della prima istruzione come una rimozione; fissare la 3.54.0 (bozza); riproporre CVE-2022-46908 --safe; definire questa una RCE di libsqlite3; usare una reverse shell come oracolo.
cd lab
./run.sh
Compila sqlite-src-3530400 in sqlite3 con il recover CLI Unix predefinito (OPT_SHELL / SQLITE_ENABLE_DBPAGE_VTAB). writable_schema dopo .dbconfig defensive off. Inserito CREATE TABLE t(x); più newline .shell echo SQLITE-CLI-RECOVER-WITNESS. .recover ha stampato .shell. Inviato tramite pipe in un secondo sqlite3, è stato eseguito. Bind su loopback.
SUCCESS sqlite-cli-recover how=recover-pipe-dot-shell recover-has-shell=yes restore-echo=yes SQLITE-CLI-RECOVER-WITNESS
Non stampare SQL di schema che non sia una singola istruzione. Suddividi al primo prepare, emetti solo quell'istruzione, oppure rifiuta la riga. Racchiudi tra virgolette il normale CREATE nello stesso modo in cui il dump delle tabelle virtuali usa già %q. Tratta una successiva riga . come ostile e scartala. --safe sul ripristino sqlite3 blocca .shell; non è attivo nella pipe documentata.
b09c88c14082339b66c7b7158d609a771e64ca69).recover poi ripristinoext/recover/sqlite3recover.c recoverOneStmt / recoverWriteSchema1src/shell.c.in recoverSqlCb, .dump printSchemaLine