一个自包含的 Docker 实验环境,用于练习利用 CVE-2026-2005——PostgreSQL pgcrypto 扩展中的堆缓冲区溢出漏洞,该漏洞可在无需超级用户权限的情况下实现远程代码执行。
受影响版本: PostgreSQL ≤ 17.7 / 16.11 / 15.15 / 14.20 / 18.1
修复版本: 18.2, 17.8, 16.12, 15.16, 14.21(发布于 2026-02-12)
前置要求: Docker、Docker Compose
git clone <this-repo>
cd CVE-2026-2005
docker compose up -d
PostgreSQL 将监听在 127.0.0.1:5433。
你已从某个应用配置文件中获取了数据库凭据:
| 参数 | 值 |
|---|
| 主机 | 127.0.0.1 |
| 端口 | 5433 |
| 数据库 | targetdb |
| 用户名 | pentester |
| 密码 | pentester123 |
连接以确认访问权限:
psql -h 127.0.0.1 -p 5433 -U pentester -d targetdb
该账户在 public 模式上拥有 CREATE 权限。它不是超级用户。
捕获两个 flag 以完成实验。
Flag 1 — 数据库权限提升
SELECT * FROM flag_db;
-- 仅在数据库会话内提升为超级用户后才可读取
Flag 2 — 容器代码执行
/var/lib/postgresql/flag.txt
-- 仅在以容器内 postgres 操作系统用户身份执行命令后才可读取
范围说明:
COPY TO PROGRAM在 Docker 容器内执行,而非宿主机上。 现实世界中的主要影响是完整的数据库读取权限(所有表、所有数据库)。 要攻破 Docker 宿主机,需要单独的容器逃逸技术。
该缺陷位于 pgcrypto/pgp-pubenc.c 中的 pgp_parse_pubenc_sesskey() 函数。
在解密公钥加密的会话密钥数据包时,该函数从攻击者控制的 RSA/ElGamal 载荷中将会话密钥长度推导为 msglen - 3,并将其复制到固定的 32 字节缓冲区(PGP_MAX_KEY)中,且未进行边界校验。攻击者可以在缓冲区边界之外写入数百字节。
利用过程分为三个阶段:
dst 结构体,将 .data 中的 CurrentUserId 覆盖为 10(BOOTSTRAP_SUPERUSERID)COPY (SELECT '') TO PROGRAM '<cmd>' 以 postgres 用户身份在容器内执行操作系统命令。在未使用 Docker 的真实部署中,这意味着对数据库宿主机拥有操作系统级访问权限。由于所有连接到同一 postmaster 进程的 ASLR 布局完全相同,在一个连接上泄露的地址在下一个连接上仍然有效。
pgcrypto/pgp-pubenc.cobjdump -t $(which postgres) | grep CurrentUserIddocker compose down -v
本实验环境仅供授权的安全研究和教育使用。请仅在您拥有或获得明确测试许可的系统上运行。