Skip to content

Conversation

@xHector1337
Copy link
Contributor

@xHector1337 xHector1337 commented Aug 20, 2025

This PR extends current PoolParty functionalities to:

  • x86 -> x86 (native not wow64) on Windows 10+
  • Verify if we can use it against Windows 7+ targets x86 (Windows 7, Windows 8, Windows 8.1 not supported)
  • Verify if we can use it against Windows 7+ targets x64 (Windows 7, Windows 8, Windows 8.1 not supported)

Technique only works on Windows 10+ x86
The injection are achieved by adding a new variant, the 'Worker Factory Start Routine Overwrite`

TEST

  • compile custom debug metsrv x86 on VS2019/VS2022, put it in <metasploit-framework>/data/meterpreter/
  • start msfconsole
  • use payload/windows/meterpreter_reverse_tcp (or staged version. it doesn't matter)
  • set MeterpreterDebugBuild true
  • set MeterpreterDebugLogging rpath:C:/Windows/Temp/doo.txt
  • generate payload and drop it to a Windows 10 x86 target.
  • get a meterpreter session
  • open a notepad and get the pid
  • migrate <notepad pid>
  • Inspect the log
  • You should see successful migration using the worker_factory_overwrite variant.

@dledda-r7 dledda-r7 assigned dledda-r7 and unassigned dledda-r7 Aug 21, 2025
@smcintyre-r7
Copy link
Contributor

Is there a scenario where this technique will work while the existing one won't? I don't think our goal is to cover all of the PoolParty techniques since we only need one that suits our need and the user can't select which to use. We'd be more interested in adding the existing PoolParty support to x86 to expand our coverage.

@dledda-r7
Copy link
Contributor

dledda-r7 commented Aug 21, 2025

@smcintyre-r7, This technique is the good candidate to cover the following missing ones:

x86 -> x86. that's because we don't have clear idea of the TP_DIRECT structure on 32-bit systems and we either need to do some fuzzing to understand the offset or use this technique

x64 -> wow64
wow64 -> wow64

This may be a long-shot, but based on the #710 (comment) comment of mine, i think with the WorkerFactory technique we can bypass the control flow guard check happening in wow64 context

EDIT: This is outside of the scope of this PR... We will circle back fo WoW64

@xHector1337 xHector1337 marked this pull request as ready for review September 3, 2025 08:55
@dledda-r7
Copy link
Contributor

dledda-r7 commented Sep 12, 2025

Windows 7 x64 & x86

[0f24] [MIGRATE] Attempting to migrate. ProcessID=3404, Arch=x64
[0f24] [MIGRATE] Attempting to migrate. PayloadLength=289792 StubLength=317
[0f24] [INJECT][supports_poolparty_injection] RtlGetVersion: 0000000076F155E0
[0f24] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0f24] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 1
[0f24] [INJECT][supports_poolparty_injection] bIsSupported: 1
[0f24] [MIGRATE] Got SeDebugPrivilege!
[0f24] [MIGRATE] creating the configuration block
[0f24] [CONFIG] preparing the configuration
[0f24] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0f24] [CONFIG] Comms handle set to 000000000000009C
[0f24] [CONFIG] Total of 1614 bytes located at 0x00000000026FBDC0
[0f24] [MIGRATE] Config of 1614 bytes stashed at 0x00000000026FBDC0
[0f24] [MIGRATE] Duplicated Event Handle: 0x16c
[0f24] [MIGRATE] Migrate stub: 0x00000000001B0000 -> 317 bytes
[0f24] [MIGRATE] Migrate context: 0x00000000001B013D -> 388 bytes
[0f24] [MIGRATE] Migrate payload: 0x00000000001B02C1 -> 289792 bytes
[0f24] [MIGRATE] Configuration: 0x00000000001F6EC1 -> 1614 bytes
[0f24] [INJECT][supports_poolparty_injection] RtlGetVersion: 0000000076F155E0
[0f24] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0f24] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 1
[0f24] [INJECT][supports_poolparty_injection] bIsSupported: 1
[0f24] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: 0000000076F30040 NtQueryObject: 0000000076F2FFB0
[0f24] [INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: 0000000076F31510
[0f24] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory = 0000000076F31090 && NtSetInformationWorkerFactory = 0000000076F314F0
[0f24] [INJECT][inject_via_poolparty] using: poolparty_stub_x64
[0f24] [INJECT][inject_via_poolparty] lpStub: 00000000001935E0
[0f24] [INJECT][inject_via_poolparty] ctx [0000000000200112] lpStartAddress: 00000000001B0000 lpParameter 00000000001B013D hTriggerEvent 0000000000000170
[0f24] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION
[0f24] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 00000000026FC9B0
[0f24] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 00000000C0000003
[0f24] [INJECT][inject_via_poolparty][remote_tp_direct_insertion] Unable to locate IoCompletion object inside the target process.. error=50 (0x32)
[0f24] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_WORKER_FACTORY_OVERWRITE
[0f24] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 00000000026FC9B0
[0f24] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 00000000C0000003
[0f24] [INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Couldn't find TpWorkerFactory object in the target process or couldn't duplicate the found TpWorkerFactory object. error=50 (0x32)
[0f24] [INJECT] inject_via_poolparty: none of the supported variant worked.. error=1 (0x1)
[0f24] [MIGRATE] inject_via_poolparty failed, proceeding with legacy injection.
[0f24] [INJECT] inject_via_remotethread: succeeded
[0f24] [INJECT] inject_via_remotethread: Sending a migrate response...
[0cf0] [MIGRATE] Attempting to migrate. ProcessID=3616, Arch=x86
[0cf0] [MIGRATE] Attempting to migrate. PayloadLength=250368 StubLength=223
[0cf0] [INJECT][supports_poolparty_injection] RtlGetVersion: 7784FB4F
[0cf0] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[0cf0] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 1
[0cf0] [INJECT][supports_poolparty_injection] bIsSupported: 1
[0cf0] [MIGRATE] creating the configuration block
[0cf0] [CONFIG] preparing the configuration
[0cf0] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0cf0] [CONFIG] Comms handle set to 0000009C
[0cf0] [CONFIG] Total of 1614 bytes located at 0x01B7B870
[0cf0] [MIGRATE] Config of 1614 bytes stashed at 0x01B7B870
[0cf0] [MIGRATE] Duplicated Event Handle: 0x168
[0cf0] [MIGRATE] Migrate stub: 0x00580000 -> 223 bytes
[0cf0] [MIGRATE] Migrate context: 0x005800DF -> 388 bytes
[0cf0] [MIGRATE] Migrate payload: 0x00580263 -> 250368 bytes
[0cf0] [MIGRATE] Configuration: 0x005BD463 -> 1614 bytes
[0cf0] [INJECT][supports_poolparty_injection] RtlGetVersion: 7784FB4F
[0cf0] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[0cf0] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 1
[0cf0] [INJECT][supports_poolparty_injection] bIsSupported: 1
[0cf0] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: 77835490 NtQueryObject: 77835570
[0cf0] [INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: 77835B40
[0cf0] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory = 778354F0 && NtSetInformationWorkerFactory = 77835B20
[0cf0] [INJECT][inject_via_poolparty] using: poolparty_stub_x86
[0cf0] [INJECT][inject_via_poolparty] lpStub: 002F1480
[0cf0] [INJECT][inject_via_poolparty] ctx [001800CE] lpStartAddress: 00580000 lpParameter 005800DF hTriggerEvent 0000016C
[0cf0] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_WORKER_FACTORY_OVERWRITE
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 01B7BEC8
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : C0000003
[0cf0] [INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Couldn't find TpWorkerFactory object in the target process or couldn't duplicate the found TpWorkerFactory object. error=50 (0x32)
[0cf0] [INJECT] inject_via_poolparty: none of the supported variant worked.. error=1 (0x1)
[0cf0] [MIGRATE] inject_via_poolparty failed, proceeding with legacy injection.
[0cf0] [INJECT] inject_via_remotethread: succeeded
[0cf0] [INJECT] inject_via_remotethread: Sending a migrate response...

@dledda-r7 dledda-r7 changed the title [WIP] Add support for PoolParty WorkerFactory Overwrite variant Add support for PoolParty WorkerFactory Overwrite variant Sep 12, 2025
@dledda-r7
Copy link
Contributor

dledda-r7 commented Sep 16, 2025

PR CURRENTLY BLOCKED

This PR is currently blocked until we fix our gem building system.
The PR looks good, code is clean, it was already tested with Windows 10+ systems and some older Windows 7 systems.
Needs minor testing to older version (Windows XP+) just to ensure meterpreter is running.

Thanks a lot @xHector1337 for your amazing work!

25/09/2025 PR IS NOT BLOCKED ANYMORE

@xHector1337
Copy link
Contributor Author

xHector1337 commented Sep 26, 2025

Windows XP Pro SP 2 x64

[0738] [PKT FIND] Types don't match, skipping.
[0738] [PKT FIND] TLV header length: 137204
[0738] [PKT FIND] TLV header type: 537133460
[0738] [PKT FIND] Types don't match, skipping.
[0738] [PKT FIND] TLV header length: 317
[0738] [PKT FIND] TLV header type: 537133467
[0738] [PKT FIND] Found!
[0738] [MIGRATE] Attempting to migrate. ProcessID=2384, Arch=x64
[0738] [MIGRATE] Attempting to migrate. PayloadLength=289792 StubLength=317
[0738] [INJECT][supports_poolparty_injection] RtlGetVersion: 0000000077ED89D0
[0738] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0738] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 5 os.dwMinorVersion: 2
[0738] [MIGRATE] Got SeDebugPrivilege!
[0738] [MIGRATE] creating the configuration block
[0738] [CONFIG] preparing the configuration
[0738] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0738] [CONFIG] Comms handle set to 000000000000006C
[0738] [CONFIG] Total of 1614 bytes located at 0x0000000000179010
[0738] [MIGRATE] Config of 1614 bytes stashed at 0x0000000000179010
[0738] [MIGRATE] Duplicated Event Handle: 0x64
[0738] [MIGRATE] Migrate stub: 0x0000000001DA0000 -> 317 bytes
[0738] [MIGRATE] Migrate context: 0x0000000001DA013D -> 388 bytes
[0738] [MIGRATE] Migrate payload: 0x0000000001DA02C1 -> 289792 bytes
[0738] [MIGRATE] Configuration: 0x0000000001DE6EC1 -> 1614 bytes
[0738] [INJECT] inject_via_remotethread: succeeded
[0738] [INJECT] inject_via_remotethread: Sending a migrate response...
[0738] [TRANSMIT] Sending packet to the server
[0738] [PKT FIND] Looking for type 65538
[0738] [PKT FIND] TLV header length: 12
[0738] [PKT FIND] TLV header type: 131073
[0738] [PKT FIND] Types don't match, skipping.
[0738] [PKT FIND] TLV header length: 41
[0738] [PKT FIND] TLV header type: 65538
[0738] [PKT FIND] Found!
[0738] [ENC] Preparing for encryption ...
[0738] [ENC] Context is valid, moving on ... 
[0738] [ENC] Context is enabled, doing the AES encryption
[0738] [ENC] IV: 71ED68A24E30E8DC9493451A7F95035E
[0738] [ENC] IV Set successfully
[0738] [ENC] Data encrypted successfully, size is 112
[0738] [ENC] Packet buffer size is: 160
[0738] [ENC] Sending header (before XOR): [0x63 0x3F 0x01 0xF9] [0x57 0xFA 0x30 0x70 0x93 0xDD 0x4A 0x2A 0xB4 0x94 0x39 0x81 0x98 0xD2 0x3D 0x82] [0x00 0x00 0x00 0x01] [0x00 0x00 0x00 0x88] [0x00 0x00 0x00 0x01]
[0738] [XOR] XORing 156 bytes with key 633f01f9
[0738] [ENC] Packet encoded and ready for transmission
[0738] [ENC] Sending header (after XOR): [0x63 0x3F 0x01 0xF9] [0x34 0xC5 0x31 0x89 0xF0 0xE2 0x4B 0xD3 0xD7 0xAB 0x38 0x78 0xFB 0xED 0x3C 0x7B] [0x63 0x3F 0x01 0xF8] [0x63 0x3F 0x01 0x71] [0x63 0x3F 0x01 0xF8]
[0738] [PKT FIND] Looking for type 131073
[0738] [PKT FIND] TLV header length: 12
[0738] [PKT FIND] TLV header type: 131073
[0738] [PKT FIND] Found!
[0738] [PACKET] Sending packet to remote, length: 160, command id: 14

** Windows XP Pro SP 3 x86 **

[05fc] [PKT FIND] TLV header type: 537133460
[05fc] [PKT FIND] Types don't match, skipping.
[05fc] [PKT FIND] TLV header length: 231
[05fc] [PKT FIND] TLV header type: 262555
[05fc] [PKT FIND] Found!
[05fc] [MIGRATE] Attempting to migrate. ProcessID=460, Arch=x86
[05fc] [MIGRATE] Attempting to migrate. PayloadLength=250368 StubLength=223
[05fc] [INJECT][supports_poolparty_injection] RtlGetVersion: 7C91964B
[05fc] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[05fc] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 5 os.dwMinorVersion: 1
[05fc] [MIGRATE] creating the configuration block
[05fc] [CONFIG] preparing the configuration
[05fc] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[05fc] [CONFIG] Comms handle set to 00000060
[05fc] [CONFIG] Total of 1614 bytes located at 0x00BEE210
[05fc] [MIGRATE] Config of 1614 bytes stashed at 0x00BEE210
[05fc] [MIGRATE] Duplicated Event Handle: 0x7c
[05fc] [MIGRATE] Migrate stub: 0x00910000 -> 223 bytes
[05fc] [MIGRATE] Migrate context: 0x009100DF -> 388 bytes
[05fc] [MIGRATE] Migrate payload: 0x00910263 -> 250368 bytes
[05fc] [MIGRATE] Configuration: 0x0094D463 -> 1614 bytes
[05fc] [INJECT] inject_via_remotethread: succeeded
[05fc] [INJECT] inject_via_remotethread: Sending a migrate response...
[05fc] [TRANSMIT] Sending packet to the server
[05fc] [PKT FIND] Looking for type 65538
[05fc] [PKT FIND] TLV header length: 12
[05fc] [PKT FIND] TLV header type: 131073
[05fc] [PKT FIND] Types don't match, skipping.
[05fc] [PKT FIND] TLV header length: 41
[05fc] [PKT FIND] TLV header type: 65538
[05fc] [PKT FIND] Found!

@dledda-r7 dledda-r7 removed their assignment Oct 8, 2025
@dledda-r7 dledda-r7 force-pushed the poolparty_worker_factory_start_routine_overwrite branch from c7c36b5 to a771597 Compare November 13, 2025 13:32
@dledda-r7
Copy link
Contributor

dledda-r7 commented Jan 7, 2026

Windows XP SP3 x86

[07bc] [MIGRATE] Attempting to migrate. ProcessID=392, Arch=x86
[07bc] [MIGRATE] Attempting to migrate. PayloadLength=254464 StubLength=223
[07bc] [INJECT][supports_poolparty_injection] RtlGetVersion: 77F581C4
[07bc] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[07bc] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 5 os.dwMinorVersion: 1
[07bc] [MIGRATE] creating the configuration block
[07bc] [CONFIG] preparing the configuration
[07bc] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[07bc] [CONFIG] Comms handle set to 00000088
[07bc] [CONFIG] Total of 1614 bytes located at 0x0016DA90
[07bc] [MIGRATE] Config of 1614 bytes stashed at 0x0016DA90
[07bc] [MIGRATE] Duplicated Event Handle: 0x4c
[07bc] [MIGRATE] Migrate stub: 0x008A0000 -> 223 bytes
[07bc] [MIGRATE] Migrate context: 0x008A00DF -> 388 bytes
[07bc] [MIGRATE] Migrate payload: 0x008A0263 -> 254464 bytes
[07bc] [MIGRATE] Configuration: 0x008DE463 -> 1614 bytes
[07bc] [INJECT] inject_via_remotethread: succeeded
[07bc] [INJECT] inject_via_remotethread: Sending a migrate response...

Windows 7 x86

[09e4] [MIGRATE] Attempting to migrate. ProcessID=3676, Arch=x86
[09e4] [MIGRATE] Attempting to migrate. PayloadLength=251392 StubLength=223
[09e4] [INJECT][supports_poolparty_injection] RtlGetVersion: 7709FB4F
[09e4] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[09e4] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 1
[09e4] [MIGRATE] creating the configuration block
[09e4] [CONFIG] preparing the configuration
[09e4] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[09e4] [CONFIG] Comms handle set to 0000009C
[09e4] [CONFIG] Total of 1614 bytes located at 0x01BBDF48
[09e4] [MIGRATE] Config of 1614 bytes stashed at 0x01BBDF48
[09e4] [MIGRATE] Duplicated Event Handle: 0x168
[09e4] [MIGRATE] Migrate stub: 0x001A0000 -> 223 bytes
[09e4] [MIGRATE] Migrate context: 0x001A00DF -> 388 bytes
[09e4] [MIGRATE] Migrate payload: 0x001A0263 -> 251392 bytes
[09e4] [MIGRATE] Configuration: 0x001DD863 -> 1614 bytes
[09e4] [INJECT] inject_via_remotethread: succeeded
[09e4] [INJECT] inject_via_remotethread: Sending a migrate response...
[09e4] [TRANSMIT] Sending packet to the server

Windows 7 x64

[0904] [MIGRATE] Attempting to migrate. ProcessID=1784, Arch=x64
[0904] [MIGRATE] Attempting to migrate. PayloadLength=293888 StubLength=317
[0904] [INJECT][supports_poolparty_injection] RtlGetVersion: 0000000076D755E0
[0904] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0904] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 1
[0904] [MIGRATE] Got SeDebugPrivilege!
[0904] [MIGRATE] creating the configuration block
[0904] [CONFIG] preparing the configuration
[0904] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0904] [CONFIG] Comms handle set to 000000000000009C
[0904] [CONFIG] Total of 1614 bytes located at 0x00000000025E6CA0
[0904] [MIGRATE] Config of 1614 bytes stashed at 0x00000000025E6CA0
[0904] [MIGRATE] Duplicated Event Handle: 0x168
[0904] [MIGRATE] Migrate stub: 0x0000000002C30000 -> 317 bytes
[0904] [MIGRATE] Migrate context: 0x0000000002C3013D -> 388 bytes
[0904] [MIGRATE] Migrate payload: 0x0000000002C302C1 -> 293888 bytes
[0904] [MIGRATE] Configuration: 0x0000000002C77EC1 -> 1614 bytes
[0904] [INJECT] inject_via_remotethread: succeeded
[0904] [INJECT] inject_via_remotethread: Sending a migrate response...

