Land #4442, wchen-r7's configurable session response timeout option

fixes #4431
bug/bundler_fix
Brent Cook 2014-12-29 13:01:00 -06:00
commit f9b141c1e2
No known key found for this signature in database
GPG Key ID: 663AF51BD5E4D8D5
1 changed files with 99 additions and 46 deletions

View File

@ -45,7 +45,8 @@ class Core
"-K" => [ false, "Terminate all sessions" ],
"-s" => [ true, "Run a script on the session given with -i, or all"],
"-r" => [ false, "Reset the ring buffer for the session given with -i, or all"],
"-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ])
"-u" => [ true, "Upgrade a shell to a meterpreter session on many platforms" ],
"-t" => [ true, "Set a response timeout (default: 15)"])
@@jobs_opts = Rex::Parser::Arguments.new(
"-h" => [ false, "Help banner." ],
@ -1222,7 +1223,7 @@ class Core
Rex::Socket::SwitchBoard.flush_routes
when "print"
tbl = Table.new(
tbl = Table.new(
Table::Style::Default,
'Header' => "Active Routing Table",
'Prefix' => "\n",
@ -1597,6 +1598,7 @@ class Core
cmds = []
script = nil
reset_ring = false
response_timeout = 15
# any arguments that don't correspond to an option or option arg will
# be put in here
@ -1646,6 +1648,10 @@ class Core
when "-h"
cmd_sessions_help
return false
when "-t"
if val.to_s =~ /^\d+$/
response_timeout = val.to_i
end
else
extra << val
end
@ -1684,30 +1690,39 @@ class Core
session = verify_session(s)
next unless session
print_status("Running '#{cmd}' on #{session.type} session #{s} (#{session.session_host})")
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
if session.type == 'meterpreter'
# If session.sys is nil, dont even try..
unless session.sys
print_error("Session #{s} does not have stdapi loaded, skipping...")
next
begin
if session.type == 'meterpreter'
# If session.sys is nil, dont even try..
unless session.sys
print_error("Session #{s} does not have stdapi loaded, skipping...")
next
end
c, c_args = cmd.split(' ', 2)
begin
process = session.sys.process.execute(c, c_args,
{
'Channelized' => true,
'Hidden' => true
})
if process && process.channel
data = process.channel.read
print_line(data) if data
end
rescue ::Rex::Post::Meterpreter::RequestError
print_error("Failed: #{$!.class} #{$!}")
rescue Rex::TimeoutError
print_error("Operation timed out")
end
elsif session.type == 'shell'
output = session.shell_command(cmd)
print_line(output) if output
end
c, c_args = cmd.split(' ', 2)
begin
process = session.sys.process.execute(c, c_args,
{
'Channelized' => true,
'Hidden' => true
})
rescue ::Rex::Post::Meterpreter::RequestError
print_error("Failed: #{$!.class} #{$!}")
end
if process && process.channel
data = process.channel.read
print_line(data) if data
end
elsif session.type == 'shell'
output = session.shell_command(cmd)
print_line(output) if output
ensure
# Restore timeout for each session
session.response_timeout = last_known_timeout
end
# If the session isn't a meterpreter or shell type, it
# could be a VNC session (which can't run commands) or
@ -1720,8 +1735,14 @@ class Core
session_list.each do |sess_id|
session = framework.sessions.get(sess_id)
if session
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
print_status("Killing session #{sess_id}")
session.kill
begin
session.kill
ensure
session.response_timeout = last_known_timeout
end
else
print_error("Invalid session identifier: #{sess_id}")
end
@ -1730,7 +1751,15 @@ class Core
print_status("Killing all sessions...")
framework.sessions.each_sorted do |s|
session = framework.sessions.get(s)
session.kill if session
if session
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
begin
session.kill
ensure
session.response_timeout = last_known_timeout
end
end
end
when 'detach'
print_status("Detaching the following session(s): #{session_list.join(', ')}")
@ -1738,18 +1767,30 @@ class Core
session = verify_session(sess_id)
# if session is interactive, it's detachable
if session
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
print_status("Detaching session #{sess_id}")
session.detach
begin
session.detach
ensure
session.response_timeout = last_known_timeout
end
end
end
when 'interact'
session = verify_session(sid)
if session
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
print_status("Starting interaction with #{session.name}...\n") unless quiet
self.active_session = session
session.interact(driver.input.dup, driver.output)
self.active_session = nil
driver.input.reset_tab_completion if driver.input.supports_readline
begin
self.active_session = session
session.interact(driver.input.dup, driver.output)
self.active_session = nil
driver.input.reset_tab_completion if driver.input.supports_readline
ensure
session.response_timeout = last_known_timeout
end
end
when 'scriptall'
unless script
@ -1770,15 +1811,21 @@ class Core
session = framework.sessions.get(sess_id)
end
if session
if script_paths[session.type]
print_status("Session #{sess_id} (#{session.session_host}):")
print_status("Running script #{script} on #{session.type} session" +
" #{sess_id} (#{session.session_host})")
begin
session.execute_file(script_paths[session.type], extra)
rescue ::Exception => e
log_error("Error executing script: #{e.class} #{e}")
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
begin
if script_paths[session.type]
print_status("Session #{sess_id} (#{session.session_host}):")
print_status("Running script #{script} on #{session.type} session" +
" #{sess_id} (#{session.session_host})")
begin
session.execute_file(script_paths[session.type], extra)
rescue ::Exception => e
log_error("Error executing script: #{e.class} #{e}")
end
end
ensure
session.response_timeout = last_known_timeout
end
else
print_error("Invalid session identifier: #{sess_id}")
@ -1790,13 +1837,19 @@ class Core
session_list.each do |sess_id|
session = verify_session(sess_id)
if session
if session.type == 'shell'
session.init_ui(driver.input, driver.output)
session.execute_script('post/multi/manage/shell_to_meterpreter')
session.reset_ui
else
print_error("Session #{sess_id} is not a command shell session, skipping...")
next
last_known_timeout = session.response_timeout
session.response_timeout = response_timeout
begin
if session.type == 'shell'
session.init_ui(driver.input, driver.output)
session.execute_script('post/multi/manage/shell_to_meterpreter')
session.reset_ui
else
print_error("Session #{sess_id} is not a command shell session, skipping...")
next
end
ensure
session.response_timeout = last_known_timeout
end
end