Fix LURI support for stageless, transport add/change and code tidies

bug/bundler_fix
OJ 2016-01-25 21:53:21 +10:00 committed by Brent Cook
parent 63e478c826
commit b95267997d
9 changed files with 57 additions and 23 deletions

View File

@ -78,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}" + datastore['LURI'] || "/"
"#{scheme}://#{uri_host}:#{bind_port}#{luri}/"
end
# Return a URI suitable for placing in a payload.
@ -105,7 +105,7 @@ module ReverseHttp
callback_host = "#{callback_name}:#{callback_port}"
end
"#{scheme}://#{callback_host}" + datastore['LURI']
"#{scheme}://#{callback_host}#{luri}/"
end
# Use the {#refname} to determine whether this handler uses SSL or not
@ -122,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
end
# Create an HTTP listener
#
def setup_handler
@ -160,7 +181,7 @@ module ReverseHttp
obj = self
# Add the new resource
service.add_resource((datastore['LURI'] || "") + "/",
service.add_resource(luri + "/",
'Proc' => Proc.new { |cli, req|
on_request(cli, req, obj)
},
@ -180,7 +201,7 @@ module ReverseHttp
#
def stop_handler
if self.service
self.service.remove_resource((datastore['LURI'] || "") + "/")
self.service.remove_resource(luri + "/")
if self.service.resources.empty? && self.sessions == 0
Rex::ServiceManager.stop_service(self.service)
end
@ -267,13 +288,15 @@ protected
self.pending_connections += 1
unless luri.empty?
sep = conn_id && conn_id[0] == '/' ? '' : '/'
conn_id = "#{luri}#{sep}#{conn_id}"
end
# Process the requested resource.
case info[:mode]
when :init_connect
print_status("Redirecting stageless connection from #{request_summary}")
if datastore['LURI'] != "/"
conn_id = (datastore['LURI']) + conn_id
end
# Handle the case where stageless payloads call in on the same URI when they
# first connect. From there, we tell them to callback on a connect URI that
@ -288,7 +311,6 @@ protected
when :init_python
print_status("Staging Python payload...")
url = payload_uri(req) + conn_id + '/'
conn_id = (datastore['LURI']) + conn_id
blob = ""
blob << obj.generate_stage(
@ -318,7 +340,6 @@ protected
when :init_java
print_status("Staging Java payload...")
url = payload_uri(req) + conn_id + "/\x00"
conn_id = (datastore['LURI']) + conn_id
blob = obj.generate_stage(
uuid: uuid,
@ -344,7 +365,6 @@ protected
print_status("Staging Native payload...")
url = payload_uri(req) + conn_id + "/\x00"
uri = URI(payload_uri(req) + conn_id)
conn_id = (datastore['LURI']) + conn_id
resp['Content-Type'] = 'application/octet-stream'
@ -381,8 +401,9 @@ protected
print_status("Attaching orphaned/stageless session...")
resp.body = ''
conn_id = req.relative_resource
conn_id = (datastore['LURI']) + conn_id
unless conn_id
conn_id = "#{luri}#{req.relative_resource}"
end
# Short-circuit the payload's handle_connection processing for create_session
create_session(cli, {

View File

@ -48,7 +48,7 @@ module Payload::Python::ReverseHttp
target_url << ':'
target_url << opts[:port].to_s
target_url << datastore['LURI']
target_url << luri
target_url << generate_callback_uri(opts)
target_url
end
@ -57,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 + datastore['LURI'].length + rand(256-(30+datastore['LURI'].length))
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

View File

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

View File

@ -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] = datastore['LURI'] + 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 + datastore['LURI'].length + rand(256-(30+datastore['LURI'].length))
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
end
if uri_req_len < 5

View File

@ -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] = datastore['LURI'] + 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,7 @@ module Payload::Windows::ReverseHttp_x64
# Choose a random URI length between 30 and 255 bytes
if uri_req_len == 0
uri_req_len = 30 + datastore['LURI'].length + rand(256-(30+datastore['LURI'].length))
uri_req_len = 30 + luri.length + rand(256 - (30 + luri.length))
end

View File

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

View File

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

View File

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

View File

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