enumexclusions.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <stdio.h>
  2. #include <Windows.h>
  3. #include <wbemidl.h>
  4. #include "enumexclusions.h"
  5. #include "beacon.h"
  6. #pragma comment(lib, "wbemuuid.lib")
  7. #pragma comment(lib, "ole32.lib")
  8. #pragma comment(lib, "oleaut32.lib")
  9. //START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
  10. #ifndef bufsize
  11. #define bufsize 8192
  12. #endif
  13. char *output = 0;
  14. WORD currentoutsize = 0;
  15. HANDLE trash = NULL;
  16. int bofstart();
  17. void internal_printf(const char* format, ...);
  18. void printoutput(BOOL done);
  19. int bofstart() {
  20. output = (char*)MSVCRT$calloc(bufsize, 1);
  21. currentoutsize = 0;
  22. return 1;
  23. }
  24. void internal_printf(const char* format, ...){
  25. int buffersize = 0;
  26. int transfersize = 0;
  27. char * curloc = NULL;
  28. char* intBuffer = NULL;
  29. va_list args;
  30. va_start(args, format);
  31. buffersize = MSVCRT$vsnprintf(NULL, 0, format, args);
  32. va_end(args);
  33. if (buffersize == -1) return;
  34. char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
  35. intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
  36. va_start(args, format);
  37. MSVCRT$vsnprintf(intBuffer, buffersize, format, args);
  38. va_end(args);
  39. if(buffersize + currentoutsize < bufsize)
  40. {
  41. MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
  42. currentoutsize += buffersize;
  43. } else {
  44. curloc = intBuffer;
  45. while(buffersize > 0)
  46. {
  47. transfersize = bufsize - currentoutsize;
  48. if(buffersize < transfersize)
  49. {
  50. transfersize = buffersize;
  51. }
  52. MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
  53. currentoutsize += transfersize;
  54. if(currentoutsize == bufsize)
  55. {
  56. printoutput(FALSE);
  57. }
  58. MSVCRT$memset(transferBuffer, 0, transfersize);
  59. curloc += transfersize;
  60. buffersize -= transfersize;
  61. }
  62. }
  63. KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
  64. KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
  65. }
  66. void printoutput(BOOL done) {
  67. char * msg = NULL;
  68. BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
  69. currentoutsize = 0;
  70. MSVCRT$memset(output, 0, bufsize);
  71. if(done) {MSVCRT$free(output); output=NULL;}
  72. }
  73. //END TrustedSec BOF print code.
  74. int EnumerateDefenderExclusions() {
  75. HRESULT hr;
  76. int result = 0;
  77. hr = OLE32$CoInitializeEx(0, COINIT_APARTMENTTHREADED);
  78. if (FAILED(hr)) goto Cleanup;
  79. IWbemLocator *pLoc = NULL;
  80. IID CLSIDWbemLocator = {0x4590f811, 0x1d3a, 0x11d0, {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
  81. IID IIDIWbemLocator = {0xdc12a687, 0x737f, 0x11cf, {0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
  82. hr = OLE32$CoCreateInstance(&CLSIDWbemLocator, 0, CLSCTX_INPROC_SERVER, &IIDIWbemLocator, (LPVOID *)&pLoc);
  83. if (FAILED(hr)) goto Cleanup;
  84. IWbemServices *pSvc = NULL;
  85. hr = pLoc->lpVtbl->ConnectServer(pLoc, OLEAUT32$SysAllocString(L"ROOT\\Microsoft\\Windows\\Defender"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
  86. if (FAILED(hr)) goto Cleanup;
  87. hr = OLE32$CoSetProxyBlanket(pSvc, RPC_C_AUTHN_WINNT, RPC_C_AUTHZ_NONE, NULL, RPC_C_AUTHN_LEVEL_CALL, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE);
  88. IEnumWbemClassObject* pEnumerator = NULL;
  89. hr = pSvc->lpVtbl->ExecQuery(pSvc, OLEAUT32$SysAllocString(L"WQL"), OLEAUT32$SysAllocString(L"SELECT * FROM MSFT_MpPreference"), WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
  90. if (FAILED(hr)) goto Cleanup;
  91. internal_printf("\nExclusion enumeration results:\n====================================================\n");
  92. ULONG returnedCount = 0;
  93. IWbemClassObject *pResult = NULL;
  94. while (pEnumerator) {
  95. hr = pEnumerator->lpVtbl->Next(pEnumerator, WBEM_INFINITE, 1, &pResult, &returnedCount);
  96. if (0 == returnedCount) break;
  97. //folder and files
  98. VARIANT pathName;
  99. hr = pResult->lpVtbl->Get(pResult, L"ExclusionPath", 0, &pathName, 0, 0);
  100. if (SUCCEEDED(hr)) {
  101. if (pathName.vt == VT_NULL) {
  102. internal_printf("[-] No file or folder exclusion configured\n");
  103. result = 1;
  104. } else if (pathName.vt == (VT_ARRAY | VT_BSTR)) {
  105. SAFEARRAY* sa = pathName.parray;
  106. BSTR* bstrArray;
  107. long lBound, uBound;
  108. OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
  109. OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
  110. OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
  111. for (long i = lBound; i <= uBound; i++) {
  112. if (MSVCRT$wcscmp(bstrArray[i], L"N/A: Must be an administrator to view exclusions") == 0) {
  113. BeaconPrintf(CALLBACK_ERROR, "Access Denied! The current user does not have sufficient permissions to enumerate exclusions.\n");
  114. goto Cleanup;
  115. } else {
  116. internal_printf("[+] Found folder/file exclusion: %ls\n", bstrArray[i]);
  117. result = 1;
  118. }
  119. }
  120. OLEAUT32$SafeArrayUnaccessData(sa);
  121. } else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse path data with error code: %d\n", pathName.vt);
  122. OLEAUT32$VariantClear(&pathName);
  123. }
  124. //extention
  125. VARIANT extName;
  126. hr = pResult->lpVtbl->Get(pResult, L"ExclusionExtension", 0, &extName, 0, 0);
  127. if (SUCCEEDED(hr)) {
  128. if (extName.vt == VT_NULL) {
  129. internal_printf("[-] No extention exclusion configured\n");
  130. result = 1;
  131. } else if (extName.vt == (VT_ARRAY | VT_BSTR)) {
  132. SAFEARRAY* sa = extName.parray;
  133. BSTR* bstrArray;
  134. long lBound, uBound;
  135. OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
  136. OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
  137. OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
  138. for (long i = lBound; i <= uBound; i++) {
  139. internal_printf("[+] Found extention exclusion: %ls\n", bstrArray[i]);
  140. result = 1;
  141. }
  142. OLEAUT32$SafeArrayUnaccessData(sa);
  143. } else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse extention data with error code: %d\n", extName.vt);
  144. OLEAUT32$VariantClear(&extName);
  145. }
  146. //processes
  147. VARIANT procName;
  148. hr = pResult->lpVtbl->Get(pResult, L"ExclusionProcess", 0, &procName, 0, 0);
  149. if (SUCCEEDED(hr)) {
  150. if (procName.vt == VT_NULL) {
  151. internal_printf("[-] No process exclusion configured\n");
  152. result = 1;
  153. } else if (procName.vt == (VT_ARRAY | VT_BSTR)) {
  154. SAFEARRAY* sa = procName.parray;
  155. BSTR* bstrArray;
  156. long lBound, uBound;
  157. OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
  158. OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
  159. OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
  160. for (long i = lBound; i <= uBound; i++) {
  161. internal_printf("[+] Found process exclusion: %ls\n", bstrArray[i]);
  162. result = 1;
  163. }
  164. OLEAUT32$SafeArrayUnaccessData(sa);
  165. } else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse process data with error code: %d\n", procName.vt);
  166. OLEAUT32$VariantClear(&procName);
  167. }
  168. }
  169. Cleanup:
  170. if (pSvc) pSvc->lpVtbl->Release(pSvc);
  171. if (pLoc) pLoc->lpVtbl->Release(pLoc);
  172. if (pEnumerator) pEnumerator->lpVtbl->Release(pEnumerator);
  173. if (pResult) pResult->lpVtbl->Release(pResult);
  174. OLE32$CoUninitialize();
  175. return result;
  176. }
  177. int go() {
  178. int result = 0;
  179. if(!bofstart()) return;
  180. result = EnumerateDefenderExclusions();
  181. if(result) printoutput(TRUE);
  182. return 0;
  183. }