Windows 8 x86

[0bfc] [MIGRATE] Attempting to migrate. ProcessID=1264, Arch=x86
[0bfc] [MIGRATE] Attempting to migrate. PayloadLength=251904 StubLength=223
[0bfc] [INJECT][supports_poolparty_injection] RtlGetVersion: 77606EF4
[0bfc] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[0bfc] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 2
[0bfc] [MIGRATE] creating the configuration block
[0bfc] [CONFIG] preparing the configuration
[0bfc] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0bfc] [CONFIG] Comms handle set to 000000A8
[0bfc] [CONFIG] Total of 1614 bytes located at 0x017663F8
[0bfc] [MIGRATE] Config of 1614 bytes stashed at 0x017663F8
[0bfc] [MIGRATE] Duplicated Event Handle: 0x11c
[0bfc] [MIGRATE] Migrate stub: 0x00F40000 -> 223 bytes
[0bfc] [MIGRATE] Migrate context: 0x00F400DF -> 388 bytes
[0bfc] [MIGRATE] Migrate payload: 0x00F40263 -> 251904 bytes
[0bfc] [MIGRATE] Configuration: 0x00F7DA63 -> 1614 bytes
[0bfc] [INJECT] inject_via_remotethread: succeeded
[0bfc] [INJECT] inject_via_remotethread: Sending a migrate response...

