PostgreSQL to_char() 函数在处理时区格式化时存在堆缓冲区溢出漏洞。攻击者通过设置超长 POSIX 时区缩写,可触发 25 字节固定缓冲区的越界写入,配合信息泄漏与 ROP 链实现远程代码执行。
to_char(timestamptz) 函数| PostgreSQL 系列 | 受影响范围 |
|---|---|
| 18.x | 18.0 – 18.5 |
| 17.x | 17.0 – 17.10 |
| 16.x | 16.0 – 16.14 |
| 15.x | 15.0 – 15.18 |
| 14.x | 14.0 – 14.23 |
formatting.c 中的 DCH_TZ / DCH_tz 处理路径使用 25 字节固定栈缓冲区存储时区缩写,但对输入长度没有任何检查。当时区缩写超过 24 字节时,strcpy() 会越界写入堆内存。
触发路径:
SET TIME ZONE '<超长缩写>+00';
SELECT to_char(now()::timestamptz, 'TZ');
↓
DCH_to_char() → DCH_from_char_action()
↓
strcpy(buf, tmtcTzn(...)) ← 堆溢出
V12 Security 的 PoC 包含三个阶段:
通过堆溢出破坏相邻堆对象,泄漏 PIE 基址和堆指针以击破 ASLR。
利用大对象或 bytea 字段在堆上布置 ROP gadget 链。
第二次溢出覆盖堆上的函数指针,跳转到 ROP 链执行任意命令(以 postgres 用户权限)。
poc.py - 完整利用脚本(210 行,针对 PostgreSQL 19beta1)requirements.txt - Python 依赖(psycopg, pwntools)docker-compose.yml - 漏洞测试环境docker-compose up -d
等待容器启动完成(健康检查通过):
docker logs pg-tzlab
pip install -r requirements.txt
python3 poc.py
默认连接 127.0.0.1:55432,用户名 postgres,密码 postgres。
成功利用后,在容器日志中可看到命令执行输出:
docker logs pg-tzlab | grep PWNED
编辑 poc.py 中的常量:
HOST, PORT - 目标地址DEFAULT_COMMAND - 要执行的命令⚠️ 重要:此 PoC 硬编码了特定构建的偏移地址(postgres:19beta1 Docker 镜像 sha256:a6bdd01...)。其他版本需要重新定位 gadget。
SET TIME ZONE 语句(> 50 字符)⚠️ 本 PoC 仅供安全研究、漏洞验证与防御性测试使用。
使用本 PoC 即表示您同意遵守当地法律法规与目标系统授权边界。