enumdotnet.c 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. #include <windows.h>
  2. #include <stdio.h>
  3. #include <psapi.h>
  4. #include <shlwapi.h>
  5. #include <strsafe.h>
  6. #include <winternl.h>
  7. #include "beacon.h"
  8. #include "enumdotnet.h"
  9. #pragma comment(lib, "ntdll.lib")
  10. #pragma comment(lib, "User32.lib")
  11. #pragma comment(lib, "Shlwapi.lib")
  12. //START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
  13. #ifndef bufsize
  14. #define bufsize 8192
  15. #endif
  16. char *output = 0;
  17. WORD currentoutsize = 0;
  18. HANDLE trash = NULL;
  19. int bofstart();
  20. void internal_printf(const char* format, ...);
  21. void printoutput(BOOL done);
  22. int bofstart() {
  23. output = (char*)MSVCRT$calloc(bufsize, 1);
  24. currentoutsize = 0;
  25. return 1;
  26. }
  27. void internal_printf(const char* format, ...){
  28. int buffersize = 0;
  29. int transfersize = 0;
  30. char * curloc = NULL;
  31. char* intBuffer = NULL;
  32. va_list args;
  33. va_start(args, format);
  34. buffersize = MSVCRT$vsnprintf(NULL, 0, format, args);
  35. va_end(args);
  36. if (buffersize == -1) return;
  37. char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
  38. intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
  39. va_start(args, format);
  40. MSVCRT$vsnprintf(intBuffer, buffersize, format, args);
  41. va_end(args);
  42. if(buffersize + currentoutsize < bufsize)
  43. {
  44. MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
  45. currentoutsize += buffersize;
  46. } else {
  47. curloc = intBuffer;
  48. while(buffersize > 0)
  49. {
  50. transfersize = bufsize - currentoutsize;
  51. if(buffersize < transfersize)
  52. {
  53. transfersize = buffersize;
  54. }
  55. MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
  56. currentoutsize += transfersize;
  57. if(currentoutsize == bufsize)
  58. {
  59. printoutput(FALSE);
  60. }
  61. MSVCRT$memset(transferBuffer, 0, transfersize);
  62. curloc += transfersize;
  63. buffersize -= transfersize;
  64. }
  65. }
  66. KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
  67. KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
  68. }
  69. void printoutput(BOOL done) {
  70. char * msg = NULL;
  71. BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
  72. currentoutsize = 0;
  73. MSVCRT$memset(output, 0, bufsize);
  74. if(done) {MSVCRT$free(output); output=NULL;}
  75. }
  76. //END TrustedSec BOF print code.
  77. BOOL FindDotNet() {
  78. int p = 0;
  79. int pid = 0;
  80. char psPath[MAX_PATH];
  81. HANDLE currentProc = NULL;
  82. UNICODE_STRING sectionName = { 0 };
  83. WCHAR ProcNumber[30];
  84. OBJECT_ATTRIBUTES objectAttributes;
  85. BOOL dotNetFound = FALSE;
  86. LPCSTR procName;
  87. //WCHAR WCprocName[256];
  88. NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
  89. NtOpenSection_t pNtOpenSection = (NtOpenSection_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
  90. if (pNtGetNextProcess == NULL || pNtOpenSection == NULL) {
  91. BeaconPrintf(CALLBACK_ERROR, "Error resolving native API calls!\n");
  92. return -1;
  93. }
  94. WCHAR objPath[] = L"\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_";
  95. sectionName.Buffer = (PWSTR)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
  96. internal_printf("\nProcess name\t\t\t\t\t\tPID\n");
  97. internal_printf("=====================================================================\n");
  98. while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
  99. pid = KERNEL32$GetProcessId(currentProc);
  100. if (pid == 0) continue;
  101. USER32$wsprintfW(ProcNumber, L"%d", pid);
  102. MSVCRT$memset(sectionName.Buffer, 0, 500);
  103. MSVCRT$memcpy(sectionName.Buffer, objPath, MSVCRT$wcslen(objPath) * 2); // add section name "prefix"
  104. KERNEL32$lstrcatW(sectionName.Buffer, ProcNumber);
  105. sectionName.Length = MSVCRT$wcslen(sectionName.Buffer) * 2; // finally, adjust the string size
  106. sectionName.MaximumLength = sectionName.Length + 1;
  107. InitializeObjectAttributes(&objectAttributes, &sectionName, OBJ_CASE_INSENSITIVE, NULL, NULL);
  108. HANDLE sectionHandle = NULL;
  109. NTSTATUS status = pNtOpenSection(&sectionHandle, SECTION_QUERY, &objectAttributes);
  110. if (NT_SUCCESS(status)) {
  111. KERNEL32$CloseHandle(sectionHandle);
  112. KERNEL32$K32GetProcessImageFileNameA(currentProc, psPath, MAX_PATH);
  113. procName = SHLWAPI$PathFindFileNameA(psPath);
  114. //KERNEL32$MultiByteToWideChar(CP_ACP, 0, procName, -1, WCprocName, 256);
  115. internal_printf("%-60s\t%d\n", procName, pid);
  116. dotNetFound = TRUE;
  117. }
  118. }
  119. return dotNetFound;
  120. }
  121. int go(void) {
  122. BOOL res = NULL;
  123. if(!bofstart()) return;
  124. res = FindDotNet();
  125. if(!res) {
  126. BeaconPrintf(CALLBACK_ERROR, "No .NET process found!");
  127. }
  128. else {
  129. printoutput(TRUE);
  130. }
  131. return 0;
  132. }