Windows 8 x64

[0c84] [MIGRATE] Attempting to migrate. ProcessID=880, Arch=x64
[0c84] [MIGRATE] Attempting to migrate. PayloadLength=292352 StubLength=317
[0c84] [INJECT][supports_poolparty_injection] RtlGetVersion: 000007F80C364CB8
[0c84] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0c84] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 2
[0c84] [MIGRATE] Got SeDebugPrivilege!
[0c84] [MIGRATE] creating the configuration block
[0c84] [CONFIG] preparing the configuration
[0c84] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0c84] [CONFIG] Comms handle set to 00000000000000A8
[0c84] [CONFIG] Total of 1614 bytes located at 0x00000000020F0480
[0c84] [MIGRATE] Config of 1614 bytes stashed at 0x00000000020F0480
[0c84] [MIGRATE] Duplicated Event Handle: 0x11c
[0c84] [MIGRATE] Migrate stub: 0x0000001A1F430000 -> 317 bytes
[0c84] [MIGRATE] Migrate context: 0x0000001A1F43013D -> 388 bytes
[0c84] [MIGRATE] Migrate payload: 0x0000001A1F4302C1 -> 292352 bytes
[0c84] [MIGRATE] Configuration: 0x0000001A1F4778C1 -> 1614 bytes
[0c84] [INJECT] inject_via_remotethread: succeeded
[0c84] [INJECT] inject_via_remotethread: Sending a migrate response...
[0c84] [TRANSMIT] Sending packet to the server

