
CVE-2026-20251 — Splunk Secure Gateway jsonpickle डिसीरियलाइज़ेशन RCE (CVSS 8.8) | ReactiveZero Security Research
शोधकर्ता: 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) खतरनाक टैग को ब्लॉक करने के लिए अभिप्रेत है, लेकिन यह पहली पहचानी गई key पर शॉर्ट-सर्किट करता है: कोई भी दस्तावेज़ जिसकी पहली top-level key एक अनुमत py/object है (मान spacebridgeapp से शुरू होता है) तुरंत True लौटाता है, जिससे सहोदर keys — जिनमें एक दुर्भावनापूर्ण py/reduce गैजेट भी शामिल है — पूरी तरह अनदेखी रह जाती हैं।
| ब्रांच | सुधारित संस्करण |
|---|---|
| Splunk Secure Gateway 3.9.x | 3.9.20 |
| Splunk Secure Gateway 3.10.x | 3.10.6 |
| Splunk Secure Gateway 3.8.x |
परीक्षित इंस्टेंस: SSG 3.9.19 Splunk Enterprise 10.0.6 पर (macOS x86_64)।
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 उन दो शर्तों को प्रदर्शित करता है जो पूर्ण exploit श्रृंखला का निर्माण करती हैं:
पेलोड जानबूझकर हानिरहित है (केवल-पठनीय uname -a)। यह हथियारबद्ध exploit नहीं है।
jsonpickle तक पहुँच (/Applications/Splunk/etc/apps/splunk_secure_gateway/lib से लोड किया गया)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 short-circuits on the first 'py'-prefixed key:
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+ में अपग्रेड करें।
अल्पकालिक शमन उपाय (यदि पैचिंग तुरंत संभव न हो):
mobile_alerts पर collection-स्तरीय ACL की समीक्षा करेंरक्षात्मक इंजीनियरिंग पैटर्न: बाह्य रूप से प्रभावित संग्रहीत डेटा से कभी भी मनमाने प्रकार पुनर्निर्मित न करें। हमलावर-सुलभ इनपुट पर jsonpickle.decode() को एक सख्त, schema-सत्यापित पार्सर से बदलें या decode() को एक स्पष्ट classes= allow-list प्रदान करें। सुनिश्चित करें कि सत्यापन रूटीन पहली पहचानी गई key पर short-circuit करने के बजाय नेस्टेड संरचनाओं को पूरी तरह ट्रैवर्स करें।
इसी advisory बैच में CVE-2026-20253 शामिल है (CVSS 9.8, PostgreSQL sidecar endpoint के माध्यम से बिना प्रमाणीकरण के मनमानी फ़ाइल निर्माण)। यह भेद्यता परीक्षित macOS x86_64 बिल्ड Splunk Enterprise 10.0.6 पर उपस्थित नहीं थी: PostgreSQL sidecar घटक इस प्लेटफ़ॉर्म पर शामिल नहीं है, कोई sidecar बाइनरी या प्रोसेस मौजूद नहीं है, और कोई संगत पोर्ट नहीं देखा गया।
यह एक महत्वपूर्ण आश्वासन सिद्धांत को दर्शाता है: एक प्रभावित संस्करण स्ट्रिंग शोषण-क्षमता के लिए एक आवश्यक शर्त है, लेकिन पर्याप्त नहीं। घटक-स्तरीय सत्यापन वास्तविक जोखिम परिदृश्य को महत्वपूर्ण रूप से बदल देता है।
| फ़ील्ड | मान |
|---|---|
| एंगेजमेंट संदर्भ | 2026FO-SPLUNK-20251 |
| परीक्षण प्रकार | White-Box भेद्यता सत्यापन (स्टैटिक कोड विश्लेषण) |
ReactiveZero Security Research
| 3.8.67 |
| Splunk Enterprise | 10.0.7 / 10.2.4 / 10.4.0+ |
| उप-प्रमाण | यह क्या दर्शाता है |
|---|
| A — वैलिडेटर बायपास | check_alert_data_valid_json() बायपास दस्तावेज़ के लिए True लौटाता है, सहोदर मान में मौजूद py/reduce गैजेट की कभी जाँच नहीं करता |
| B — py/reduce निष्पादन | jsonpickle.decode(..., safe=True) subprocess.check_output(['uname', '-a']) निष्पादित करता है, यह सिद्ध करते हुए कि safe=True इस कोड पथ को नियंत्रित नहीं करता |
| दिनांक | 26 जून, 2026 |
| दायरा | स्थानीय Splunk Enterprise 10.0.6 शोध इंस्टेंस (127.0.0.1:8089) |
| वर्गीकरण | गोपनीय |