|
|
@@ -0,0 +1,223 @@
|
|
|
+#include <stdio.h>
|
|
|
+#include <Windows.h>
|
|
|
+#include <wbemidl.h>
|
|
|
+#include "findexclusions.h"
|
|
|
+#include "beacon.h"
|
|
|
+
|
|
|
+#pragma comment(lib, "wbemuuid.lib")
|
|
|
+#pragma comment(lib, "ole32.lib")
|
|
|
+#pragma comment(lib, "oleaut32.lib")
|
|
|
+
|
|
|
+
|
|
|
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
|
|
|
+#ifndef bufsize
|
|
|
+#define bufsize 8192
|
|
|
+#endif
|
|
|
+char *output = 0;
|
|
|
+WORD currentoutsize = 0;
|
|
|
+HANDLE trash = NULL;
|
|
|
+int bofstart();
|
|
|
+void internal_printf(const char* format, ...);
|
|
|
+void printoutput(BOOL done);
|
|
|
+
|
|
|
+int bofstart() {
|
|
|
+ output = (char*)MSVCRT$calloc(bufsize, 1);
|
|
|
+ currentoutsize = 0;
|
|
|
+ return 1;
|
|
|
+}
|
|
|
+
|
|
|
+void internal_printf(const char* format, ...){
|
|
|
+ int buffersize = 0;
|
|
|
+ int transfersize = 0;
|
|
|
+ char * curloc = NULL;
|
|
|
+ char* intBuffer = NULL;
|
|
|
+ va_list args;
|
|
|
+ va_start(args, format);
|
|
|
+ buffersize = MSVCRT$vsnprintf(NULL, 0, format, args);
|
|
|
+ va_end(args);
|
|
|
+
|
|
|
+ if (buffersize == -1) return;
|
|
|
+
|
|
|
+ char* transferBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, bufsize);
|
|
|
+ intBuffer = (char*)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, buffersize);
|
|
|
+ va_start(args, format);
|
|
|
+ MSVCRT$vsnprintf(intBuffer, buffersize, format, args);
|
|
|
+ va_end(args);
|
|
|
+ if(buffersize + currentoutsize < bufsize)
|
|
|
+ {
|
|
|
+ MSVCRT$memcpy(output+currentoutsize, intBuffer, buffersize);
|
|
|
+ currentoutsize += buffersize;
|
|
|
+ } else {
|
|
|
+ curloc = intBuffer;
|
|
|
+ while(buffersize > 0)
|
|
|
+ {
|
|
|
+ transfersize = bufsize - currentoutsize;
|
|
|
+ if(buffersize < transfersize)
|
|
|
+ {
|
|
|
+ transfersize = buffersize;
|
|
|
+ }
|
|
|
+ MSVCRT$memcpy(output+currentoutsize, curloc, transfersize);
|
|
|
+ currentoutsize += transfersize;
|
|
|
+ if(currentoutsize == bufsize)
|
|
|
+ {
|
|
|
+ printoutput(FALSE);
|
|
|
+ }
|
|
|
+ MSVCRT$memset(transferBuffer, 0, transfersize);
|
|
|
+ curloc += transfersize;
|
|
|
+ buffersize -= transfersize;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, intBuffer);
|
|
|
+ KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, transferBuffer);
|
|
|
+}
|
|
|
+
|
|
|
+void printoutput(BOOL done) {
|
|
|
+ char * msg = NULL;
|
|
|
+ BeaconOutput(CALLBACK_OUTPUT, output, currentoutsize);
|
|
|
+ currentoutsize = 0;
|
|
|
+ MSVCRT$memset(output, 0, bufsize);
|
|
|
+ if(done) {MSVCRT$free(output); output=NULL;}
|
|
|
+}
|
|
|
+//END TrustedSec BOF print code.
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+int EnumerateDefenderExclusions() {
|
|
|
+ HRESULT hr;
|
|
|
+ int result = 0;
|
|
|
+
|
|
|
+ hr = OLE32$CoInitializeEx(0, COINIT_APARTMENTTHREADED);
|
|
|
+ if (FAILED(hr)) goto Cleanup;
|
|
|
+
|
|
|
+ IWbemLocator *pLoc = NULL;
|
|
|
+ IID CLSIDWbemLocator = {0x4590f811, 0x1d3a, 0x11d0, {0x89, 0x1f, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
|
|
|
+ IID IIDIWbemLocator = {0xdc12a687, 0x737f, 0x11cf, {0x88, 0x4d, 0x00, 0xaa, 0x00, 0x4b, 0x2e, 0x24}};
|
|
|
+ hr = OLE32$CoCreateInstance(&CLSIDWbemLocator, 0, CLSCTX_INPROC_SERVER, &IIDIWbemLocator, (LPVOID *)&pLoc);
|
|
|
+ if (FAILED(hr)) goto Cleanup;
|
|
|
+
|
|
|
+ IWbemServices *pSvc = NULL;
|
|
|
+ hr = pLoc->lpVtbl->ConnectServer(pLoc, OLEAUT32$SysAllocString(L"ROOT\\Microsoft\\Windows\\Defender"), NULL, NULL, 0, NULL, 0, 0, &pSvc);
|
|
|
+ if (FAILED(hr)) goto Cleanup;
|
|
|
+
|
|
|
+ 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);
|
|
|
+
|
|
|
+ IEnumWbemClassObject* pEnumerator = NULL;
|
|
|
+ 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);
|
|
|
+ if (FAILED(hr)) goto Cleanup;
|
|
|
+
|
|
|
+ internal_printf("\nExclusion enumeration results:\n====================================================\n");
|
|
|
+
|
|
|
+ ULONG returnedCount = 0;
|
|
|
+ IWbemClassObject *pResult = NULL;
|
|
|
+ while (pEnumerator) {
|
|
|
+ hr = pEnumerator->lpVtbl->Next(pEnumerator, WBEM_INFINITE, 1, &pResult, &returnedCount);
|
|
|
+ if (0 == returnedCount) break;
|
|
|
+
|
|
|
+ //folder and files
|
|
|
+ VARIANT pathName;
|
|
|
+ hr = pResult->lpVtbl->Get(pResult, L"ExclusionPath", 0, &pathName, 0, 0);
|
|
|
+ if (SUCCEEDED(hr)) {
|
|
|
+ if (pathName.vt == VT_NULL) {
|
|
|
+ internal_printf("[-] No file or folder exclusion configured\n");
|
|
|
+ result = 1;
|
|
|
+ } else if (pathName.vt == (VT_ARRAY | VT_BSTR)) {
|
|
|
+
|
|
|
+ SAFEARRAY* sa = pathName.parray;
|
|
|
+ BSTR* bstrArray;
|
|
|
+ long lBound, uBound;
|
|
|
+
|
|
|
+ OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
|
|
|
+ OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
|
|
|
+ OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
|
|
|
+
|
|
|
+ for (long i = lBound; i <= uBound; i++) {
|
|
|
+ if (MSVCRT$wcscmp(bstrArray[i], L"N/A: Must be an administrator to view exclusions") == 0) {
|
|
|
+ BeaconPrintf(CALLBACK_ERROR, "Access Denied! The current user does not have sufficient permissions to enumerate exclusions.\n");
|
|
|
+ goto Cleanup;
|
|
|
+ } else {
|
|
|
+ internal_printf("[+] Found folder/file exclusion: %ls\n", bstrArray[i]);
|
|
|
+ result = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ OLEAUT32$SafeArrayUnaccessData(sa);
|
|
|
+ } else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse path data with error code: %d\n", pathName.vt);
|
|
|
+
|
|
|
+ OLEAUT32$VariantClear(&pathName);
|
|
|
+ }
|
|
|
+
|
|
|
+ //extention
|
|
|
+ VARIANT extName;
|
|
|
+ hr = pResult->lpVtbl->Get(pResult, L"ExclusionExtension", 0, &extName, 0, 0);
|
|
|
+ if (SUCCEEDED(hr)) {
|
|
|
+ if (extName.vt == VT_NULL) {
|
|
|
+ internal_printf("[-] No extention exclusion configured\n");
|
|
|
+ result = 1;
|
|
|
+ } else if (extName.vt == (VT_ARRAY | VT_BSTR)) {
|
|
|
+
|
|
|
+ SAFEARRAY* sa = extName.parray;
|
|
|
+ BSTR* bstrArray;
|
|
|
+ long lBound, uBound;
|
|
|
+
|
|
|
+ OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
|
|
|
+ OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
|
|
|
+ OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
|
|
|
+
|
|
|
+ for (long i = lBound; i <= uBound; i++) {
|
|
|
+ internal_printf("[+] Found extention exclusion: %ls\n", bstrArray[i]);
|
|
|
+ result = 1;
|
|
|
+ }
|
|
|
+ OLEAUT32$SafeArrayUnaccessData(sa);
|
|
|
+ } else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse extention data with error code: %d\n", extName.vt);
|
|
|
+
|
|
|
+ OLEAUT32$VariantClear(&extName);
|
|
|
+ }
|
|
|
+
|
|
|
+ //processes
|
|
|
+ VARIANT procName;
|
|
|
+ hr = pResult->lpVtbl->Get(pResult, L"ExclusionProcess", 0, &procName, 0, 0);
|
|
|
+ if (SUCCEEDED(hr)) {
|
|
|
+ if (procName.vt == VT_NULL) {
|
|
|
+ internal_printf("[-] No process exclusion configured\n");
|
|
|
+ result = 1;
|
|
|
+ } else if (procName.vt == (VT_ARRAY | VT_BSTR)) {
|
|
|
+
|
|
|
+ SAFEARRAY* sa = procName.parray;
|
|
|
+ BSTR* bstrArray;
|
|
|
+ long lBound, uBound;
|
|
|
+
|
|
|
+ OLEAUT32$SafeArrayGetLBound(sa, 1, &lBound);
|
|
|
+ OLEAUT32$SafeArrayGetUBound(sa, 1, &uBound);
|
|
|
+ OLEAUT32$SafeArrayAccessData(sa, (void**)&bstrArray);
|
|
|
+
|
|
|
+ for (long i = lBound; i <= uBound; i++) {
|
|
|
+ internal_printf("[+] Found process exclusion: %ls\n", bstrArray[i]);
|
|
|
+ result = 1;
|
|
|
+ }
|
|
|
+ OLEAUT32$SafeArrayUnaccessData(sa);
|
|
|
+ } else BeaconPrintf(CALLBACK_ERROR, "Error occurred! Couldn't properly parse process data with error code: %d\n", procName.vt);
|
|
|
+
|
|
|
+ OLEAUT32$VariantClear(&procName);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+Cleanup:
|
|
|
+ if (pSvc) pSvc->lpVtbl->Release(pSvc);
|
|
|
+ if (pLoc) pLoc->lpVtbl->Release(pLoc);
|
|
|
+ if (pEnumerator) pEnumerator->lpVtbl->Release(pEnumerator);
|
|
|
+ if (pResult) pResult->lpVtbl->Release(pResult);
|
|
|
+ OLE32$CoUninitialize();
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+int go() {
|
|
|
+ int result = 0;
|
|
|
+
|
|
|
+ if(!bofstart()) return;
|
|
|
+
|
|
|
+ result = EnumerateDefenderExclusions();
|
|
|
+ if(result) printoutput(TRUE);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|