Windows 8.1 x86

[1294] [MIGRATE] Attempting to migrate. ProcessID=4976, Arch=x86
[1294] [MIGRATE] Attempting to migrate. PayloadLength=251392 StubLength=223
[1294] [INJECT][supports_poolparty_injection] RtlGetVersion: 77DAEAB0
[1294] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[1294] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 3
[1294] [MIGRATE] creating the configuration block
[1294] [CONFIG] preparing the configuration
[1294] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[1294] [CONFIG] Comms handle set to 000000E8
[1294] [CONFIG] Total of 1614 bytes located at 0x00301DB8
[1294] [MIGRATE] Config of 1614 bytes stashed at 0x00301DB8
[1294] [MIGRATE] Duplicated Event Handle: 0x138
[1294] [MIGRATE] Migrate stub: 0x036C0000 -> 223 bytes
[1294] [MIGRATE] Migrate context: 0x036C00DF -> 388 bytes
[1294] [MIGRATE] Migrate payload: 0x036C0263 -> 251392 bytes
[1294] [MIGRATE] Configuration: 0x036FD863 -> 1614 bytes
[1294] [INJECT] inject_via_remotethread: succeeded
[1294] [INJECT] inject_via_remotethread: Sending a migrate response...
[1294] [TRANSMIT] Sending packet to the server

