Land #6707, support for LURI handler
commit
6b3326eab2
|
@ -471,7 +471,7 @@ class ReadableText
|
|||
def self.dump_references(mod, indent = '')
|
||||
output = ''
|
||||
|
||||
if (mod.respond_to? :references and mod.references and mod.references.length > 0)
|
||||
if (mod.respond_to? :references && mod.references && mod.references.length > 0)
|
||||
output << "References:\n"
|
||||
mod.references.each { |ref|
|
||||
output << indent + ref.to_s + "\n"
|
||||
|
@ -530,6 +530,7 @@ class ReadableText
|
|||
columns << 'Id'
|
||||
columns << 'Type'
|
||||
columns << 'Checkin?' if show_extended
|
||||
columns << 'Local URI' if show_extended
|
||||
columns << 'Information'
|
||||
columns << 'Connection'
|
||||
|
||||
|
@ -558,6 +559,12 @@ class ReadableText
|
|||
else
|
||||
row << '?'
|
||||
end
|
||||
|
||||
if session.exploit_datastore.has_key?('LURI') && !session.exploit_datastore['LURI'].empty?
|
||||
row << " (#{session.exploit_datastore['LURI']})"
|
||||
else
|
||||
row << '?'
|
||||
end
|
||||
end
|
||||
|
||||
row << sinfo
|
||||
|
@ -597,6 +604,7 @@ class ReadableText
|
|||
sess_type = session.type.to_s
|
||||
sess_uuid = session.payload_uuid.to_s
|
||||
sess_puid = session.payload_uuid.respond_to?(:puid_hex) ? session.payload_uuid.puid_hex : nil
|
||||
sess_luri = session.exploit_datastore['LURI'] || ""
|
||||
|
||||
sess_checkin = "<none>"
|
||||
sess_machine_id = session.machine_id.to_s
|
||||
|
@ -626,6 +634,9 @@ class ReadableText
|
|||
out << " MachineID: #{sess_machine_id}\n"
|
||||
out << " CheckIn: #{sess_checkin}\n"
|
||||
out << " Registered: #{sess_registration}\n"
|
||||
if !sess_luri.empty?
|
||||
out << " LURI: #{sess_luri}\n"
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
@ -678,6 +689,7 @@ class ReadableText
|
|||
if (verbose)
|
||||
uripath = ctx[0].get_resource if ctx[0].respond_to?(:get_resource)
|
||||
uripath = ctx[0].datastore['URIPATH'] if uripath.nil?
|
||||
uripath = ctx[0].datastore['LURI'] if uripath.nil?
|
||||
row << (uripath || "")
|
||||
row << (framework.jobs[k].start_time || "")
|
||||
end
|
||||
|
|
|
@ -46,7 +46,8 @@ module ReverseHttp
|
|||
register_options(
|
||||
[
|
||||
OptString.new('LHOST', [true, 'The local listener hostname']),
|
||||
OptPort.new('LPORT', [true, 'The local listener port', 8080])
|
||||
OptPort.new('LPORT', [true, 'The local listener port', 8080]),
|
||||
OptString.new('LURI', [false, 'The HTTP Path', ''])
|
||||
], Msf::Handler::ReverseHttp)
|
||||
|
||||
register_advanced_options(
|
||||
|
@ -65,7 +66,8 @@ module ReverseHttp
|
|||
|
||||
def print_prefix
|
||||
if Thread.current[:cli]
|
||||
super + "#{listener_uri} handling request from #{Thread.current[:cli].peerhost}; (UUID: #{uuid.to_s}) "
|
||||
luri = datastore['LURI'].empty? ? "" : "-> (#{datastore['LURI']}) "
|
||||
super + "#{listener_uri} handling request from #{Thread.current[:cli].peerhost}#{luri}; (UUID: #{uuid.to_s}) "
|
||||
else
|
||||
super
|
||||
end
|
||||
|
@ -76,7 +78,7 @@ module ReverseHttp
|
|||
# @return [String] A URI of the form +scheme://host:port/+
|
||||
def listener_uri(addr=datastore['LHOST'])
|
||||
uri_host = Rex::Socket.is_ipv6?(addr) ? "[#{addr}]" : addr
|
||||
"#{scheme}://#{uri_host}:#{bind_port}/"
|
||||
"#{scheme}://#{uri_host}:#{bind_port}#{luri}/"
|
||||
end
|
||||
|
||||
# Return a URI suitable for placing in a payload.
|
||||
|
@ -103,7 +105,7 @@ module ReverseHttp
|
|||
callback_host = "#{callback_name}:#{callback_port}"
|
||||
end
|
||||
|
||||
"#{scheme}://#{callback_host}/"
|
||||
"#{scheme}://#{callback_host}"
|
||||
end
|
||||
|
||||
# Use the {#refname} to determine whether this handler uses SSL or not
|
||||
|
@ -120,6 +122,27 @@ module ReverseHttp
|
|||
(ssl?) ? 'https' : 'http'
|
||||
end
|
||||
|
||||
#
|
||||
# The local URI for the handler.
|
||||
#
|
||||
# @return [String] Representation of the URI to listen on.
|
||||
#
|
||||
def luri
|
||||
l = datastore['LURI'] || ""
|
||||
|
||||
if l && l.length > 0 && l[0] != '/'
|
||||
# make sure the luri has the prefix
|
||||
l = "/#{l}"
|
||||
|
||||
# but not the suffix
|
||||
if l[-1] == '/'
|
||||
l = l[0...-1]
|
||||
end
|
||||
end
|
||||
|
||||
l.dup
|
||||
end
|
||||
|
||||
# Create an HTTP listener
|
||||
#
|
||||
def setup_handler
|
||||
|
@ -158,7 +181,7 @@ module ReverseHttp
|
|||
obj = self
|
||||
|
||||
# Add the new resource
|
||||
service.add_resource("/",
|
||||
service.add_resource(luri + "/",
|
||||
'Proc' => Proc.new { |cli, req|
|
||||
on_request(cli, req, obj)
|
||||
},
|
||||
|
@ -178,7 +201,7 @@ module ReverseHttp
|
|||
#
|
||||
def stop_handler
|
||||
if self.service
|
||||
self.service.remove_resource('/')
|
||||
self.service.remove_resource(luri + "/")
|
||||
if self.service.resources.empty? && self.sessions == 0
|
||||
Rex::ServiceManager.stop_service(self.service)
|
||||
end
|
||||
|
@ -241,12 +264,15 @@ protected
|
|||
uuid.arch ||= obj.arch
|
||||
uuid.platform ||= obj.platform
|
||||
|
||||
conn_id = nil
|
||||
conn_id = luri
|
||||
if info[:mode] && info[:mode] != :connect
|
||||
conn_id = generate_uri_uuid(URI_CHECKSUM_CONN, uuid)
|
||||
conn_id << generate_uri_uuid(URI_CHECKSUM_CONN, uuid)
|
||||
else
|
||||
conn_id << req.relative_resource
|
||||
conn_id = conn_id[0...-1] if conn_id[-1] == '/'
|
||||
end
|
||||
|
||||
request_summary = "#{req.relative_resource} with UA '#{req.headers['User-Agent']}'"
|
||||
request_summary = "#{luri}#{req.relative_resource} with UA '#{req.headers['User-Agent']}'"
|
||||
|
||||
# Validate known UUIDs for all requests if IgnoreUnknownPayloads is set
|
||||
if datastore['IgnoreUnknownPayloads'] && ! framework.uuid_db[uuid.puid_hex]
|
||||
|
@ -281,7 +307,7 @@ protected
|
|||
resp.body = pkt.to_r
|
||||
|
||||
when :init_python
|
||||
print_status("Staging Python payload ...")
|
||||
print_status("Staging Python payload...")
|
||||
url = payload_uri(req) + conn_id + '/'
|
||||
|
||||
blob = ""
|
||||
|
@ -310,7 +336,7 @@ protected
|
|||
})
|
||||
|
||||
when :init_java
|
||||
print_status("Staging Java payload ...")
|
||||
print_status("Staging Java payload...")
|
||||
url = payload_uri(req) + conn_id + "/\x00"
|
||||
|
||||
blob = obj.generate_stage(
|
||||
|
@ -334,7 +360,7 @@ protected
|
|||
})
|
||||
|
||||
when :init_native
|
||||
print_status("Staging Native payload ...")
|
||||
print_status("Staging Native payload...")
|
||||
url = payload_uri(req) + conn_id + "/\x00"
|
||||
uri = URI(payload_uri(req) + conn_id)
|
||||
|
||||
|
@ -370,16 +396,18 @@ protected
|
|||
end
|
||||
|
||||
when :connect
|
||||
print_status("Attaching orphaned/stageless session ...")
|
||||
print_status("Attaching orphaned/stageless session...")
|
||||
|
||||
resp.body = ''
|
||||
conn_id = req.relative_resource
|
||||
|
||||
url = payload_uri(req) + conn_id
|
||||
url << '/' unless url[-1] == '/'
|
||||
|
||||
# Short-circuit the payload's handle_connection processing for create_session
|
||||
create_session(cli, {
|
||||
:passive_dispatcher => obj.service,
|
||||
:conn_id => conn_id,
|
||||
:url => payload_uri(req) + conn_id + "/\x00",
|
||||
:url => url + "\x00",
|
||||
:expiration => datastore['SessionExpirationTimeout'].to_i,
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'].to_i,
|
||||
:retry_total => datastore['SessionRetryTotal'].to_i,
|
||||
|
|
|
@ -48,6 +48,7 @@ module Payload::Python::ReverseHttp
|
|||
|
||||
target_url << ':'
|
||||
target_url << opts[:port].to_s
|
||||
target_url << luri
|
||||
target_url << generate_callback_uri(opts)
|
||||
target_url
|
||||
end
|
||||
|
@ -56,7 +57,7 @@ module Payload::Python::ReverseHttp
|
|||
# Return the longest URI that fits into our available space
|
||||
#
|
||||
def generate_callback_uri(opts={})
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||
|
||||
# Generate the short default URL if we don't have enough space
|
||||
if self.available_space.nil? || required_space > self.available_space
|
||||
|
|
|
@ -50,7 +50,7 @@ module Msf::Payload::TransportConfig
|
|||
unless uri
|
||||
type = opts[:stageless] == true ? :init_connect : :connect
|
||||
sum = uri_checksum_lookup(type)
|
||||
uri = generate_uri_uuid(sum, opts[:uuid])
|
||||
uri = luri + generate_uri_uuid(sum, opts[:uuid])
|
||||
end
|
||||
|
||||
{
|
||||
|
|
|
@ -51,7 +51,7 @@ module Payload::Windows::ReverseHttp
|
|||
|
||||
# Add extra options if we have enough space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:url] = generate_uri
|
||||
conf[:url] = luri + generate_uri
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:ua] = datastore['MeterpreterUserAgent']
|
||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
||||
|
@ -61,7 +61,7 @@ module Payload::Windows::ReverseHttp
|
|||
conf[:proxy_type] = datastore['PayloadProxyType']
|
||||
else
|
||||
# Otherwise default to small URIs
|
||||
conf[:url] = generate_small_uri
|
||||
conf[:url] = luri + generate_small_uri
|
||||
end
|
||||
|
||||
generate_reverse_http(conf)
|
||||
|
@ -98,7 +98,7 @@ module Payload::Windows::ReverseHttp
|
|||
|
||||
# Choose a random URI length between 30 and 255 bytes
|
||||
if uri_req_len == 0
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||
end
|
||||
|
||||
if uri_req_len < 5
|
||||
|
|
|
@ -55,7 +55,7 @@ module Payload::Windows::ReverseHttp_x64
|
|||
|
||||
# add extended options if we do have enough space
|
||||
unless self.available_space.nil? || required_space > self.available_space
|
||||
conf[:url] = generate_uri
|
||||
conf[:url] = luri + generate_uri
|
||||
conf[:exitfunk] = datastore['EXITFUNC']
|
||||
conf[:ua] = datastore['MeterpreterUserAgent']
|
||||
conf[:proxy_host] = datastore['PayloadProxyHost']
|
||||
|
@ -65,7 +65,7 @@ module Payload::Windows::ReverseHttp_x64
|
|||
conf[:proxy_type] = datastore['PayloadProxyType']
|
||||
else
|
||||
# Otherwise default to small URIs
|
||||
conf[:url] = generate_small_uri
|
||||
conf[:url] = luri + generate_small_uri
|
||||
end
|
||||
|
||||
generate_reverse_http(conf)
|
||||
|
@ -96,7 +96,8 @@ module Payload::Windows::ReverseHttp_x64
|
|||
|
||||
# Choose a random URI length between 30 and 255 bytes
|
||||
if uri_req_len == 0
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
|
||||
|
||||
end
|
||||
|
||||
if uri_req_len < 5
|
||||
|
|
|
@ -644,6 +644,16 @@ class ClientCore < Extension
|
|||
scheme = opts[:transport].split('_')[1]
|
||||
url = "#{scheme}://#{opts[:lhost]}:#{opts[:lport]}"
|
||||
|
||||
if opts[:luri] && opts[:luri].length > 0
|
||||
if opts[:luri][0] != '/'
|
||||
url << '/'
|
||||
end
|
||||
url << opts[:luri]
|
||||
if url[-1] == '/'
|
||||
url = url[0...-1]
|
||||
end
|
||||
end
|
||||
|
||||
if opts[:comm_timeout]
|
||||
request.add_tlv(TLV_TYPE_TRANS_COMM_TIMEOUT, opts[:comm_timeout])
|
||||
end
|
||||
|
|
|
@ -575,6 +575,7 @@ class Console::CommandDispatcher::Core
|
|||
'-p' => [ true, 'LPORT parameter' ],
|
||||
'-i' => [ true, 'Specify transport by index (currently supported: remove)' ],
|
||||
'-u' => [ true, 'Custom URI for HTTP/S transports (used when removing transports)' ],
|
||||
'-lu' => [ true, 'Local URI for HTTP/S transports (used when adding/changing transports with a custom LURI)' ],
|
||||
'-ua' => [ true, 'User agent for HTTP/S transports (optional)' ],
|
||||
'-ph' => [ true, 'Proxy host for HTTP/S transports (optional)' ],
|
||||
'-pp' => [ true, 'Proxy port for HTTP/S transports (optional)' ],
|
||||
|
@ -656,6 +657,8 @@ class Console::CommandDispatcher::Core
|
|||
opts[:uri] = val
|
||||
when '-i'
|
||||
transport_index = val.to_i
|
||||
when '-lu'
|
||||
opts[:luri] = val
|
||||
when '-ph'
|
||||
opts[:proxy_host] = val
|
||||
when '-pp'
|
||||
|
|
|
@ -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),
|
||||
http_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),
|
||||
http_url: generate_callback_url(opts),
|
||||
http_user_agent: opts[:user_agent],
|
||||
http_proxy_host: opts[:proxy_host],
|
||||
http_proxy_port: opts[:proxy_port]
|
||||
|
|
|
@ -30,13 +30,13 @@ module MetasploitModule
|
|||
|
||||
def generate_jar(opts={})
|
||||
# Default URL length is 30-256 bytes
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
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
|
||||
|
||||
url = "http://#{datastore["LHOST"]}:#{datastore["LPORT"]}/"
|
||||
url = "http://#{datastore["LHOST"]}:#{datastore["LPORT"]}#{luri}"
|
||||
# TODO: perhaps wire in an existing UUID from opts?
|
||||
url << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ module MetasploitModule
|
|||
uri_req_len = 5
|
||||
end
|
||||
|
||||
url = "https://#{datastore["LHOST"]}:#{datastore["LPORT"]}/"
|
||||
url = "https://#{datastore["LHOST"]}:#{datastore["LPORT"]}#{luri}"
|
||||
# TODO: perhaps wire in an existing UUID from opts?
|
||||
url << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
|
||||
|
|
|
@ -41,7 +41,7 @@ module MetasploitModule
|
|||
|
||||
def config
|
||||
# Default URL length is 30-256 bytes
|
||||
uri_req_len = 30 + rand(256-30)
|
||||
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?
|
||||
|
@ -53,8 +53,8 @@ module MetasploitModule
|
|||
c << "Spawn=#{spawn}\n"
|
||||
c << "URL=http://#{datastore["LHOST"]}"
|
||||
c << ":#{datastore["LPORT"]}" if datastore["LPORT"]
|
||||
c << "/"
|
||||
c << generate_uri_checksum(Rex::Payloads::Meterpreter::UriChecksum::URI_CHECKSUM_INITJ, uri_req_len)
|
||||
c << "#{luri}"
|
||||
c << generate_uri_uuid_mode(:init_java, uri_req_len)
|
||||
c << "\n"
|
||||
|
||||
c
|
||||
|
|
|
@ -57,6 +57,7 @@ module MetasploitModule
|
|||
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"
|
||||
|
||||
|
|
Loading…
Reference in New Issue