var77/CVE-2026-2005
GitHub: var77/CVE-2026-2005
针对 PostgreSQL pgcrypto 扩展 PGP 会话密钥解析堆溢出漏洞的 PoC,实现任意内存读写并提权至超级用户执行系统命令。
Stars: 24 | Forks: 5
# CVE-2026-2005 - PostgreSQL pgcrypto 堆溢出漏洞利用
针对 PostgreSQL `pgcrypto` 扩展中 PGP 会话密钥解析导致的基于堆的缓冲区溢出的 PoC 漏洞利用,可导致任意内存读写以及提权至超级用户。
有关完整的技术细节,请参阅 [Zeroday Cloud 公告](https://www.zeroday.cloud/blog/postgres-xint)。
## 演示

## 用法
### 1. 编译 PostgreSQL
从存在漏洞的 commit 克隆并编译 PostgreSQL,以便二进制文件的符号偏移量完全匹配。该漏洞利用通过将泄露的指针与 ELF 符号偏移量进行匹配来解析 ASLR 基址 - 不同的构建或版本将具有不同的偏移量,从而导致利用失败。
```
git clone https://github.com/postgres/postgres.git
cd postgres
git checkout 4b324845ba5d24682b9b3708a769f00d160afbd7
./configure \
--prefix="$HOME/projects/pg/pgsql" \
--with-libxml \
--with-libxslt \
--enable-debug \
--with-ssl=openssl
make -j$(nproc)
make install-world-bin
```
### 2. 安装 Python 依赖
```
pip install -r requirements.txt
```
### 3. 运行漏洞利用
```
python poc.py \
--binary "$HOME/projects/pg/pgsql/bin/postgres" \
--dbname test-db \
--host 127.0.0.1 \
--port 5432 \
--user test-user \
--password secret \
--cmd id
```
### 选项
| 参数 | 默认值 | 说明 |
|---------------|---------------------|-------------|
| `--binary` | (postgres 二进制文件) | 用于提取符号的 postgres 二进制文件路径 |
| `--dbname` | postgres | 目标数据库名称 |
| `--host` | localhost | PostgreSQL 主机 |
| `--port` | 5432 | PostgreSQL 端口 |
| `--user` | postgres | 数据库用户 |
| `--password` | (空) | 数据库密码 |
| `--cmd` | whoami | 提权后要执行的操作系统命令 |
| `--gdb` | (标志) | 在溢出点通过 tmux 附加 GDB |
## 漏洞利用流程
该漏洞利用分为 7 个阶段进行:
1. **堆指针泄露** - 构造的 PGP 消息会破坏 `mdst` 缓冲区的 malloc 块头。当 PostgreSQL 在被破坏的块上调用 `pfree()` 时,分配器会发出包含指针地址的错误,从而泄露 `mdst->data` 的堆位置。
2. **任意读取** - 第二次溢出将 `mdst->data` 覆写为指向 `(leaked_ptr - 0x10000)`。解密后,`mbuf_steal_data()` 将该地址处的内容作为解密输出返回,从而转储可能包含陈旧代码指针的堆内存。
3. **指针扫描** - 扫描十六进制转储以查找看起来像代码地址(>= `0x500000000000`)但不在堆区域中的 8 字节小端序值。这些是候选的 PIE(位置无关可执行文件)指针。
4. **PIE 基址投票** - 根据 postgres 二进制文件中的 ELF 符号偏移量测试每个候选地址。对于页偏移量匹配的每个 `(addr - sym_offset)` 对,投出一票。保留获得 10 票以上的候选者;按票数排序的最小基址(PIE 是映射的最低 ELF 段)为最佳候选。
5. **PIE 基址验证** - 利用任意读取原语,漏洞利用在 `(candidate_base + current_user_offset)` 处读取 `CurrentUserId`,并将其与会话的已知 OID 进行比较。匹配则确认 PIE 基址。
6. **任意写入** - 溢出破坏了 `msrc` 和 `mdst` MBuf 头。伪造的 `msrc->data`/`read_pos` 指向包含加密超级用户 OID(10)的嵌入式对称加密数据包。伪造的 `mdst->data` 指向 `CurrentUserId - 4`(其中的 `-4` 是为了处理 `pgp-pgsql.c:533` 中将输出长度写入前 4 个字节的 `SET_VARSIZE`)。
7. **权限提升** - 在 `CurrentUserId` 被覆写为 10(引导超级用户)的情况下,`COPY FROM PROGRAM` 将以 postgres 系统用户身份执行指定的操作系统命令。
## 环境要求
- Python 3.10+
- psycopg2-binary, pwntools, pycryptodome (`pip install -r requirements.txt`)
- 从存在漏洞的 commit(4b324845)编译并启用了 `pgcrypto` 的 PostgreSQL
## 免责声明
此概念验证仅用于教育和防御性研究目的。请仅针对您拥有或获得明确授权测试的系统使用。
## 参考
- [CVE-2026-2005:PostgreSQL pgcrypto 整数溢出导致 RCE](https://www.zeroday.cloud/blog/postgres-xint)
标签:ASLR绕过, CISA项目, CVE-2026-2005, Maven, pgcrypto, PoC, PostgreSQL, Python, Web报告查看器, 任意内存读写, 协议分析, 堆溢出, 无后门, 暴力破解, 权限提升, 测试用例, 漏洞验证, 网络安全, 逆向工具, 隐私保护, 零日漏洞