Windows 8.1 x64

[0f74] [MIGRATE] Attempting to migrate. ProcessID=168, Arch=x64
[0f74] [MIGRATE] Attempting to migrate. PayloadLength=291840 StubLength=317
[0f74] [INJECT][supports_poolparty_injection] RtlGetVersion: 00007FFC6BAF00A0
[0f74] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0f74] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 6 os.dwMinorVersion: 3
[0f74] [MIGRATE] Got SeDebugPrivilege!
[0f74] [MIGRATE] creating the configuration block
[0f74] [CONFIG] preparing the configuration
[0f74] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0f74] [CONFIG] Comms handle set to 00000000000000E8
[0f74] [CONFIG] Total of 1614 bytes located at 0x00000000001F6810
[0f74] [MIGRATE] Config of 1614 bytes stashed at 0x00000000001F6810
[0f74] [MIGRATE] Duplicated Event Handle: 0x138
[0f74] [MIGRATE] Migrate stub: 0x000000CBB4660000 -> 317 bytes
[0f74] [MIGRATE] Migrate context: 0x000000CBB466013D -> 388 bytes
[0f74] [MIGRATE] Migrate payload: 0x000000CBB46602C1 -> 291840 bytes
[0f74] [MIGRATE] Configuration: 0x000000CBB46A76C1 -> 1614 bytes
[0f74] [INJECT] inject_via_remotethread: succeeded
[0f74] [INJECT] inject_via_remotethread: Sending a migrate response...
[0f74] [TRANSMIT] Sending packet to the server

Windows 10 x86

[32a4] [MIGRATE] Attempting to migrate. ProcessID=14332, Arch=x86
[32a4] [MIGRATE] Attempting to migrate. PayloadLength=254464 StubLength=223
[32a4] [INJECT][supports_poolparty_injection] RtlGetVersion: 76FBA090
[32a4] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[32a4] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 10 os.dwMinorVersion: 0
[32a4] [MIGRATE] creating the configuration block
[32a4] [CONFIG] preparing the configuration
[32a4] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[32a4] [CONFIG] Comms handle set to 00000190
[32a4] [CONFIG] Total of 1614 bytes located at 0x01C83880
[32a4] [MIGRATE] Config of 1614 bytes stashed at 0x01C83880
[32a4] [MIGRATE] Duplicated Event Handle: 0x3ac
[32a4] [MIGRATE] Migrate stub: 0x06480000 -> 223 bytes
[32a4] [MIGRATE] Migrate context: 0x064800DF -> 388 bytes
[32a4] [MIGRATE] Migrate payload: 0x06480263 -> 254464 bytes
[32a4] [MIGRATE] Configuration: 0x064BE463 -> 1614 bytes
[32a4] [INJECT][supports_poolparty_injection] RtlGetVersion: 76FBA090
[32a4] [INJECT][supports_poolparty_injection] dwSourceArch: 1 dwDestinationArch: 1
[32a4] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 10 os.dwMinorVersion: 0
[32a4] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: 7701EC40 NtQueryObject: 7701EA80
[32a4] [INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: 7701DE30
[32a4] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory = 7701EB80 && NtSetInformationWorkerFactory = 7701DE70
[32a4] [INJECT][inject_via_poolparty] using: poolparty_stub_x86
[32a4] [INJECT][inject_via_poolparty] ctx [064C00CE] lpStartAddress: 06480000 lpParameter 064800DF hTriggerEvent 000003B0
[32a4] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION
[32a4] [INJECT][inject_via_poolparty][remote_tp_direct_insertion] Currently only x86-64 destination arch is supported.. error=50 (0x32)
[32a4] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_WORKER_FACTORY_OVERWRITE
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 007241A0
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : C0000004
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc lpProcessInfo: 01C85F88
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 00000000
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 01C85F88 dwInformationSizeIn: 6616
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] lpObjectInfo: 01C90B30
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 00000000
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 00000000
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 00000000
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 00000000
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 00000000
[32a4] [INJECT][inject_via_poolparty][get_remote_handle] hHijackHandle: 00000344
[32a4] [INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtQueryInformationWorkerFactory returned 0x0 && ReturnLength = 96
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] Dump of Worker Factory
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.Paused = 00000000
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.ThreadMaximum = 00000300
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.ThreadMinimum = 00000000
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.PendingWorkerCount = 00000000
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.WaitingWorkerCount = 00000002
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.TotalWorkerCount = 00000002
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.LastThreadCreationStatus = 00000000
[32a4] [INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] Setting WorkerFactoryThreadMinimum to 3
[32a4] [INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtSetInformationWorkerFactory returned 0x0
[32a4] [INJECT][inject_via_poolparty][worker_factory_start_routine_overwrite] NtQueryInformationWorkerFactory returned 0x0 && ReturnLength = 96
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] Dump of Worker Factory
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.Paused = 00000000
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.ThreadMaximum = 00000300
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.ThreadMinimum = 00000003
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.PendingWorkerCount = 00000001
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.WaitingWorkerCount = 00000002
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.TotalWorkerCount = 00000002
[32a4] [INJECT][inject_via_poolparty][DEBUG WORKER FACTORY] WorkerFactoryBasicInfo.LastThreadCreationStatus = 00000000
[32a4] [INJECT] inject_via_poolparty: injected!
[32a4] [INJECT] inject_via_poolparty: Sending a migrate response...

