
Mémoire de recherche de Master sur CVE-2024-30051 (débordement de tas DWM Windows). Comprend un exploit à haute fiabilité avec optimisation automatisée du heap spray, journalisation en temps réel et analyse empirique du taux de réussite. Pièce de portfolio démontrant l'exploitation avancée de binaires Windows, la manipulation de la disposition du tas et l'élévation de privilèges locaux via le gestionnaire de fenêtres du bureau.
Débordement de tas basé sur tas dans le Gestionnaire de fenêtres du bureau Windows (
dwmcore.dll) Élévation de privilège locale → Niveau d'intégrité SYSTEM via le processus DWM Cible de build : Windows 11 22H2 (10.0.22621.3447) · Correctif : KB5037771
Ce dépôt contient ma recherche de Mémoire de Master sur CVE-2024-30051, une
vulnérabilité de Élévation de privilège de sévérité élevée (CVSS 7.8) dans la
bibliothèque principale du Gestionnaire de fenêtres du bureau Windows (dwmcore.dll).
La vulnérabilité provient d'une erreur de calcul de taille de division entière dans
CCommandBuffer::Initialize. La taille utilisée pour new() et la taille utilisée pour
memcpy() divergent en raison de cette erreur, produisant un débordement de tas de
0x8F octets. Une exploitation réussie amène dwm.exe à charger une DLL contrôlée par
l'attaquant, exécutant du code arbitraire sous le compte window manager\dwm-1 avec
Niveau d'intégrité SYSTEM.
| Aspect | Description |
|---|---|
| Diffing de correctifs | Analyse BinDiff complète identifiant CCommandBuffer::Initialize comme le locus exact de la vulnérabilité (score de similarité 0,32 contre 0,98 global sur 14 062 fonctions appariées) |
| Analyse dynamique WinDbg | Vérification pas à pas de l'ensemble des 4 hooks, de l'écrasement du champ de taille et de la construction de la charge utile |
| Analyse empirique de heap spray | 50 sessions contrôlées sur deux configurations de RAM (8 192 Mo et 4 096 Mo) avec tests statistiques formels |
| Résultats statistiques | Mann-Whitney U (p = 0,031) et test t de Welch (p = 0,011) confirment l'effet de la RAM ; moyennes observées 12,9–19× meilleures que la prédiction théorique d'environ 64 tentatives |
| Chemin de la DLL de charge utile centralisé | Chemin codé en dur extrait vers la constante de préprocesseur #define PAYLOAD_DLL_PATH |
| Journalisation de session | Log complet horodaté par session écrit dans %TEMP%\cve_30051_log.txt |
| Documentation académique | Cause racine, analyse de heap spray sur 50 sessions et chronologie CVE |
CVE-2024-30051-Masters-Thesis/
├── README.md
├── LICENSE
├── setup.bat # Copie s11.dll à l'emplacement requis
│
├── exploit/
│ ├── C21.sln # Solution Visual Studio 2022
│ ├── exploit_src/
│ │ ├── c26f.vcxproj
│ │ ├── c26f.filters
│ │ └── main.cpp # Exploit — heap spray + hooking + débordement
│ └── payload/
│ ├── payload.vcxproj
│ ├── payload.vcxproj.filters
│ ├── dllmain.cpp # DLL de charge utile — spawn un shell SYSTEM + nettoyage
│ ├── framework.h
│ ├── pch.h
│ └── pch.cpp
│
└── docs/
├── screenshots/ # Captures de diffing de correctifs, WinDbg et forensiques
└── analysis/
├── 01-root-cause.md # Bogue de division entière dans CCommandBuffer::Initialize
├── 02-heap-spray.md # Données empiriques sur 50 sessions et résultats statistiques
└── 03-timeline.md # Chronologie de la découverte, divulgation et correctif
Ouvrez C21.sln dans Visual Studio 2022. Compilez le projet payload en Release x64.
Exécutez setup.bat depuis la racine du dépôt. Il copie s11.dll vers
C:\Users\Public\Documents\s11.dll (le chemin défini par PAYLOAD_DLL_PATH).
⚠️ La DLL doit se trouver exactement à ce chemin avant d'exécuter
C26f.exe. La placer à côté de l'exécutable ne fonctionnera pas.
Compilez le projet C26f en Release x64.
x64\Release\C26f.exe
Exécutez depuis une invite de commandes standard (non élevée). L'exploit se réessaie automatiquement jusqu'à 10 fois.
En cas de succès, dwm.exe charge s11.dll et lance une invite de commandes avec Niveau d'intégrité SYSTEM.
Un journal de session est écrit dans %TEMP%\cve_30051_log.txt.
#define MAX_ATTEMPTS 10 // Tentatives max de réessai automatique par session
#define SPRAY_STEP 0x10 // Indice d'espacement des trous (1024 trous)
#define SPRAY_RANGE_START 0x3000 // Indice de début de plage de spray
#define SPRAY_RANGE_END 0x7000 // Indice de fin de plage de spray
#define SLEEP_POST_SPRAY 0xC8 // ms d'attente après le spray (200ms)
#define SLEEP_POST_HOLES 0xC8 // ms d'attente après libération des trous (200ms)
#define PAYLOAD_DLL_PATH "C:\\Users\\Public\\Documents\\s11.dll"
Dans CCommandBuffer::Initialize (dwmcore.dll 10.0.22621.3447),
CD2DSharedBuffer::GetBufferSize est appelée deux fois. La taille passée à new() subit
une division entière par 0x90 avant la multiplication, tandis que memcpy() utilise la valeur brute :
buffer_size = GetBufferSize() → p. ex. 0x23F
size_new = (0x23F / 0x90) * 0x90 = 0x1B0 ← allouée
size_memcpy = 0x23F ← copiée
overflow = 0x23F - 0x1B0 = 0x8F octets
Comparaison BinDiff entre le build 10.0.22621.3447 (vulnérable) et 10.0.22621.3593 (patché) :
| Métrique | Valeur |
|---|---|
| Similarité globale | 0,98 |
| Confiance | 0,99 |
| Fonctions appariées | 14 062 (99,1 %) |
Similarité de CCommandBuffer::Initialize | 0,32 |
| Blocs de base — version vulnérable | 4 |
| Blocs de base — version patchée | 20 (16 blocs de validation ajoutés) |
Le score anormal de 0,32 contre une similarité globale de 0,98 est la signature directe du locus de la vulnérabilité.
1. Hook RtlCreateHeap → capturer le handle du tas de dwmcore
2. Hook RtlAllocateHeap → capturer l'adresse du bloc de base
3. Hook NtDCompositionCreateChannel → capturer MappedAddress (région mémoire partagée)
4. Hook NtDCompositionCommitChannel → écraser le champ de taille (0x120 → 0x23F)
injecter des commandes batch supplémentaires
5. Heap spray de 0x10000 objets CHolographicInteropTexture (taille=0x1B0)
6. Libérer des trous tous les 0x10 indices → créer des espaces pour l'atterrissage du débordement
7. Écrire la charge utile dans le buffer de débordement → KCBTable+0x388 + LoadLibraryA + chemin DLL
8. Libérer tous les objets spray → déclencher le débordement → LoadLibraryA("s11.dll")
9. dwm.exe charge la DLL de charge utile → spawn un CMD en intégrité SYSTEM
La RAM disponible influence-t-elle le nombre de tentatives nécessaires pour un heap spray réussi ?