Novel Arbitrary Write in SQLite
8 hours ago
- 通过滥用 sqlite_dbpage 虚拟表,SQLite 可能被利用进行任意代码执行,该表提供对原始数据库页面的低级读写访问,并且通常默认启用。
- 使用 ATTACH DATABASE 和 sqlite_dbpage,攻击者可以覆盖数据库页面;但是,SQLite 头部的前 100 字节(魔术字节、计数器)无法直接控制,从而阻止完全任意的文件写入。
- 该技术通过写入共享对象 (.so) 文件,然后使用 LIEF 将 ELF 程序头表 (e_phoff) 重定位到文件末尾,以避免第 1 页中不可变的头部字节。
- 可以自动生成完整的 SQL 脚本:分配页面、对载荷进行分块、填充到页大小,并从最后一页开始发出逆序的 UPDATE 语句,以避免过早破坏数据库头部。
- 在 Python 中,攻击针对 import 遮蔽:.so 文件优先于 .py 模块,当应用程序重启并重新导入模块时,可导致代码执行。
- 可以通过使进程崩溃来强制重启——要么通过 Gunicorn 的工作进程超时(默认 30 秒),要么在达到内存限制时,使用递归公用表表达式(例如,CREATE TEMP TABLE ... SELECT x+1 FROM c)导致内存耗尽。
- 该技术扩展到 Ruby,通过遮蔽 C 扩展(如 nio4r_ext.so,Puma 的依赖),当 Puma 工作进程重启时会加载它;Ruby 的 requirer 会在加载路径中使用 .so 文件。
- 对于 Ruby,也可以利用 __END__ 标记滥用 .rb 文件:__END__ 之后的所有内容都被视为 DATA 常量,因此可以用注释和短载荷隐藏 SQLite 头部。
- Node.js 限制更多:原生插件使用 .node 文件(同一 ELF 格式)并需要 CommonJS,但 sqlite_dbpage 在主流的 SQLite 构建中很少启用,限制了实际利用。
- Python 的 .pth 文件也可以通过 site-packages 中的 'import' 行实现代码执行,允许恶意 .pth 文件通过将 SQLite 头部字节放在 '#' 注释之后来绕过空字节问题。
- 该攻击需要在 SQL 注入点支持堆叠查询,并且 sqlite_dbpage 必须编译进去(ENABLE_DBPAGE_VTAB)并在运行时启用;兼容性因操作系统和语言运行时而异(例如,python:bookworm 禁用它,而 python:slim 和 Ruby 启用它)。