Skip to content
Permalink
Browse files

New DPAPI stuff & crypto

[new] dpapi::masterkey now supports SID with SYSTEM_DPAPI (for @dirkjanm services ;))
[new] dpapi::cache filter non relevant SIDs
[new] dpapi::cred now supports WinInet double DPAPI
[new] dpapi::blob /raw for hex input
[new] dpapi::blob /ascii to force ascii output (when not unicode data)
[new] crypto:: & dpapi::cng key & certificates flags from current SDK (VSM)
[new] sr98::nedap module (@iceman1001 <3)
[new] lsadump::mbc to dump MachineBoundCertificate
  • Loading branch information
gentilkiwi committed Nov 25, 2019
1 parent 6436bbe commit 3c81f16b5be1edb097898ab2ada0614e31a5195d
@@ -32,45 +32,54 @@ const KUHL_M kuhl_m_dpapi = {

NTSTATUS kuhl_m_dpapi_blob(int argc, wchar_t * argv[])
{
DATA_BLOB dataIn, dataOut;
DATA_BLOB dataIn = {0, NULL}, dataOut;
PKULL_M_DPAPI_BLOB blob;
PCWSTR outfile, infile;
PCWSTR szData;
PWSTR description = NULL;

if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL))
if(kull_m_string_args_byName(argc, argv, L"in", &szData, NULL))
{
if(kull_m_file_readData(infile, &dataIn.pbData, &dataIn.cbData))
if(!kull_m_file_readData(szData, &dataIn.pbData, &dataIn.cbData))
PRINT_ERROR_AUTO(L"kull_m_file_readData");
}
else if(kull_m_string_args_byName(argc, argv, L"raw", &szData, NULL))
{
if(!kull_m_string_stringToHexBuffer(szData, &dataIn.pbData, &dataIn.cbData))
PRINT_ERROR(L"kull_m_string_stringToHexBuffer!\n");
}

