
प्रूफ ऑफ कॉन्सेप्ट CVE-2025-24990 (Agere Systems का ड्राइवर)
ltmdm64.sys)यह ड्राइवर बहुत पुराना है और मेरे टेस्ट मशीन पर डिफ़ॉल्ट रूप से लोड नहीं होता है, इसलिए मैं इसे BYOVD परिदृश्य में एक्सप्लॉइट करूंगा। दिलचस्प बात यह है कि मेरे शोध के अनुसार यह ड्राइवर विंडोज 7 पर मौजूद है और इसमें कम से कम एक बग है। यहाँ
उस समय, MSRC ने कोई कार्रवाई नहीं की 🤡
इस ड्राइवर के भीतर कुछ IOCTL METHOD_NEITHER का उपयोग करते हैं लेकिन यह जाँच नहीं करते हैं कि कॉलर द्वारा आपूर्ति किया गया एड्रेस बफर यूज़र-मोड से है या कर्नेल-मोड से। यहाँ एक उदाहरण IOCTL कोड है जिसे मैंने OSR के साथ डिकोड किया है:
इसका मतलब है कि आप DeviceIoControl API को एक कर्नेल एड्रेस दे सकते हैं और ड्राइवर इसे सामान्य रूप से संभालेगा।
ध्यान दें कि कर्नेल एड्रेस लीक करने के लिए आपको पहले kASLR को बायपास करना होगा, मैं EnumDeviceDrivers का उपयोग करूंगा (विंडोज 24h2 पर आपको ऐसा करने के लिए SeDebugPriv की आवश्यकता है)।
समस्या IOCTL 0x802b200f (ud_response) में है। फिर से, यह IOCTL डिस्पैच उस एड्रेस को मान्य नहीं करता है जिसे मैं यूज़र-मोड से आपूर्ति करता हूं, लेकिन मैं इसका उपयोग बाद में करूंगा।
ud_response ll_load_diagnostics को कॉल करता है, और मैं निम्नलिखित कोड तक पहुंचूंगा:
शुरुआत में ग्लोबल वेरिएबल eeprom इनिशियलाइज़ नहीं होता है, इसलिए इसमें NULL होगा। यहाँ एक सरल कोड है जो इसे ट्रिगर करेगा।
मैं इसका उपयोग बाद में करूंगा।
यह IOCTL केवल ड्राइवर वर्जन स्ट्रिंग "8.36" को संख्या 0x836 (एक DWORD) में परिवर्तित करता है और इसे कॉलर द्वारा आपूर्ति किए गए एड्रेस पर लिखता है (METHOD_NEITHER के कारण)। तकनीकी रूप से, मैं इन चार बाइट्स (36 08 00 00) को एक मनमाने कर्नेल एड्रेस पर लिख सकता हूं। मैं इसका उपयोग ड्राइवर के ग्लोबल वेरिएबल्स को ओवरराइट करने और निष्पादन प्रवाह को बदलने के लिए करूंगा।
मैं इस 0x802b2003 को IOCTL_GET_VERSION कहूंगा
मनमाना नल 1 बाइट:
NULL-डीरेफरेंस मामले पर वापस जाते हुए, मैं एक निश्चित एड्रेस (0x083600000000) आवंटित करने के लिए VirtualAlloc API का उपयोग करता हूं। फिर मैं IOCTL_GET_VERSION का उपयोग करके *(eeprom + 4) पर ऊपर वर्णित चार बाइट्स लिखता हूं। जब ड्राइवर बाद में eeprom को डीरेफरेंस करता है, तो यह मेरे द्वारा आवंटित एड्रेस से पढ़ेगा।
NULL डीरेफरेंस को ठीक करने के बाद, IOCTL बफर आकार के आधार पर, मेरे द्वारा यूज़र-मोड से आपूर्ति किए गए एड्रेस पर एक स्ट्रिंग लिखता है।
यह कोड केवल यह प्रदर्शित करता है जो मैंने ऊपर वर्णित किया है, एक बफर आवंटित करें और इसे 0xAA से भरें, NULL डीरेफरेंस को ठीक करें, फिर ड्राइवर को कॉल करें। ध्यान दें कि मैं 11 बाइट्स आवंटित करता हूं लेकिन ड्राइवर को केवल 10 का बफर आकार प्रदान करता हूं ताकि यह देख सकूं कि यह कैसे व्यवहार करता है।
यह मेरे बफर में बाइट्स का एक निश्चित अनुक्रम लिखता है और फिर अंतिम बाइट (11वें) को नल कर देता है, भले ही मैं केवल 10 का आकार प्रदान करता हूं। यह मेरे बफर में अंतिम 0xAA को 0x00 से बदल देता है। यह इंगित करता है कि यदि मैं 0 का आकार प्रदान करता हूं, तो ड्राइवर अभी भी लक्षित एड्रेस पर एक एकल 0x00 बाइट लिखता है।
मनमाना घटाव
अब मेरे पास नल और निश्चित 4 बाइट्स के साथ मनमाना है, आइए एक और प्रिमिटिव बनाएं।
यह IOCTL ग्लोबल LtMsgEvent को मेरे यूज़र बफर पर सेट करेगा फिर जाँच करेगा कि WDM नल है या नहीं फिर इसे फिर से शून्य पर सेट करेगा।
फिर 0x802b2207 में यह ObfReferenceObject API को कॉल करेगा।
प्रारंभिक अवस्था में WDM नल है लेकिन IOCTL_GET_VERSION की मदद से मैं WDM को 0x36 पर सेट कर सकता हूं (इसका आकार केवल 1 बाइट है) और LtMsgEvent अभी भी मेरा बफर है। फिर मैं WDM को नल कर दूंगा और 0x802b2207 को कॉल करूंगा। अंत में ObfReferenceObject तक पहुंचूंगा। मैं इन दो ioctl को IOCTL_SET_LtMsgEvent और IOCTL_DEREF_LtMsgEvent कहूंगा।
ObfReferenceObject का उपयोग करने वाली एक्सप्लॉइट तकनीक हमारे KTHREAD के PreviousMode को UserMode से KernelMode में बदल देती है, आप इसके बारे में यहाँ) पढ़ सकते हैं। हालाँकि, विंडोज़ ने इस एक्सप्लॉइट को ठीक कर दिया है, इसलिए हम इसका उपयोग नहीं कर सकते।
लेकिन ObfReferenceObject में प्रिमिटिव अभी भी मौजूद है। API हमारे द्वारा प्रदान किए गए एड्रेस से 0x30 घटाता है, परिणाम को 8-बाइट पूर्णांक में बदलता है, और फिर 1 घटाता है।
*(signed long long)(LtMsgEvent-0x30) -= 1
लेकिन समस्या यह है कि यह जाँचता है कि अगला मान 0 है या वर्तमान मान < 1 है (8-बाइट हस्ताक्षरित पूर्णांक के रूप में व्याख्या की गई)। यदि कोई भी स्थिति सत्य है, तो यह KeBugCheckEx पर कूद जाता है और सिस्टम को क्रैश कर देता है।
मनमाना लेखन
मनमाना घटाव के साथ, मुझे बाइट 0xFF लिखने के लिए कहीं और खोजने की आवश्यकता है फिर इसे उस बाइट तक घटाएं जो मुझे चाहिए और मुझे यह ioctl 0x802b2243 मिला: