flawopen.com/Teardowns/cve-2024-30051-windows-dwm-privilege-escalation

● CVE-2024-30051 · CVSS 9.8 · अति गंभीर
सुरक्षा अनुसंधान · FlawOpen

CVE-2024-30051: Windows DWM कोर लाइब्रेरी हीप ओवरफ़्लो प्रिविलेज एस्केलेशन विश्लेषण

dwmcore.dll में अनचेक्ड 32-बिट पूर्णांक जोड़ (integer addition) के कारण स्थानीय मैलवेयर ने छोटे आकार का हीप बफ़र आवंटित कर मेमोरी दूषित की और SYSTEM विशेषाधिकार प्राप्त किए।

💡 आसान भाषा में (ELI5)

कल्पना कीजिए कि एक शिपिंग कंपनी आपको 10 सामान रखने वाला एक छोटा बॉक्स देती है क्योंकि आपने कहा था 'मेरे पास 5 सामान प्लस 5 सामान हैं'। लेकिन आप जानबूझकर इतने विशाल नंबर देते हैं कि कंप्यूटर का साधारण जोड़ 32-बिट की सीमा पार करके वापस शून्य पर आ जाता है—कंप्यूटर सोचता है कि '4 अरब प्लस 10 सामान बराबर सिर्फ 10 सामान'। कंप्यूटर एक छोटा डिब्बा तैयार करता है, आप उसमें 4 अरब सामान ठूंस देते हैं, और वह पूरे गोदाम के फर्श पर बिखर जाता है, जिससे आप पूरे सुरक्षा परिसर पर नियंत्रण पा लेते हैं।

इस पेज के मुख्य शब्द

Desktop Window Manager (dwmcore.dll)
विंडोज़ का मुख्य सबसिस्टम जो विज़ुअल विंडो फ़्रेम, डायरेक्ट कंपोज़िशन रेंडरिंग और डेस्कटॉप ग्राफ़िक्स को संयोजित करने के लिए ज़िम्मेदार है।
पूर्णांक ओवरफ़्लो / रैप-अराउंड (Integer Overflow)
32-बिट अनसाइन्ड अंकगणित में 0xFFFFFFFF + 1 का मान वापस 0 हो जाता है। यदि हीप बफ़र आवंटित करने से पहले यह गणना की जाए, तो एक अत्यंत छोटा बफ़र बनता है।
पूल व हीप करप्शन (Heap Corruption)
हीप चंक की सीमा से परे पड़ोस के एलोकेटर स्ट्रक्चर्स में अनधिकृत डेटा लिखना, जिससे स्थानीय हमलावर NT AUTHORITY\SYSTEM प्रिविलेज हासिल कर लेता है।
सुरक्षित अंकगणित फ़ंक्शन (ULongAdd)
माइक्रोसॉफ्ट की सुरक्षित रनटाइम लाइब्रेरी का फ़ंक्शन, जो योग लौटाने से पहले यह पुष्टि करता है कि जोड़ में पूर्णांक ओवरफ़्लो तो नहीं हुआ।

मूल कारण विश्लेषण (Root Cause)

मूल कारण dwmcore.dll के CInteraction::ProcessInputArray फ़ंक्शन में अनचेक्ड 32-बिट पूर्णांक ओवरफ़्लो है, जहाँ offset + count का मान 0xFFFFFFFF से अधिक होने पर छोटा 16-बाइट हीप बफ़र आवंटित होता है और memcpy अनियंत्रित मेमोरी ओवरफ़्लो कर देता है।

हमले का चरण-दर-चरण प्रवाह

Step 1

1. प्रारंभिक स्थानीय मैलवेयर निष्पादन

एक निम्न-विशेषाधिकार प्राप्त स्थानीय मैलवेयर प्रक्रिया (जैसे QakBot ड्रॉपर) डेस्कटॉप विंडो मैनेजर (DWM) के साथ एक सुरक्षित IPC चैनल स्थापित करती है।

Step 2

2. विशाल कंपोज़िशन कमांड तैयार करना

हमलावर एक विशेष डायरेक्ट कंपोज़िशन ड्रॉइंग संदेश तैयार करता है जहाँ commandHeader.offset + commandHeader.length जानबूझकर 0xFFFFFFFF सीमा को पार कर जाता है।

Step 3

3. कम आकार का हीप आवंटन

पैच रहित dwmcore.dll ओवरफ़्लो योग की गणना करता है, और कई मेगाबाइट के बजाय केवल 64 बाइट का छोटा हीप चंक आवंटित कर देता है।

Step 4

4. लीनियर मेमोरी ओवरराइट और SYSTEM प्रिविलेज

मैसेज पार्सर पूरे पेलोड को उस छोटे हीप चंक में कॉपी करता है, जिससे आसन्न फ़ंक्शन पॉइंटर्स ओवरराइट हो जाते हैं और हमलावर को पूर्ण SYSTEM विशेषाधिकार प्राप्त हो जाते हैं।

सोर्स कोड: कमज़ोर बनाम सुरक्षित कार्यान्वयन

✕ कमज़ोर कार्यान्वयन
// VULNERABLE: Decompiled C logic from dwmcore.dll before May 2024 patch
HRESULT CInteraction::ProcessInputArray(BYTE* pBuffer, ULONG offset, ULONG count) {
    // CRITICAL ROOT CAUSE:
    // Raw addition wraps around 32-bit integer boundaries!
    // If offset = 0xFFFFFFF0 and count = 0x20:
    // 0xFFFFFFF0 + 0x20 = 0x00000010 (16 bytes!)
    ULONG totalAllocationSize = offset + count;

    // Allocates a tiny 16-byte heap buffer!
    BYTE* pDestArray = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, totalAllocationSize);
    if (!pDestArray) {
        return E_OUTOFMEMORY;
    }

    // Copies original oversized byte count, overflowing heap chunks!
    memcpy(pDestArray + offset, pBuffer, count);
    return S_OK;
}
✓ सुरक्षित और सुदृढ़ फ़िक्स
// SECURE: Decompiled C logic from dwmcore.dll after Patch Tuesday
#include <intsafe.h>

HRESULT CInteraction::ProcessInputArray(BYTE* pBuffer, ULONG offset, ULONG count) {
    ULONG totalAllocationSize = 0;

    // 1. Enforce safe integer arithmetic check
    // Returns INTSAFE_E_ARITHMETIC_OVERFLOW if sum exceeds ULONG_MAX
    if (FAILED(ULongAdd(offset, count, &totalAllocationSize))) {
        return E_INVALIDARG;
    }

    // 2. Validate upper bound threshold limits
    if (totalAllocationSize > MAX_ALLOWED_INPUT_SIZE) {
        return E_INVALIDARG;
    }

    BYTE* pDestArray = (BYTE*)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, totalAllocationSize);
    if (!pDestArray) {
        return E_OUTOFMEMORY;
    }

    memcpy(pDestArray + offset, pBuffer, count);
    return S_OK;
}

इंजीनियरिंग और सिस्टम सुरक्षा चेकलिस्ट