Windows 10 x64

[0cf0] [MIGRATE] Attempting to migrate. ProcessID=5672, Arch=x64
[0cf0] [MIGRATE] Attempting to migrate. PayloadLength=293888 StubLength=317
[0cf0] [INJECT][supports_poolparty_injection] RtlGetVersion: 00007FFC2D78E520
[0cf0] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0cf0] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 10 os.dwMinorVersion: 0
[0cf0] [MIGRATE] Got SeDebugPrivilege!
[0cf0] [MIGRATE] creating the configuration block
[0cf0] [CONFIG] preparing the configuration
[0cf0] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[0cf0] [CONFIG] Comms handle set to 00000000000001A0
[0cf0] [CONFIG] Total of 1614 bytes located at 0x00000000024D0830
[0cf0] [MIGRATE] Config of 1614 bytes stashed at 0x00000000024D0830
[0cf0] [MIGRATE] Duplicated Event Handle: 0x3c0
[0cf0] [MIGRATE] Migrate stub: 0x0000023B34570000 -> 317 bytes
[0cf0] [MIGRATE] Migrate context: 0x0000023B3457013D -> 388 bytes
[0cf0] [MIGRATE] Migrate payload: 0x0000023B345702C1 -> 293888 bytes
[0cf0] [MIGRATE] Configuration: 0x0000023B345B7EC1 -> 1614 bytes
[0cf0] [INJECT][supports_poolparty_injection] RtlGetVersion: 00007FFC2D78E520
[0cf0] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[0cf0] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 10 os.dwMinorVersion: 0
[0cf0] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: 00007FFC2D7ED3D0 NtQueryObject: 00007FFC2D7ED2B0
[0cf0] [INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: 00007FFC2D7F04C0
[0cf0] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory = 00007FFC2D7EFA80 && NtSetInformationWorkerFactory = 00007FFC2D7F0480
[0cf0] [INJECT][inject_via_poolparty] using: poolparty_stub_x64
[0cf0] [INJECT][inject_via_poolparty] ctx [0000023B345C0112] lpStartAddress: 0000023B34570000 lpParameter 0000023B3457013D hTriggerEvent 00000000000003C4
[0cf0] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 00000000024DB900
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 00000000C0000004
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc lpProcessInfo: 00000000024E9C80
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 0000000000000000
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 00000000024E9C80 dwInformationSizeIn: 9656
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] lpObjectInfo: 00000000024DB900
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[0cf0] [INJECT][inject_via_poolparty][get_remote_handle] hHijackHandle: 0000000000000398
[0cf0] [INJECT][inject_via_poolparty][remote_tp_wait_insertion] ZwSetIoCompletion: 0
[0cf0] [INJECT] inject_via_poolparty: injected!
[0cf0] [INJECT] inject_via_poolparty: Sending a migrate response...