if(dataIn.pbData)
{
if(blob = kull_m_dpapi_blob_create(dataIn.pbData))
{
if(blob = kull_m_dpapi_blob_create(dataIn.pbData))
kull_m_dpapi_blob_descr(0, blob);
if(kuhl_m_dpapi_unprotect_raw_or_blob(dataIn.pbData, dataIn.cbData, &description, argc, argv, NULL, 0, (LPVOID *) &dataOut.pbData, &dataOut.cbData, NULL))
{
kull_m_dpapi_blob_descr(0, blob);

if(kuhl_m_dpapi_unprotect_raw_or_blob(dataIn.pbData, dataIn.cbData, &description, argc, argv, NULL, 0, (LPVOID *) &dataOut.pbData, &dataOut.cbData, NULL))
if(description)
{
if(description)
{
kprintf(L"description : %s\n", description);
LocalFree(description);
}

if(kull_m_string_args_byName(argc, argv, L"out", &outfile, NULL))
{
if(kull_m_file_writeData(outfile, dataOut.pbData, dataOut.cbData))
kprintf(L"Write to file \'%s\' is OK\n", outfile);
}
else
kprintf(L"description : %s\n", description);
LocalFree(description);
}
if(kull_m_string_args_byName(argc, argv, L"out", &szData, NULL))
{
if(kull_m_file_writeData(szData, dataOut.pbData, dataOut.cbData))
kprintf(L"Write to file \'%s\' is OK\n", szData);
}
else
{
kprintf(L"data: ");
if(kull_m_string_args_byName(argc, argv, L"ascii", NULL, NULL))
{
kprintf(L"data: ");
kull_m_string_printSuspectUnicodeString(dataOut.pbData, dataOut.cbData);
kprintf(L"\n");
kprintf(L"%.*S\n", dataOut.cbData, dataOut.pbData);
}
LocalFree(dataOut.pbData);
else kull_m_string_printSuspectUnicodeString(dataOut.pbData, dataOut.cbData);
kprintf(L"\n");
}
kull_m_dpapi_blob_delete(blob);
LocalFree(dataOut.pbData);
}
LocalFree(dataIn.pbData);
kull_m_dpapi_blob_delete(blob);
}
else PRINT_ERROR_AUTO(L"kull_m_file_readData");
LocalFree(dataIn.pbData);
}
return STATUS_SUCCESS;
}
@@ -224,12 +233,13 @@ NTSTATUS kuhl_m_dpapi_masterkey(int argc, wchar_t * argv[])
if((cbSystem - cbSystemOffset) == 2 * SHA_DIGEST_LENGTH)
{
kprintf(L"\n[masterkey] with DPAPI_SYSTEM (machine, then user): "); kull_m_string_wprintf_hex(pSystem + cbSystemOffset, 2 * SHA_DIGEST_LENGTH, 0); kprintf(L"\n");
if(kull_m_dpapi_unprotect_masterkey_with_shaDerivedkey(masterkeys->MasterKey, pSystem + cbSystemOffset, SHA_DIGEST_LENGTH, &output, &cbOutput))
if(kull_m_dpapi_unprotect_masterkey_with_userHash(masterkeys->MasterKey, pSystem + cbSystemOffset, SHA_DIGEST_LENGTH, convertedSid, &output, &cbOutput))

{
kprintf(L"** MACHINE **\n");
kuhl_m_dpapi_display_MasterkeyInfosAndFree(statusGuid ? &guid : NULL, output, cbOutput, NULL);
}
else if(kull_m_dpapi_unprotect_masterkey_with_shaDerivedkey(masterkeys->MasterKey, pSystem + cbSystemOffset + SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH, &output, &cbOutput))
else if(kull_m_dpapi_unprotect_masterkey_with_userHash(masterkeys->MasterKey, pSystem + cbSystemOffset + SHA_DIGEST_LENGTH, SHA_DIGEST_LENGTH, convertedSid, &output, &cbOutput))
{
kprintf(L"** USER **\n");
kuhl_m_dpapi_display_MasterkeyInfosAndFree(statusGuid ? &guid : NULL, output, cbOutput, NULL);
@@ -239,11 +249,12 @@ NTSTATUS kuhl_m_dpapi_masterkey(int argc, wchar_t * argv[])
else
{
kprintf(L"\n[masterkey] with DPAPI_SYSTEM: "); kull_m_string_wprintf_hex(pSystem + cbSystemOffset, cbSystem - cbSystemOffset, 0); kprintf(L"\n");
if(kull_m_dpapi_unprotect_masterkey_with_shaDerivedkey(masterkeys->MasterKey, pSystem + cbSystemOffset, cbSystem - cbSystemOffset, &output, &cbOutput))
if(kull_m_dpapi_unprotect_masterkey_with_userHash(masterkeys->MasterKey, pSystem + cbSystemOffset, cbSystem - cbSystemOffset, convertedSid, &output, &cbOutput))
kuhl_m_dpapi_display_MasterkeyInfosAndFree(statusGuid ? &guid : NULL, output, cbOutput, NULL);
else PRINT_ERROR(L"kull_m_dpapi_unprotect_masterkey_with_shaDerivedkey\n");
}
}
else PRINT_ERROR(L"system masterkey needs /SYSTEM:key\n");
}
else if(convertedSid)
{
@@ -182,19 +182,22 @@ BOOL kuhl_m_dpapi_oe_credential_add(LPCWSTR sid, LPCGUID guid, LPCVOID md4hash,

if(sid)
{
if(!(entry = kuhl_m_dpapi_oe_credential_get(sid, guid)))
if(kuhl_m_dpapi_oe_is_sid_valid_ForCacheOrAuto(NULL, sid, FALSE))
{
if(entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) LocalAlloc(LPTR, sizeof(KUHL_M_DPAPI_OE_CREDENTIAL_ENTRY)))
if(!(entry = kuhl_m_dpapi_oe_credential_get(sid, guid)))
{
entry->data.sid = _wcsdup(sid);
entry->navigator.Blink = gDPAPI_Credentials.Blink;
entry->navigator.Flink = &gDPAPI_Credentials;
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) gDPAPI_Credentials.Blink)->navigator.Flink = (PLIST_ENTRY) entry;
gDPAPI_Credentials.Blink= (PLIST_ENTRY) entry;
if(entry = (PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) LocalAlloc(LPTR, sizeof(KUHL_M_DPAPI_OE_CREDENTIAL_ENTRY)))
{
entry->data.sid = _wcsdup(sid);
entry->navigator.Blink = gDPAPI_Credentials.Blink;
entry->navigator.Flink = &gDPAPI_Credentials;
((PKUHL_M_DPAPI_OE_CREDENTIAL_ENTRY) gDPAPI_Credentials.Blink)->navigator.Flink = (PLIST_ENTRY) entry;
gDPAPI_Credentials.Blink= (PLIST_ENTRY) entry;
}
}
if(entry)
status = kuhl_m_dpapi_oe_credential_addtoEntry(entry, guid, md4hash, sha1hash, md4protectedhash, password);
}
if(entry)
status = kuhl_m_dpapi_oe_credential_addtoEntry(entry, guid, md4hash, sha1hash, md4protectedhash, password);
}
else PRINT_ERROR(L"No SID?");
return status;
@@ -386,6 +389,53 @@ NTSTATUS kuhl_m_dpapi_oe_cache(int argc, wchar_t * argv[])
return STATUS_SUCCESS;
}

