
CVE-2023-41993 के लिए प्रूफ-ऑफ-कॉन्सेप्ट शोषण, सफारी में एक WebKit JIT टाइप कन्फ्यूज़न। हीप मैनिपुलेशन और GetterSetter कन्फ्यूज़न के माध्यम से addrof/fakeobj प्राइमिटिव प्रदान करता है, जो WebContent प्रक्रिया में आर्बिट्रेरी रीड/राइट सक्षम बनाता है।
CVE-2023-41993 के लिए PoC शोषण। यह केवल addrof/fakeobj तक लिखा गया है। विश्वसनीयता बहुत अच्छी नहीं है। यदि आप इसे बेहतर बनाना चाहते हैं, तो स्ट्रक्चर आईडी को स्प्रे करने का प्रयास करें।
https://po6ix.github.io/POC-for-CVE-2023-41993/pwn.html
मैंने कई अनुरोधों के बाद GitHub Pages के साथ होस्ट करने का निर्णय लिया है।
मुझे शुभकामनाएं दें कि GitHub मुझे ब्लॉक न करे...
ऐसा इसलिए है क्योंकि pwn फ़ंक्शन में परिभाषित फ़ैक्टर मान आपके डिवाइस के लिए सही नहीं है।
ऐसे मामले के लिए, मैंने इसे 87 और 1088 के बीच यादृच्छिक मान का उपयोग करने के लिए बनाया है।
तो आप कभी-कभी रिफ्रेश करके सही फ़ैक्टर मान पा सकते हैं।
यह संभाव्य रूप से 100 प्रयासों के भीतर काम करना चाहिए।
यह भी अच्छा होगा यदि आप मुझे सफलता के मामले से दिखाई गई जानकारी भेज सकें।
यह आपको Safari वेबकंटेंट प्रक्रिया के लिए r/w प्रिमिटिव देता है।
लेकिन इसे वास्तव में उपयोगी बनाने के लिए, आपको अन्य घटकों के साथ चेन करने की आवश्यकता होगी।
आप इसके लिए एक विस्तृत लेख चाह सकते हैं, लेकिन दुर्भाग्य से मेरे पास इसे लिखने का समय नहीं है। इसलिए मैं यहां कुछ नोट लिख रहा हूं ताकि आप समझ सकें कि यह कैसे काम करता है।
यदि आप कमिट देखते हैं, तो यह HeapLocation के लिए बदलाव के बारे में है। यह जानने के लिए एक नया फ़ैक्टर जोड़ा गया है कि नोड्स समान हैं या नहीं। यह हमें बताता है कि GetByOffset, MultiGetByOffset जैसे नोड्स भ्रमित हो सकते हैं। लेकिन वास्तव में यह केवल ऑफसेट के बारे में है। मान लीजिए कि इसमें दो GetByOffset नोड्स हैं जिनके अलग-अलग ऑफसेट हैं। उनमें से एक CSEed हो जाएगा और शेष का उपयोग किया जाएगा। तो यह मूल रूप से ऑफसेट भ्रम है, लेकिन यह आपको किसी भी मनमाने ऑफसेट तक पहुंच नहीं देता है। क्योंकि इस प्रकार के नोड्स को CSE करने के लिए उन्हें LICMPhase द्वारा hoisted किए जाने की आवश्यकता होती है। उस प्रकार के नोड्स के लिए जो लेखन ऑपरेशन करते हैं, उन्हें इस चरण में hoisted करने की अनुमति नहीं है। तो PutByOffset, MultiPutByOffset नोड्स के साथ वही भ्रम नहीं होता है। साथ ही, जब GetByOffset को hoisted किया जाता है, तो safeToExecute फ़ंक्शन को यह देखने के लिए कॉल किया जाता है कि नोड निष्पादित करने के लिए वैध है और केवल स्टोरेज क्षमता (inline/ool) से कम ऑफसेट तक पहुंच की अनुमति देता है। तो इसका शोषण करने का विचार GetterSetter था। यदि आप एक प्रॉपर्टी को परिभाषित करने के लिए Object.__defineGetter__ कॉल करते हैं, तो GetterSetter ऑब्जेक्ट बनाया जाता है लेकिन प्रॉपर्टी स्टोरेज में संग्रहीत होता है और यह सामान्य रूप से सुलभ नहीं है। लेकिन आप इस ऑफसेट हेरफेर के साथ कर सकते हैं जो आपके पास है। फिर आप एक टाइप कंफ्यूजन को ट्रिगर करने के लिए Object फ़ंक्शन को कॉल करते हैं।
JSObject* JSCell::toObjectSlow(JSGlobalObject* globalObject) const
{
Integrity::auditStructureID(structureID());
ASSERT(!isObject());
if (isString())
return static_cast<const JSString*>(this)->toObject(globalObject);
if (isHeapBigInt())
return static_cast<const JSBigInt*>(this)->toObject(globalObject);
ASSERT(isSymbol());
return static_cast<const Symbol*>(this)->toObject(globalObject);
}
यह एक SymbolObject बनाएगा जिसमें GetterSetter एक आंतरिक मान के रूप में होगा। और यह गलत है, क्योंकि SymbolObject का यह आंतरिक मान एक Symbol इंस्टेंस होना चाहिए न कि GetterSetter।
let getterSetter = jitme(1);
let symbolObject = Object(getterSetter);
symbolObject.description; // call the getter
String Symbol::description() const
{
auto& uid = m_privateName.uid();
return uid.isNullSymbol() ? String() : uid;
}
फिर जब आप डिस्क्रिप्शन गेट्टर को कॉल करते हैं, तो यह एक String इंस्टेंस लौटाएगा। यह Symbol.m_privateName और GetterSetter.m_getter के बीच एक टाइप कंफ्यूजन है। हर बार जब आप इस गेट्टर को कॉल करते हैं, यह m_privateName.m_uid के रेफरेंस काउंटर फील्ड को बढ़ाएगा जो ऑफसेट 0x0 पर है। यह बहुत उपयोगी है, क्योंकि यह ऑफसेट वह है जहां गेट्टर फ़ंक्शन की स्ट्रक्चर आईडी है। इस फ़ंक्शन को कुछ बार कॉल करके, आप JSFunction इंस्टेंस की स्ट्रक्चर आईडी बदल सकते हैं। मैंने एक और टाइप तैयार किया है जिसमें कई प्रॉपर्टी हैं। फिर यदि आप स्ट्रक्चर आईडी को इसके समान सिंक करते हैं, तो आप प्रॉपर्टी स्टोरेज पर oob राइट कर सकते हैं। यह सीधे addrof/fakeobj प्रिमिटिव देता है।