导语:数据库管理员们,注意了。V12安全团队的Rick de Jager(里克·德·雅格尔)联合多位研究员发现了PostgreSQL中的一个严重漏洞——CVE-2026-14669。攻击者只需一个经过认证的数据库账户,就能通过to_char()函数的堆缓冲区溢出拿到PostgreSQL服务器的代码执行权限。V12已公开完整POC,CVSS评分8.8,影响面极广。
一、漏洞概述
CVE-2026-14669是PostgreSQL数据库中to_char()函数的一个堆缓冲区溢出漏洞,可导致经过认证的用户在PostgreSQL服务器进程中执行任意代码。
CVSS 3.1评分:8.8(高危)
漏洞根因在于datetime_to_char_body()函数的两个路径(DCH_TZ和DCH_tz):该函数根据格式化字符串的长度来分配输出工作区缓冲区,但接下来会将会话中用户可控的POSIX时区缩写复制到该缓冲区中,完全不检查长度。
只要获得一个有效的数据库账户,攻击者就能设置一个超长的时区缩写,触发堆溢出,最终在PostgreSQL后端进程的权限下执行任意代码。
受影响版本:
- PostgreSQL 18.6
- PostgreSQL 17.11
- PostgreSQL 16.15
- PostgreSQL 15.19
- PostgreSQL 14.24
- PostgreSQL 19 Beta 3
二、漏洞原理详解
2.1 根因分析
PostgreSQL的datetime_to_char_body()函数在处理to_char()格式化输出时,会根据格式化字符串的长度来分配输出缓冲区:
palloc(fmt_len * DCH_MAX_ITEM_SIZ + 1)
然而,在处理TZ和TZtz格式说明符时,函数会直接读取当前会话的POSIX时区缩写,并复制到已分配的缓冲区中,但完全不做长度检查。
攻击者只需要修改当前会话的时区设置为超长字符串,即可控制溢出数据量。
2.2 利用过程
V12安全团队发布的POC揭示了完整的四步利用链:
第一步:信息泄露(堆布局准备)
两次相邻的to_char(now(), 'TZ')调用会重用同一个已释放的堆空间。第二次溢出重写了第一个结果的varlena长度字段,导致二进制COPY输出泄露约16 KiB的相邻堆内存。函数指针在此数据中暴露了PostgreSQL的PIE基地址。
第二步:堆指针泄露(无效指针路径)
50字节的超长时区缩写会触发无效指针路径,其错误信息包含了被拒绝的地址,从而泄露一个活着的堆指针。
第三步:元数据破坏(内存错位)
priming to_char('TZtz')操作破坏了分配器元数据,使后续decode(..., 'hex')分配溢出到printtup的每行内存上下文中。有效载荷修复了所需的上下文字段,安装了一个伪造的MemoryContextCallback,并将其指向system()和要执行的命令。
第四步:代码执行(触发回调)
在行处理结束时,MemoryContextReset()调用伪造的回调,执行配置的任意命令。V12的POC默认执行id命令,演示输出:
pg-tzlab | PWNED
pg-tzlab | uid=999(postgres) gid=999(postgres) ...

三、发现者与漏洞 attribution
CVE-2026-14669由以下安全研究人员独立发现并报告:
- Rick de Jager(里克·德·雅格尔) — V12安全团队(推特@v12sec)
- Hcamael(海卡梅尔)
- Amjad Shahzad(阿姆贾德·沙赫扎德)
- Tan Zhen(谭震) — 安恒信息实验室(AntAISecurityLab)
- Tomer Fichman(托默·菲奇曼)
- Zheng Yu(郑宇)
- Amy Burnett(艾米·伯内特) — OpenAI Codex Security
- Heewon Song(宋熙元)
- Sylvie Mayer(西尔维·迈耶)
- Aleksander Alekseev(亚历山大·阿列克谢夫)
- Hillai Ben Sasson(希莱·本·萨松)
PostgreSQL官方已在commit 3d724bf4中修复了此漏洞。
四、POC公开情况
V12安全团队已在GitHub上公开了完整的漏洞利用仓库:
GitHub: github.com/v12-security/pocs/tree/main/postgresql/server
利用要求:
- Docker + Docker Compose
- Python 3
- requirements.txt中的依赖包
运行环境:
python3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
启动靶场:
docker compose up -d
docker compose logs -f postgres
运行POC:
python poc.py
POC针对官方PostgreSQL 19 beta1 x64 Debian镜像(SHA256: a6bdd01b51b115f446a03135f9395575b3eb6ba90a92bfb692da82088f8820f8),偏移量与具体构建版本相关,不同构建通常会崩溃后端而非执行载荷。
注意: 这是一个远程代码执行POC,只在可控的隔离环境中运行。
五、修复方案
PostgreSQL官方已在以下版本中修复此漏洞:
| 版本 | 修复状态 |
|---|---|
| PostgreSQL 18.6 | ✅ 已修复 |
| PostgreSQL 17.11 | ✅ 已修复 |
| PostgreSQL 16.15 | ✅ 已修复 |
| PostgreSQL 15.19 | ✅ 已修复 |
| PostgreSQL 14.24 | ✅ 已修复 |
| PostgreSQL 19 Beta 3 | ✅ 已修复 |
建议所有使用PostgreSQL的组织:
- 立即升级到上述修复版本
- 如果无法立即升级,考虑限制数据库账户的权限
- 监控异常的
to_char()调用和时区设置操作 - 检查非预期的
MemoryContextCallback行为
六、总结
这是一个典型的”认证后→代码执行”漏洞链。虽然需要认证账户作为前提条件,但一旦获得账户,攻击者可以直接在数据库服务器进程内执行任意代码——相当于拿到了数据库主机的操作系统级控制权。
CVSS 8.8的评分对于一个需要认证的RCE来说已经相当高。结合PostgreSQL在企业中的广泛部署(大量应用的后端数据存储),这个漏洞的实战价值不容小觑。
V12安全团队还预告即将发布客户端RCE的POC,届时双向RCE(客户端感染服务器、服务器感染客户端)的完整攻击场景将全部公开。
POC地址: https://github.com/v12-security/pocs/tree/main/postgresql/server
版权声明:本文由华盟网原创发布,保留所有权利。配图由华盟网授权使用。











暂无评论内容