
CVE-2015-0057 के लिए विस्तृत तकनीकी विश्लेषण और exploit कार्यान्वयन, जो win32k.sys में use-after-free भेद्यता है, जिसमें XP से 8.1 तक के 32-बिट और 64-बिट Windows सिस्टम शामिल हैं।
लेखक: Aaron Adams
अनुवाद: 55-AA
अनुवादक का नोट: इस लेख के कुछ भागों का अनुवाद सारांश रूप में किया गया है। मूल पाठ के लिए कृपया मूल लेख देखें।
परिभाषाएँ:
इस वर्ष की शुरुआत में, मैं win32k.sys (CVE-2015-0057) में एक दिलचस्प भेद्यता के संपर्क में आया और इसे 32-बिट और 64-बिट सिस्टम पर स्थिर रूप से शोषण करने में सफल रहा, जो XP से Windows 8.1 तक (कुछ अपवादों के साथ) लागू होता है। यह लेख विस्तार से वर्णन करता है कि मैंने इन दोनों प्लेटफार्मों पर शोषण कैसे पूरा किया, अंत में कुछ अतिरिक्त चीजें भी संलग्न हैं। साथ ही, यह भी बताया गया है कि SMEP सक्षम Windows 8.1 पर कम अखंडता अनुमति वाले प्रक्रिया के तहत शोषण कैसे किया जाए।
यह लेख काफी लंबा है, मैंने इस भेद्यता का शोषण करने की जटिलता को छिपाने के बजाय यथासंभव अधिक विवरण प्रदान करने का प्रयास किया है, हालाँकि मैंने कुछ विवरणों को टाला भी है। उम्मीद है कि ये विवरण सभी के लिए सहायक होंगे।
10 फरवरी 2015 को, माइक्रोसॉफ्ट ने MS15-010 से संबंधित विवरण जारी किए। इस बग को सबसे पहले enSilo के Udi Yavo ने खोजा था। Udi ने ब्रेकिंग मैलवेयर ब्लॉग पर एक अच्छा विश्लेषण दिया था "one bit rule-bypassing windows 10 protections using single bit"। मैं इस लेख को ध्यान से पढ़ने की सलाह देता हूं ताकि इस बग को गहराई से समझा जा सके, हालाँकि मैं इस लेख में यथासंभव अधिक से अधिक विवरण प्रदान करूंगा, जिसमें उन बाधाओं का विवरण शामिल है जिन्हें भेद्यता को ट्रिगर करते समय दूर करना होगा। इस भेद्यता का शोषण करना बहुत दिलचस्प है, अधिकांश विवरण Udi के ब्लॉग से लिए गए हैं, और यहाँ उनका बयान है:
उचित प्रकटीकरण: हालांकि यह ब्लॉग तकनीकी है, हम किसी भी कोड या पूर्ण विवरण का खुलासा नहीं करेंगे ताकि किसी भी तकनीकी विशेषज्ञ द्वारा इस भेद्यता के शोषण को पुन: उत्पन्न नहीं किया जा सके।
इस भेद्यता का शोषण करने के अतिरिक्त पुरस्कार के रूप में, हमें एक पोकेमॉन का विकास मिला: तकनीकी पोकेमॉन। मुझे लगता है कि मुझे Udi को कुछ श्रेय देना चाहिए क्योंकि उन्होंने इस बग की खोज की और ब्लॉग पर संबंधित स्थिति और इस बग का शोषण करने के विवरण प्रदान किए, ये चीजें बहुत उपयोगी थीं।
पहले, मैंने कभी win32k.sys की भेद्यता का शोषण नहीं किया था, न ही मैं उपयोगकर्ता मोड कॉलबैक और कई संबंधित API से परिचित था, इसलिए मैं उन प्रसिद्ध सुरक्षा शोधकर्ताओं के प्रति आभार व्यक्त करता हूं जिन्होंने ऑनलाइन नए संसाधन उपलब्ध कराए, जैसे Skywing, Tarjei Mandt, Alex Ionescu और j00ru आदि। इन लोगों ने इतनी सारी तकनीकी जानकारी सार्वजनिक रूप से उपलब्ध कराई, इन सभी की प्रशंसा होनी चाहिए। मैंने मुख्य रूप से Tarjei Mandt के एक लेख Win32k.sys शोषण पेपर का संदर्भ लिया।
जब मैं इस भेद्यता का शोषण लिख रहा था, तब एक उत्कृष्ट रिवर्स इंजीनियर ने CVE-2015-1701 का स्थिर शोषण लागू किया था, जिसमें उपयोगकर्ता मोड कॉलबैक के उदाहरण कोड उपयोगी थे। उस लेखक को धन्यवाद।
यह ध्यान देने योग्य है कि मेरा नीचे का विश्लेषण Windows 7 पर किया गया था, क्योंकि ऐसा लगता है कि यह एकमात्र संस्करण है जहाँ win32k.sys के सभी संरचनाओं में संबंधित प्रतीक हैं। ये प्रतीक अधिकांशतः Win32k.sys के अन्य संस्करणों की संरचनाओं में उपलब्ध हैं। किसी कारण से, माइक्रोसॉफ्ट ने Windows 8 से इन प्रतीकों को हटा दिया।
अंत में, मैं यह कहना चाहूंगा कि मेरी शोषण विधि काफी जटिल है। यह पूरी तरह संभव है कि कोई आसान तरीका हो, बस मैंने इसे नहीं खोजा। मैं यह सुनना चाहूंगा कि किसी ने भिन्न विधि का उपयोग किया हो। किसी भी तरह से, मुझे आशा है कि यह सब win32k.sys की भेद्यताओं पर शोध के लिए उपयोगी है।
नीचे हम win32k!xxxEnableWndSBArrows के डिसअसेंबली कोड में इस बग को देखते हैं, जो एक सूक्ष्म बग है:
पैच न किए गए संस्करण में:
.text:FFFFF97FFF1B157D mov r8d, r13d
.text:FFFFF97FFF1B1580 mov rdx, r14
.text:FFFFF97FFF1B1583 call xxxDrawScrollBar ; उपयोगकर्ता मोड कॉलबैक ट्रिगर करता है
.text:FFFFF97FFF1B1588 jmp short loc_FFFFF97FFF1B1519
[...]
.text:FFFFF97FFF1B1519 mov eax, [rbx] ; tagSBINFO पॉइंटर को बिना जांचे संदर्भित करता है
.text:FFFFF97FFF1B151B mov ebp, 0FFFFFFFBh
.text:FFFFF97FFF1B1520 xor eax, esi
उपरोक्त कोड में, Win32K!xxxdrawscrollbar उपयुक्त परिस्थितियों में उपयोगकर्ता स्थान पर कॉलबैक कर सकता है, जहाँ tagSBINFO का पॉइंटर हमलावर द्वारा मुक्त किया जा सकता है, और जब कोड वापस ऊपर आता है, तो 0xFFFFF97FFF1B1519 पर कोड एक अमान्य पॉइंटर का संदर्भ लेगा।
पैच किए गए संस्करण में:
.text:FFFFF97FFF1D69C3 xor r8d, r8d
.text:FFFFF97FFF1D69C6 mov rdx, rbp
.text:FFFFF97FFF1D69C9 call xxxDrawScrollBar ; उपयोगकर्ता मोड कॉलबैक ट्रिगर करता है
.text:FFFFF97FFF1D69CE cmp rbx, [rdi+0B0h] ; जांचता है कि tagSBINFO पॉइंटर सही है
---.text:FFFFF97FFF1D69D5 jz short loc_FFFFF97FFF1D69E4; यदि सही है तो मूल प्रवाह जारी रखें
| .text:FFFFF97FFF1D69D7 mov rcx, rbp
| .text:FFFFF97FFF1D69DA call _ReleaseDC
| .text:FFFFF97FFF1D69DF jmp loc_FFFFF97FFF1D6958 ; फंक्शन से बाहर कूदें
|->.text:FFFFF97FFF1D69E4 mov eax, [rbx] ; सुरक्षित रूप से सही tagSBINFO पॉइंटर का उपयोग करें
.text:FFFFF97FFF1D69E6 xor eax, r14d
उपरोक्त पैच किए गए संस्करण में, हम देखते हैं कि tagSBINFO पॉइंटर का उपयोग करने से पहले शून्यता की जाँच की गई है। संबंधित संरचना की जानकारी बाद में दी जाएगी।
इस शोषण को लागू करते समय, हमने कई बार भ्रष्टाचार (corruption) किया। और उनमें से एक भ्रष्टाचार के दौरान हमने इस भेद्यता को ट्रिगर किया।
इस बग का तकनीकी मूल एक डेस्कटॉप हीप का UAF (use-after-free) है। शुरुआत में, यह मुझे भ्रमित कर रहा था, क्योंकि मैं win32k.sys के उपयोगकर्ता मोड कॉलबैक तंत्र से परिचित नहीं था, और यह भी स्पष्ट नहीं था कि यह कैसे काम करता है। इसलिए, मैंने सोचा कि यह एक लॉक रेस कंडीशन है जो UAF का कारण बनती है। वास्तव में, उस संरचना के लॉक का सही ढंग से उपयोग किया गया था, और इसका प्रवाह अपेक्षित था। संक्षेप में, समस्या का असली कारण है:
बस इतना ही, उपयोगकर्ता मोड कॉलबैक को छोड़कर, यह चरण काफी स्पष्ट है।
लेकिन, हम भ्रष्टाचार कैसे करते हैं और क्यों करते हैं? जैसा कि Udi के ब्लॉग में उल्लेख किया गया है, आप एक निश्चित स्थान पर 2 बिट सेट या क्लियर कर सकते हैं, और इस स्थान को सिस्टम कोड tagSBINFO संरचना में WSBflags फ़ील्ड मानता है। यह UAF का मानक उपयोग नहीं है, लेकिन लेख में एक संकेत दिया गया है कि यह कैसे काम करता है, जिसे मैं अगले खंडों में समझाऊंगा। पहले, आइए समझें कि हम इन बिट्स को कैसे नियंत्रित करते हैं।
tagSBINFO संरचना (32-बिट और 64-बिट में समान):