abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · sqlite-cli-recover
类别: 命令注入 影响范围: 本地
SQLite 3.53.4(b09c88c)CLI 的 .recover 会将恶意的 sqlite_schema.sql 作为后续的点命令打印出来。recoverOneStmt 只准备第一条语句。植入的 CREATE TABLE 加上换行后的 .shell 仍会被写出。文档中记载的恢复管道会以操作员 UID 执行它。
.dump 的 printSchemaLine 属于同一类输出。不是 libsqlite3。不是 --safe。判定依据是 echo 一个见证字符串。
| ID | 暂无 CVE |
| 类别 | 命令注入(CLI .recover / .dump schema 输出) |
| 影响范围 | 本地(受害者运行文档中记载的恢复管道;UI:R) |
| CWE | CWE-78 |
| CVSS | 高危:7.8 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H |
| 产品 | SQLite(sqlite3 CLI) |
| 受影响版本 | 3.53.4(b09c88c14082339b66c7b7158d609a771e64ca69)SOURCE_ID 2026-07-24 19:02:57 bf7c7f30031888f4e796e429ab3978879485813aaca6f641c7b33e4e09459bcc |
| 认证 | 受害者运行 sqlite3 hostile.db .recover | sqlite3 restored.db |
| 许可证 | GNU Affero GPL v3.0 |
| 实验环境 | 仅 127.0.0.1:18930。见证字符串 SQLITE-CLI-RECOVER-WITNESS。 |
在 sqlite_schema.sql 中植入一条有效的首条 CREATE 以及后续的 .shell。受害者将该数据库恢复到第二个 sqlite3 时,就会以自己的 UID 运行该点命令。
植入物是一个 .db 文件。受害者操作是文档中记载的恢复管道,而不是粘贴的 go 行,也不是意外关闭了 --safe。.shell 即 system()。实验判定依据是 echo 一个见证字符串。不是反弹 shell。
对 3.53.4 进行了二十次源码排查。Recover 自身的排查将 recoverOneStmt 称为仅准备第一条语句,然后就离开了。遗留问题在于打印路径:recoverSqlCb 仍会输出多余文本。而管道传输该脚本正是 sqlite.org 告诉你的恢复方式。
已记录的弯路:将首条语句准备视为剥离;锁定 3.54.0(草稿);重新提交 CVE-2022-46908 --safe;称此为 libsqlite3 RCE;使用反弹 shell 作为判定依据。
cd lab
./run.sh
将 sqlite-src-3530400 构建为 sqlite3,使用默认 Unix CLI recover(OPT_SHELL / SQLITE_ENABLE_DBPAGE_VTAB)。在 .dbconfig defensive off 之后设置 writable_schema。植入 CREATE TABLE t(x); 加上换行后的 .shell echo SQLITE-CLI-RECOVER-WITNESS。.recover 打印出了 .shell。管道传输到第二个 sqlite3 后,它被执行了。绑定回环地址。
SUCCESS sqlite-cli-recover how=recover-pipe-dot-shell recover-has-shell=yes restore-echo=yes SQLITE-CLI-RECOVER-WITNESS
不要打印不是单条语句的 schema SQL。在第一次 prepare 处分割,只输出该语句,或拒绝该行。像虚拟表 dump 已经使用 %q 那样对普通 CREATE 进行引用。将后续的 . 行视为恶意并丢弃。在恢复用的 sqlite3 上使用 --safe 可以阻止 .shell;但文档中记载的管道并未启用它。
b09c88c14082339b66c7b7158d609a771e64ca69).recover 然后恢复ext/recover/sqlite3recover.c recoverOneStmt / recoverWriteSchema1src/shell.c.in recoverSqlCb、.dump printSchemaLine