
Forschung im Rahmen einer Masterarbeit zu CVE-2024-30051 (Windows DWM Heap Overflow). Bietet einen hochzuverlässigen Exploit mit automatisierter Heap-Spray-Optimierung, Echtzeit-Protokollierung und empirischer Erfolgsquotenanalyse. Portfolioprojekt, das fortgeschrittene Windows-Binary-Exploitation, Heap-Layout-Manipulation und LPE über den Desktop Window Manager demonstriert.
Heap-basierter Pufferüberlauf im Windows Desktop Window Manager (
dwmcore.dll)
Lokale Rechteausweitung → Integritätsstufe SYSTEM über den DWM-Prozess
Ziel-Build: Windows 11 22H2 (10.0.22621.3447) · Patch: KB5037771
Dieses Repository enthält meine Forschung zur Masterarbeit über CVE-2024-30051, eine
Schwachstelle mit hohem Schweregrad (CVSS 7,8) zur Rechteausweitung in der Core Library
des Windows Desktop Window Managers (dwmcore.dll).
Die Schwachstelle rührt von einer Fehlberechnung der Größe durch Integer-Division in
CCommandBuffer::Initialize her. Die für new() verwendete Größe und die für memcpy()
verwendete Größe weichen aufgrund dieser Fehlberechnung voneinander ab, was einen
Heap-Überlauf von 0x8F Bytes erzeugt. Ein erfolgreicher Exploit führt dazu, dass dwm.exe
eine vom Angreifer kontrollierte DLL lädt und beliebigen Code unter dem Konto
window manager\dwm-1 mit Integritätsstufe SYSTEM ausführt.
| Aspekt | Beschreibung |
|---|---|
| Patch-Diffing | Vollständige BinDiff-Analyse, die CCommandBuffer::Initialize als exakten Ort der Schwachstelle identifiziert (Ähnlichkeitswert 0,32 gegenüber global 0,98 über 14.062 abgeglichene Funktionen) |
| WinDbg-Dynamikanalyse | Schritt-für-Schritt-Verifikation aller 4 Hooks, des Überschreibens des Größenfelds und der Payload-Konstruktion |
| Empirische Heap-Spray-Analyse | 50 kontrollierte Sitzungen über zwei RAM-Konfigurationen (8.192 MB und 4.096 MB) mit formalen statistischen Tests |
| Statistische Erkenntnisse | Mann-Whitney-U (p = 0,031) und Welch's t-Test (p = 0,011) bestätigen den RAM-Effekt; beobachtete Mittelwerte 12,9–19× besser als die theoretische Vorhersage von ~64 Versuchen |
| Payload-DLL-Pfad zentralisiert | Fest verdrahteten Pfad in die Präprozessor-Konstante #define PAYLOAD_DLL_PATH extrahiert |
| Sitzungsprotokollierung | Vollständiges, mit Zeitstempel versehenes Protokoll pro Sitzung, geschrieben nach %TEMP%\cve_30051_log.txt |
| Akademische Dokumentation | Root Cause, 50-Sitzungen-Heap-Spray-Analyse und CVE-Zeitleiste |
CVE-2024-30051-Masters-Thesis/
├── README.md
├── LICENSE
├── setup.bat # Copies s11.dll to required location
│
├── exploit/
│ ├── C21.sln # Visual Studio 2022 solution
│ ├── exploit_src/
│ │ ├── c26f.vcxproj
│ │ ├── c26f.filters
│ │ └── main.cpp # Exploit — heap spray + hooking + overflow
│ └── payload/
│ ├── payload.vcxproj
│ ├── payload.vcxproj.filters
│ ├── dllmain.cpp # Payload DLL — spawns SYSTEM shell + cleanup
│ ├── framework.h
│ ├── pch.h
│ └── pch.cpp
│
└── docs/
├── screenshots/ # Patch diffing, WinDbg, and forensic captures
└── analysis/
├── 01-root-cause.md # Integer division bug in CCommandBuffer::Initialize
├── 02-heap-spray.md # 50-session empirical data and statistical findings
└── 03-timeline.md # Discovery, disclosure, and patch chronology
Öffnen Sie C21.sln in Visual Studio 2022. Erstellen Sie das Projekt payload in Release x64.
Führen Sie setup.bat aus dem Repository-Stammverzeichnis aus. Es kopiert s11.dll nach
C:\Users\Public\Documents\s11.dll (den durch PAYLOAD_DLL_PATH definierten Pfad).
⚠️ Die DLL muss sich vor dem Ausführen von
C26f.exean genau diesem Pfad befinden. Ein Platzieren neben der ausführbaren Datei funktioniert nicht.
Erstellen Sie das Projekt C26f in Release x64.
x64\Release\C26f.exe
Führen Sie es aus einer normalen (nicht erhöhten) CMD aus. Der Exploit versucht automatisch bis zu 10 Mal erneut.
Bei Erfolg lädt dwm.exe die s11.dll und startet eine CMD mit SYSTEM-Integritätsstufe.
Ein Sitzungsprotokoll wird nach %TEMP%\cve_30051_log.txt geschrieben.
#define MAX_ATTEMPTS 10 // Max auto-retry attempts per session
#define SPRAY_STEP 0x10 // Hole spacing index (1024 holes)
#define SPRAY_RANGE_START 0x3000 // Spray range start index
#define SPRAY_RANGE_END 0x7000 // Spray range end index
#define SLEEP_POST_SPRAY 0xC8 // ms wait after spray (200ms)
#define SLEEP_POST_HOLES 0xC8 // ms wait after freeing holes (200ms)
#define PAYLOAD_DLL_PATH "C:\\Users\\Public\\Documents\\s11.dll"
In CCommandBuffer::Initialize (dwmcore.dll 10.0.22621.3447)
wird CD2DSharedBuffer::GetBufferSize zweimal aufgerufen. Die an new() übergebene Größe wird
vor der Multiplikation einer Integer-Division durch 0x90 unterzogen, während memcpy() den Rohwert verwendet:
buffer_size = GetBufferSize() → e.g. 0x23F
size_new = (0x23F / 0x90) * 0x90 = 0x1B0 ← allocated
size_memcpy = 0x23F ← copied
overflow = 0x23F - 0x1B0 = 0x8F bytes
BinDiff-Vergleich zwischen Build 10.0.22621.3447 (verwundbar) und 10.0.22621.3593 (gepatcht):
| Metrik | Wert |
|---|---|
| Globale Ähnlichkeit | 0,98 |
| Konfidenz | 0,99 |
| Abgeglichene Funktionen | 14.062 (99,1 %) |
Ähnlichkeit von CCommandBuffer::Initialize | 0,32 |
| Basisblöcke — verwundbare Version | 4 |
| Basisblöcke — gepatchte Version | 20 (16 Validierungsblöcke hinzugefügt) |
Der anomale Wert von 0,32 gegenüber einer globalen Ähnlichkeit von 0,98 ist die direkte Signatur des Orts der Schwachstelle.
1. Hook RtlCreateHeap → capture dwmcore heap handle
2. Hook RtlAllocateHeap → capture base chunk address
3. Hook NtDCompositionCreateChannel → capture MappedAddress (shared memory region)
4. Hook NtDCompositionCommitChannel → overwrite size field (0x120 → 0x23F)
inject additional batch commands
5. Heap spray 0x10000 CHolographicInteropTexture objects (size=0x1B0)
6. Free holes every 0x10 indices → create gaps for overflow landing
7. Write payload into overflow buffer → KCBTable+0x388 + LoadLibraryA + DLL path
8. Release all spray objects → trigger overflow → LoadLibraryA("s11.dll")
9. dwm.exe loads payload DLL → spawns CMD as SYSTEM integrity
Beeinflusst der verfügbare RAM die Anzahl der Versuche, die für ein erfolgreiches Heap-Spray erforderlich sind?
Zwei Blöcke mit je 25 Sitzungen. Protokoll pro Sitzung: sauberen Snapshot nach dem Booten wiederherstellen → 100 Sekunden Stabilisierung abwarten → Exploit starten → erfolgreichen Versuch notieren.
| Block | RAM | Sitzungen | Erfolge | Fehlschläge |
|---|---|---|---|---|
| A | 8.192 MB | 25 | 24 | 1 |
| B | 4.096 MB | 25 | 24 | 1 |