flawopen.com/Teardowns/cve-2024-30051-windows-dwm-privilege-escalation
Bagaimana penambahan bilangan bulat 32-bit tanpa validasi di dwmcore.dll memungkinkan malware lokal memicu alokasi heap yang terlalu kecil, merusak memori, dan meningkatkan hak akses ke SYSTEM.
Bayangkan sebuah perusahaan ekspedisi memberi Anda kotak kecil berkapasitas 10 barang karena Anda memesan '5 barang ditambah 5 barang'. Namun, Anda sengaja memasukkan angka yang sangat besar sehingga penghitung komputer meluap dan kembali ke nol: komputer mengira '4 miliar ditambah 10 barang sama dengan 10 barang'. Komputer menyiapkan kotak mini, Anda menjejalkan 4 miliar barang hingga tumpah ruah ke seluruh gudang, memungkinkan Anda mengambil alih fasilitas keamanan.
Desktop Window Manager (dwmcore.dll)Integer Wrap-Around / OverflowPool / Heap CorruptionSafe Integer Arithmetic (ULongAdd)Akar masalahnya adalah integer overflow 32-bit tanpa pemeriksaan di dwmcore.dll!CInteraction::ProcessInputArray, di mana offset + count berputar melewati batas maksimum, mengalokasikan 16 byte heap yang kemudian dirusak oleh memcpy.
Proses malware berhak akses rendah (seperti dropper QakBot) membuka saluran komunikasi IPC dengan Desktop Window Manager.
Penyerang menyusun pesan DirectComposition di mana offset + length sengaja dibuat melampaui batas 0xFFFFFFFF.
dwmcore.dll yang belum ditambal menghitung penjumlahan yang meluap dan hanya mengalokasikan buffer 16 byte.
Parser pesan menyalin seluruh payload ke buffer mini tersebut, menimpa penunjuk fungsi di dekatnya untuk meraih hak akses 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;
}