
CVE-2023-28252 के लिए तकनीकी विश्लेषण और प्रूफ-ऑफ-कॉन्सेप्ट एक्सप्लॉइट, जो Nokoyawa रैंसमवेयर हमलों में उपयोग की जाने वाली Windows कॉमन लॉग फ़ाइल सिस्टम (CLFS) ड्राइवर विशेषाधिकार वृद्धि भेद्यता है।
फरवरी 2022 से एक नए रैंसमवेयर की सूचना मिली थी जो Windows 0-day भेद्यता का उपयोग करता प्रतीत होता है, Trend Micro द्वारा किए गए शोध के अनुसार।
इस रैंसमवेयर के बारे में अधिक जानकारी इस लिंक पर मिल सकती है।
Kaspersky के विश्लेषण के अनुसार, Nokoyawa रैंसमवेयर समूह ने जून 2022 से Common Log File System (CLFS) ड्राइवर को लक्षित करने वाले अन्य exploits का उपयोग किया है, जिनमें समान लेकिन भिन्न विशेषताएँ हैं, और ये सभी एक ही exploit डेवलपर से जुड़े हैं।
अप्रैल 2023 में जब Microsoft ने पैच जारी किया, तो CVE-2023-28252 को निर्दिष्ट किया गया।
इससे पहले, 2022 में उसी घटक में एक समान बग पर हमने शोध किया था, और इस ब्लॉगपोस्ट में प्रलेखित किया था।
विश्लेषण का सामना करने के लिए, .blf फ़ाइल प्रारूप को जानना आवश्यक है, जिसे CLFS.sys नामक भेद्य Common Log File System ड्राइवर द्वारा संभाला जाता है और जो system32 के भीतर ड्राइवर फ़ोल्डर में होता है।
इस फ़ाइल प्रकार के बारे में अधिक जानकारी नीचे दिए गए लिंक में मिल सकती है:
https://github.com/ionescu007/clfs-docs/blob/main/README.md
https://www.coresecurity.com/core-labs/articles/understanding-cve-2022-37969-windows-clfs-lpe
यह विश्लेषण Windows 11 21H2, clfs.sys version 10.0.22000.1574 के लिए किया गया है, हालाँकि यह Windows 10 21H2, Windows 10 22H2, Windows 11 22H2 और Windows server 2022 पर भी काम करता है।
पिछले Windows संस्करणों में, कुछ मानों को समायोजित करना आवश्यक है, अन्यथा हम BSOD उत्पन्न कर देंगे।
Microsoft Patch Tuesday अप्रैल 2023.
आप ड्राइवर संस्करण को दिखाए अनुसार जाँच सकते हैं
जब भेद्यता प्रकाशित हुई, अप्रैल 2023 में, मैंने Esteban Kazimirow के साथ CLFS.sys ड्राइवर का रिवर्सिंग करना शुरू किया, हालाँकि इस मामले में केवल पैच का विश्लेषण करना यह अनुमान लगाना बहुत कठिन था कि बग कहाँ था और उसे कैसे ट्रिगर किया जाए, क्योंकि शोषण बहुत जटिल है।
बाद में, एक ब्लॉगपोस्ट प्रकाशित हुआ जिसके लेखक ने एक मैलवेयर नमूने से, HexRays द्वारा डीकंपाइल किए गए कोड के कुछ हिस्से और कुछ जानकारी दिखाई, जिसने मार्गदर्शन किया कि शोषण को कहाँ सामना करना था।
स्पष्ट रूप से प्रदान की गई जानकारी पूरी नहीं थी, लेकिन इस सहायता के बिना PoC और बाद में एक कार्यात्मक exploit बनाना संभव नहीं होता।
समझने में आसानी के लिए, हम पहले समझाएंगे कि PoC कैसे बनाया जाए और फिर हम भेद्यता विश्लेषण करेंगे।
इस ब्लॉगपोस्ट में दो खंड हैं:
PoC बनाना:
1-शोषण के लिए आवश्यक कर्नेल पते प्राप्त करें
2-.blf फ़ाइलें बनाने के लिए पथ तैयार करना:
3-CreateLogFile() फ़ंक्शन का उपयोग करके "trigger blf" फ़ाइल बनाना
4-"trigger blf" फ़ाइल तैयार करना
5-trigger blf के BASE BLOCK का कर्नेल पता प्राप्त करना
6-trigger blf के हैंडल के साथ AddLogContainer को कॉल करना
7-spray blf फ़ाइलें तैयार करना
8-spray करने के लिए मेमोरी तैयार करना
9-बग को ट्रिगर करना
डीबगिंग:
1-मेमोरी स्प्रे की जाँच करना
2-trigger blf के RecordOffset[12] को देखना
3-spray blf फ़ाइल में iFlushBlock मान को देखना
4-यह BLOCK 0 CONTROL के बजाय BLOCK 1 SHADOW से क्यों पढ़ता है ?
5-blf spray फ़ाइलों में checksum शून्य के बराबर क्यों होता है ?
6-शोषण समाप्त करना।
7-वास्तविक पैच
मैं कुछ आवश्यक कर्नेल पते प्राप्त करने के लिए InitEnvironment नामक एक फ़ंक्शन बनाऊँगा।
अपनी प्रक्रिया का EPROCESS पता प्राप्त करें और उसे g_EProcessAddress वेरिएबल में संग्रहीत करें, फिर SYSTEM प्रक्रिया का EPROCESS पता प्राप्त करें और उसे system_EPROCESS में संग्रहीत करें, फिर अपनी प्रक्रिया के मुख्य थ्रेड का EHTREAD पता प्राप्त करें और उसे g_EThreadAddress में संग्रहीत करें और अंत में PREVIOUS MODE का पता, जो PoC के इस संस्करण में उपयोग नहीं किया जाएगा।

यह विधि सर्वविदित है, GetObjectKernelAddress फ़ंक्शन पहले तर्क SystemExtendedHandleInformation के साथ NtQuerySystemInformation को दो बार कॉल करता है, पहला कॉल गलत आकार के साथ किया जाता है और त्रुटि लौटाता है, लेकिन सही आकार भी लौटाता है जो दूसरे कॉल में उपयोग होता है और सभी हैंडल की जानकारी प्राप्त करता है, फिर लूप में प्रत्येक हैंडल की जानकारी से गुजरता है और सही handleinfo के Object फ़ील्ड में कर्नेल में खोजा गया पता प्राप्त करता है।

मुझे CLFS.sys द्वारा निर्यात किए गए निम्नलिखित फ़ंक्शनों के कर्नेल पते भी चाहिए:
• ClfsEarlierLsn
• ClfsMgmtDeregisterManagedClient
और NTOSKRNL.exe से निर्यात किए गए फ़ंक्शन
• RtlClearBit/PoFxProcessorNotification
• SeSetAccessStateGenericMapping
इन पतों को प्राप्त करने के लिए वही समान विधि उपयोग की जाती है जो दोनों मॉड्यूलों का कर्नेल आधार प्राप्त करने के लिए प्रयोग होती है, NtQuerySystemInformation को दो बार कॉल करके, लेकिन इस मामले में पहला तर्क SYSTEM_INFORMATION_CLASS होगा (PoC में हम इस उद्देश्य के लिए FindKernelModulesBase फ़ंक्शन का उपयोग करते हैं)।
फिर यह LoadLibrary को कॉल करके CLFS.sys और NTOSKRNL.exe को यूज़र मोड में सामान्य मॉड्यूल के रूप में लोड करता है, GetProcAddress के साथ यूज़र मोड में पते प्राप्त करता है और फिर प्रत्येक से imagebase घटाता है, जिससे फ़ंक्शन का ऑफ़सेट प्राप्त होता है और अंत में प्रत्येक ऑफ़सेट को संबंधित कर्नेल आधारों में जोड़ता है और इस प्रकार सभी आवश्यक फ़ंक्शनों के कर्नेल पते प्राप्त करता है।

मैं createInitialTriggerBlfFile नामक एक फ़ंक्शन बनाता हूँ जो एक .blf फ़ाइल उत्पन्न और लिखेगा।
CreateLogFile में तर्क के रूप में उपयोग किया जाने वाला पथ सामान्य पथ से भिन्न होता है, उदाहरण के लिए C:\Users\Public फ़ोल्डर में स्थित 1280.blf फ़ाइल को खोलने के लिए, हमें पथ LOG:C:\Users\Public\1280. सेट करना होगा। यह stored_name_CreateLog वेरिएबल में सहेजा जाएगा।
मैं यह wsprintfW() का उपयोग करके करता हूँ क्योंकि stored_env पहले पर्यावरण चरों से प्राप्त पथ C:\Users\Public संग्रहीत करता है। इस स्ट्रिंग में मैं LOG: स्ट्रिंग जोड़ूँगा और अंत में एक यादृच्छिक नाम जोड़ूँगा, बिना .blf एक्सटेंशन के।
