flawopen.com/Teardowns/cve-2024-30051-windows-dwm-privilege-escalation
Wie eine ungeprüfte 32-Bit-Ganzzahladition in dwmcore.dll es lokaler Schadsoftware ermöglichte, eine unterdimensionierte Heap-Zuweisung auszulösen, Speicher zu korrumpieren und SYSTEM-Rechte zu erlangen.
Stellen Sie sich vor, ein Paketdienst gibt Ihnen eine Schachtel für 10 Gegenstände, weil Sie '5 Gegenstände plus 5 Gegenstände' angemeldet haben. Sie übergeben jedoch so gigantische Zahlen, dass der Computer-Zähler überläuft und wieder bei Null beginnt: Der Computer kalkuliert '4 Milliarden plus 10 Gegenstände gleich 10 Gegenstände'. Er stellt eine Mini-Schachtel bereit, Sie stopfen 4 Milliarden Gegenstände hinein, die das gesamte Lager überfluten, sodass Sie die Kontrolle über das Gebäude übernehmen.
Desktop Window Manager (dwmcore.dll)Integer Wrap-Around / OverflowPool / Heap CorruptionSafe Integer Arithmetic (ULongAdd)Die Schwachstelle resultiert aus einem ungeprüften 32-Bit-Ganzzahlüberlauf in dwmcore.dll!CInteraction::ProcessInputArray, bei dem offset + count überläuft, ein 16-Byte-Heap-Puffer reserviert wird und memcpy benachbarten Speicher überschreibt.
Ein Prozess mit niedrigen Rechten (z. B. ein QakBot-Dropper) initiiert einen IPC-Kanal zum Desktop Window Manager.
Der Angreifer konstruiert eine DirectComposition-Nachricht, bei der die Summe aus offset und length gezielt 0xFFFFFFFF übersteigt.
Die ungepatchte dwmcore.dll berechnet die überlaufene Summe und allokiert einen winzigen 16-Byte-Puffer statt mehrerer Megabyte.
Der Parser kopiert die gesamten Nutzdaten in den Mini-Puffer, überschreibt benachbarte Funktionszeiger und erlangt SYSTEM-Rechte.
// 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;
}