const DWORD invalidAuthorityForAuto[] = {18, 19, 20};
const DWORD invalidAuthorityForCache[] = {18, 19, 20, 80, 82, 83, 90, 96};
BOOL kuhl_m_dpapi_oe_is_sid_valid_ForCacheOrAuto(PSID sid, LPCWSTR szSid, BOOL AutoOrCache)
{
BOOL status = FALSE;
PUCHAR count;
PSID tmpSid = NULL;
DWORD s0, i, maxAuth;
const DWORD *pAuth;

if(szSid)
ConvertStringSidToSid(szSid, &tmpSid);
else tmpSid = sid;

if(AutoOrCache)
{
pAuth = invalidAuthorityForAuto;
maxAuth = ARRAYSIZE(invalidAuthorityForAuto);
}
else
{
pAuth = invalidAuthorityForCache;
maxAuth = ARRAYSIZE(invalidAuthorityForCache);
}

if(IsValidSid(tmpSid))
{
if(count = GetSidSubAuthorityCount(tmpSid))
{
if(*count >= 1)
{
s0 = *GetSidSubAuthority(tmpSid, 0);
status = TRUE;
for(i = 0; i < maxAuth; i++)
{
if(pAuth[i] == s0)
{
status = FALSE;
break;
}
}
}
}
}
return status;
}

BOOL kuhl_m_dpapi_oe_autosid(LPCWSTR filename, LPWSTR * pSid)
{
BOOL status = FALSE;
@@ -400,10 +450,12 @@ BOOL kuhl_m_dpapi_oe_autosid(LPCWSTR filename, LPWSTR * pSid)
{
if(ConvertStringSidToSid(++pE, &tmpSid))
{
if(status = ConvertSidToStringSid(tmpSid, pSid))
if(kuhl_m_dpapi_oe_is_sid_valid_ForCacheOrAuto(tmpSid, NULL, TRUE))
{
kprintf(L"Auto SID from path seems to be: %s\n", *pSid);
if(status = ConvertSidToStringSid(tmpSid, pSid))
kprintf(L"Auto SID from path seems to be: %s\n", *pSid);
}
else kprintf(L"SID detected in path but not relevant, can be forced with /sid:S-1-...\n");
LocalFree(tmpSid);
}
}
@@ -33,6 +33,7 @@ typedef struct _KUHL_M_DPAPI_OE_DOMAINKEY_ENTRY {

NTSTATUS kuhl_m_dpapi_oe_clean();
NTSTATUS kuhl_m_dpapi_oe_cache(int argc, wchar_t * argv[]);
BOOL kuhl_m_dpapi_oe_is_sid_valid_ForCacheOrAuto(PSID sid, LPCWSTR szSid, BOOL AutoOrCache);
BOOL kuhl_m_dpapi_oe_autosid(LPCWSTR filename, LPWSTR * pSid);

LIST_ENTRY gDPAPI_Masterkeys;
@@ -8,39 +8,51 @@
NTSTATUS kuhl_m_dpapi_cred(int argc, wchar_t * argv[])
{
PCWSTR infile;
PVOID file, out;
DWORD szFile, szOut;
PBYTE file;
PVOID out;
DWORD i, szFile, szOut;
BOOL isNT5Cred;
PKULL_M_CRED_BLOB cred;
PKULL_M_CRED_LEGACY_CREDS_BLOB legacyCreds;

if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL))
{
if(kull_m_file_readData(infile, (PBYTE *) &file, &szFile))
if(kull_m_file_readData(infile, &file, &szFile))
{
isNT5Cred = RtlEqualGuid((PBYTE) file + sizeof(DWORD), &KULL_M_DPAPI_GUID_PROVIDER);
kull_m_dpapi_blob_quick_descr(0, isNT5Cred ? file : ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blob);
if(kuhl_m_dpapi_unprotect_raw_or_blob(isNT5Cred ? file : ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blob, isNT5Cred ? szFile : ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blobSize, NULL, argc, argv, NULL, 0, &out, &szOut, isNT5Cred ? L"Decrypting Legacy Credential(s):\n" : L"Decrypting Credential:\n"))
if(szFile >= FIELD_OFFSET(KULL_M_DPAPI_BLOB, dwMasterKeyVersion))
{
if(isNT5Cred)
isNT5Cred = RtlEqualGuid(file + sizeof(DWORD), &KULL_M_DPAPI_GUID_PROVIDER);
kull_m_dpapi_blob_quick_descr(0, isNT5Cred ? file : ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blob);
if(kuhl_m_dpapi_unprotect_raw_or_blob(isNT5Cred ? file : ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blob, isNT5Cred ? szFile : ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blobSize, NULL, argc, argv, NULL, 0, &out, &szOut, isNT5Cred ? L"Decrypting Legacy Credential(s):\n" : L"Decrypting Credential:\n"))
{
if(legacyCreds = kull_m_cred_legacy_creds_create(out))
if(isNT5Cred)
{
kull_m_cred_legacy_creds_descr(0, legacyCreds);
kull_m_cred_legacy_creds_delete(legacyCreds);
if(legacyCreds = kull_m_cred_legacy_creds_create(out))
{
kull_m_cred_legacy_creds_descr(0, legacyCreds);
for(i = 0; i < legacyCreds->__count; i++)
kuhl_m_dpapi_cred_tryEncrypted(legacyCreds->Credentials[i]->TargetName, legacyCreds->Credentials[i]->CredentialBlob, legacyCreds->Credentials[i]->CredentialBlobSize, argc, argv);
kull_m_cred_legacy_creds_delete(legacyCreds);
}
}
}
else
{
if(cred = kull_m_cred_create(out))
else
{
kull_m_cred_descr(0, cred);
kull_m_cred_delete(cred);
if(cred = kull_m_cred_create(out))
{
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);
kprintf(L"\n");
}
else kuhl_m_dpapi_cred_tryEncrypted(cred->TargetName, cred->CredentialBlob, cred->CredentialBlobSize, argc, argv);
kull_m_cred_delete(cred);
}
}
LocalFree(out);
}
LocalFree(out);
LocalFree(file);
}
LocalFree(file);
}
else PRINT_ERROR_AUTO(L"kull_m_file_readData");
}
@@ -84,7 +96,6 @@ NTSTATUS kuhl_m_dpapi_vault(int argc, wchar_t * argv[])
{
kprintf(L" AES128 key: "); kull_m_string_wprintf_hex(aes128, AES_128_KEY_SIZE, 0); kprintf(L"\n");
kprintf(L" AES256 key: "); kull_m_string_wprintf_hex(aes256, AES_256_KEY_SIZE, 0); kprintf(L"\n\n");

if(CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
{
for(i = 0; i < vaultCredential->__cbElements; i++)
@@ -146,10 +157,32 @@ NTSTATUS kuhl_m_dpapi_vault(int argc, wchar_t * argv[])
else PRINT_ERROR_AUTO(L"kull_m_file_readData (cred)");
}
else PRINT_ERROR(L"Input Cred file needed (/cred:file)\n");

return STATUS_SUCCESS;
}

void kuhl_m_dpapi_cred_tryEncrypted(LPCWSTR target, LPCBYTE data, DWORD dataLen, int argc, wchar_t * argv[])
{
PVOID cred;
DWORD credLen;
if(wcsstr(target, L"Microsoft_WinInet_"))
{
if(dataLen >= FIELD_OFFSET(KULL_M_DPAPI_BLOB, dwMasterKeyVersion))
{
if(RtlEqualGuid(data + sizeof(DWORD), &KULL_M_DPAPI_GUID_PROVIDER))
{
kprintf(L"\n");
if(kuhl_m_dpapi_unprotect_raw_or_blob(data, dataLen, NULL, argc, argv, KULL_M_CRED_ENTROPY_CRED_DER, sizeof(KULL_M_CRED_ENTROPY_CRED_DER), &cred, &credLen, L"Decrypting additional blob\n"))
{
kprintf(L" CredentialBlob: ");
kull_m_string_printSuspectUnicodeString(cred, credLen);
LocalFree(cred);
}
}
}
}
}

BOOL kuhl_m_dpapi_vault_key_type(PKULL_M_CRED_VAULT_CREDENTIAL_ATTRIBUTE attribute, HCRYPTPROV hProv, BYTE aes128[AES_128_KEY_SIZE], BYTE aes256[AES_256_KEY_SIZE], HCRYPTKEY *hKey, BOOL *isAttr)
{
BOOL status = FALSE;
@@ -6,6 +6,7 @@
#pragma once
#include "../kuhl_m_dpapi.h"
#include "../modules/kull_m_cred.h"
#include "../../sekurlsa/kuhl_m_sekurlsa.h"

typedef struct _KUHL_M_DPAPI_ENCRYPTED_CRED {
DWORD version;
@@ -17,5 +18,6 @@ typedef struct _KUHL_M_DPAPI_ENCRYPTED_CRED {
NTSTATUS kuhl_m_dpapi_cred(int argc, wchar_t * argv[]);
NTSTATUS kuhl_m_dpapi_vault(int argc, wchar_t * argv[]);

void kuhl_m_dpapi_cred_tryEncrypted(LPCWSTR target, LPCBYTE data, DWORD dataLen, int argc, wchar_t * argv[]);
BOOL kuhl_m_dpapi_vault_key_type(PKULL_M_CRED_VAULT_CREDENTIAL_ATTRIBUTE attribute, HCRYPTPROV hProv, BYTE aes128[AES_128_KEY_SIZE], BYTE aes256[AES_256_KEY_SIZE], HCRYPTKEY *hKey, BOOL *isAttr);
void kuhl_m_dpapi_vault_basic(PVOID data, DWORD size, GUID *schema);

0 comments on commit 3c81f16

Please sign in to comment.
You can’t perform that action at this time.