
# iOS 15.0 - 15.1.1 के लिए desc_race एक्सप्लॉइट (स्थिर कर्नेल r/w प्रिमिटिव्स के साथ) (CVE-2021-30955)
"desc_race" (CVE-2021-30955) iOS 15.0 - 15.1.1 के लिए शोषण (स्थिर कर्नेल r/w प्राइमिटिव्स के साथ)
IOSurfaceClient ऐरे की क्षमता को 0x2000 तक बढ़ाएँ, लक्ष्य एक पॉइंटर लिखना है जिसकी सामग्री पूरी तरह से नियंत्रित हो और फिर कर्नेल r/w प्राप्त करने के लिए IOSurfaceRootUserClient इंटरफेस का उपयोग करें। ऐरे का आकार 0x2000 * 8 बाइट्स है, इस प्रकार यह KHEAP_KEXT के बड़े मैप में रहता है जो KHEAP_DEFAULT के समान है।
फिर 0x4000 बाइट्स के ool डिस्क्रिप्टर के साथ एक सहायक kmsg का उपयोग करके 0x4000 बाइट्स का कर्नेल बफर आवंटित करें जिसे पीछे से अधिलेखित किया जाएगा। और फिर आवंटित संदेश के साथ बग को ट्रिगर करें, जिसे डबल कॉपीइन kmsg कहा जाता है, जो सहायक कर्नेल बफर के ठीक पीछे रखा गया है। और इस संदेश में एक ool पोर्ट्स डिस्क्रिप्टर होता है जिसकी गिनती 0x2000 है, इस प्रकार यह IOSurfaceClient ऐरे के काफी करीब होगा।
फिर आपको सहायक संदेश प्राप्त करना चाहिए। यदि रेसिंग सफल होती है, तो ool पोर्ट्स डिस्क्रिप्टर उजागर हो जाएगा और हम IOSurfaceClient ऐरे का पता लगा सकते हैं।
फिर 0x4000 बाइट्स का कर्नेल बफर फिर से आवंटित करें, यह उपरोक्त कर्नेल बफर पर कब्जा कर लेगा। इस बार मैं उचित बॉडी के साथ एक नकली kmsg हेडर बनाता हूँ। फिर मैं डबल कॉपीइन kmsg को नष्ट कर देता हूँ, कर्नेल हमारे नकली हेडर से शुरू होगा। मैं एक नकली mach_msg_ool_descriotpor_t का उपयोग करता हूँ और पूरी तरह से नियंत्रित कॉपी के साथ vm_copy_discard() को ट्रिगर करता हूँ। कॉपी को नष्ट करने के दौरान, सबसे मूल्यवान पंक्तियाँ _vm_map_entry_unlink_ll में हैं:
1
2
3
4
5
6
#define _vm_map_entry_unlink_ll(hdr, entry) \
MACRO_BEGIN \
(hdr)->nentries--; \
(entry)->vme_next->vme_prev = (entry)->vme_prev; \
(entry)->vme_prev->vme_next = (entry)->vme_next; \
MACRO_END
entry हमारे नियंत्रण में है, यह हमें एक उत्तम r/w प्राइमिटिव देता है। मैं इसका उपयोग IOSurfaceClient ऐरे में एक नियंत्रित पॉइंटर लिखने के लिए करता हूँ, और फिर IOSurfaceRootUserClient इंटरफेस के साथ मिलकर कर्नेल r/w प्राप्त करता हूँ।
इस शोषण को विकसित करते समय मैंने bazad की पोस्ट "One byte to rule them all" को बार-बार पढ़ा है, और उनके शोषण में वही तकनीक, vm_copy_t को नकली बनाना, का उपयोग किया है। लेकिन कुछ बिंदु भिन्न हैं।
XNU संदेश पर हस्ताक्षर करता है और हम अब एक दूषित kmsg प्राप्त नहीं कर सकते।
विनाश प्रक्रिया में, मैं vm_object की mapping_in_progress सेट करता हूँ ताकि कर्नेल स्पिन करे और इस प्रकार ज़ोन जाँच के कारण पैनिक न हो।
bazad को उनकी महान पोस्ट के लिए, WangTielei को यह बताने के लिए कि IOSurfaceClient इंटरफेस अब r/w प्राइमिटिव के लिए अमान्य हैं, और pedantcoder को उनकी दयालुता के लिए बहुत धन्यवाद।