Windows 11

[1c48] [MIGRATE] Attempting to migrate. ProcessID=5404, Arch=x64
[1c48] [MIGRATE] Attempting to migrate. PayloadLength=293888 StubLength=317
[1c48] [INJECT][supports_poolparty_injection] RtlGetVersion: 00007FF95CEDF0A0
[1c48] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[1c48] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 10 os.dwMinorVersion: 0
[1c48] [MIGRATE] Got SeDebugPrivilege!
[1c48] [MIGRATE] creating the configuration block
[1c48] [CONFIG] preparing the configuration
[1c48] [CONFIG] Allocating 1036 bytes for transport, total of 1604 bytes
[1c48] [CONFIG] Comms handle set to 00000000000001BC
[1c48] [CONFIG] Total of 1614 bytes located at 0x00000000006264D0
[1c48] [MIGRATE] Config of 1614 bytes stashed at 0x00000000006264D0
[1c48] [MIGRATE] Duplicated Event Handle: 0x8f0
[1c48] [MIGRATE] Migrate stub: 0x000002D052390000 -> 317 bytes
[1c48] [MIGRATE] Migrate context: 0x000002D05239013D -> 388 bytes
[1c48] [MIGRATE] Migrate payload: 0x000002D0523902C1 -> 293888 bytes
[1c48] [MIGRATE] Configuration: 0x000002D0523D7EC1 -> 1614 bytes
[1c48] [INJECT][supports_poolparty_injection] RtlGetVersion: 00007FF95CEDF0A0
[1c48] [INJECT][supports_poolparty_injection] dwSourceArch: 2 dwDestinationArch: 2
[1c48] [INJECT][supports_poolparty_injection] os.dwMajorVersion: 10 os.dwMinorVersion: 0
[1c48] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationProcess: 00007FF95CF4F700 NtQueryObject: 00007FF95CF4F5E0
[1c48] [INJECT][inject_via_poolparty][ntdll_init] ZwSetIoCompletion: 00007FF95CF529D0
[1c48] [INJECT][inject_via_poolparty][ntdll_init] NtQueryInformationWorkerFactory = 00007FF95CF51EF0 && NtSetInformationWorkerFactory = 00007FF95CF52990
[1c48] [INJECT][inject_via_poolparty] using: poolparty_stub_x64
[1c48] [INJECT][inject_via_poolparty] ctx [000002D051F80112] lpStartAddress: 000002D052390000 lpParameter 000002D05239013D hTriggerEvent 00000000000008F4
[1c48] [INJECT][inject_via_poolparty] Attempting injection with variant POOLPARTY_TECHNIQUE_TP_DIRECT_INSERTION
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 00000000026112F0
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 00000000C0000004
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] HeapReAlloc lpProcessInfo: 00000000026112F0
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] NtQueryInformationProcess() : 0000000000000000
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] lpProcessInfo: 00000000026112F0 dwInformationSizeIn: 22816
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] lpObjectInfo: 0000000002616C20
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] pNtQueryObject result: 0000000000000000
[1c48] [INJECT][inject_via_poolparty][get_remote_handle] hHijackHandle: 0000000000000498
[1c48] [INJECT][inject_via_poolparty][remote_tp_wait_insertion] ZwSetIoCompletion: 0
[1c48] [INJECT] inject_via_poolparty: injected!
[1c48] [INJECT] inject_via_poolparty: Sending a migrate response...

Copy link
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was able to test the debug build here for the following cases and they all worked as expected.

  • Windows 7 SP1 x86
  • Windows 11 x64 (WOW64 -> WOW64)
  • Windows 10 x86

Copy link
Contributor

@smcintyre-r7 smcintyre-r7 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @xHector1337 for your work on this!

@smcintyre-r7 smcintyre-r7 merged commit ebb9cdd into rapid7:master Jan 8, 2026
28 of 31 checks passed
zeroSteiner added a commit to zeroSteiner/metasploit-framework that referenced this pull request Jan 8, 2026
@xHector1337 xHector1337 deleted the poolparty_worker_factory_start_routine_overwrite branch January 11, 2026 11:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants