
SQLite 3.53.4 CLI - Alta - Local - Injeção de comando - recover dump emite esquema hostil como dot-command
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-cli-recover
Write-up: https://abraxaslabs.tech/research/sqlite-cli-recover
Classe: Injeção de comando Alcance: Local
O .recover da CLI do SQLite 3.53.4 (b09c88c) imprime um sqlite_schema.sql hostil como um dot-command posterior. recoverOneStmt prepara apenas a primeira instrução. Um CREATE TABLE plantado mais uma nova linha com .shell ainda é gravado. O pipe de restauração documentado o executa com o UID do operador.
O printSchemaLine do .dump é da mesma classe de emissão. Não é libsqlite3. Não é --safe. O oráculo é o echo de uma string testemunha.
| ID | ainda sem CVE |
| Classe | Injeção de comando (emissão de schema da CLI .recover / .dump) |
| Alcance | Local (a vítima executa o pipe de recuperação documentado; 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 |
| Produto | SQLite (CLI sqlite3) |
| Afetado | 3.53.4 (b09c88c14082339b66c7b7158d609a771e64ca69) SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc |
| Autenticação | a vítima executa sqlite3 hostile.db .recover | sqlite3 restored.db |
| Licença | GNU Affero GPL v3.0 |
| Lab | apenas 127.0.0.1:18930. Testemunha SQLITE-CLI-RECOVER-WITNESS. |
Plantar um primeiro CREATE válido mais um .shell posterior em sqlite_schema.sql. Uma vítima que recupera esse db para um segundo sqlite3 executa o dot-command com o próprio UID.
O plant é um arquivo .db. A ação da vítima é o pipe de recuperação documentado, não uma linha go colada e não o --safe desativado por acidente. .shell é system(). O oráculo do lab é o echo de uma testemunha. Não é um reverse shell.
Vinte buscas no código-fonte da 3.53.4. A própria busca do recover chamou recoverOneStmt de preparação apenas da primeira instrução e seguiu adiante. O que sobrou é o caminho de impressão: recoverSqlCb ainda emite o texto extra. Fazer o pipe desse script é como o sqlite.org manda você restaurar.
Caminhos errados já registrados: tratar a preparação da primeira instrução como remoção; fixar na 3.54.0 (rascunho); reenviar o CVE-2022-46908 --safe; chamar isso de RCE no libsqlite3; usar um reverse shell como oráculo.
cd lab
./run.sh
Compila sqlite-src-3530400 em sqlite3 com o CLI Unix recover padrão (OPT_SHELL / SQLITE_ENABLE_DBPAGE_VTAB). writable_schema após .dbconfig defensive off. Inserido CREATE TABLE t(x); mais nova linha .shell echo SQLITE-CLI-RECOVER-WITNESS. .recover imprimiu .shell. Canalizado para um segundo sqlite3, ele executou. Vinculado ao loopback.
SUCCESS sqlite-cli-recover how=recover-pipe-dot-shell recover-has-shell=yes restore-echo=yes SQLITE-CLI-RECOVER-WITNESS
Não imprima SQL de schema que não seja uma única instrução. Divida no primeiro prepare, emita apenas essa instrução, ou rejeite a linha. Faça a citação de CREATE comum da mesma forma que o dump de tabela virtual já usa %q. Trate uma linha . posterior como hostil e descarte-a. --safe no sqlite3 de restauração bloqueia .shell; ele não está ativado no pipe documentado.
b09c88c14082339b66c7b7158d609a771e64ca69).recover documentado e depois restauraçãoext/recover/sqlite3recover.c recoverOneStmt / recoverWriteSchema1src/shell.c.in recoverSqlCb, .dump printSchemaLine