metasploit-framework/modules/auxiliary/gather/f5_bigip_cookie_disclosure.rb

126 lines
3.2 KiB
Ruby
Raw Normal View History

2014-04-14 23:11:17 +00:00
##
# This module requires Metasploit: http://metasploit.com/download
2014-04-14 23:11:17 +00:00
# Current source: https://github.com/rapid7/metasploit-framework
##
require 'msf/core'
class Metasploit3 < Msf::Auxiliary
include Msf::Auxiliary::Report
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
2014-04-30 14:31:07 +00:00
'Name' => 'F5 BigIP Backend Cookie Disclosure',
2014-04-14 23:11:17 +00:00
'Description' => %q{
This module identifies F5 BigIP load balancers and leaks backend
information through cookies inserted by the BigIP devices.
2014-04-14 23:11:17 +00:00
},
2014-04-28 09:32:46 +00:00
'Author' => [ 'Thanat0s <thanspam[at]trollprod.org>' ],
2014-04-15 00:48:55 +00:00
'References' =>
[
['URL', 'http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html'],
['URL', 'http://support.f5.com/kb/en-us/solutions/public/7000/700/sol7784.html?sr=14607726']
],
2014-04-14 23:11:17 +00:00
'License' => MSF_LICENSE
))
register_options(
[
OptString.new('TARGETURI', [true, 'The URI path to test', '/']),
2014-04-30 14:31:07 +00:00
OptInt.new('REQUESTS', [true, 'Number of requests to send to disclose back', 10])
2014-04-14 23:11:17 +00:00
], self.class)
end
2014-04-30 14:31:07 +00:00
def change_endianness(value, size=4)
conversion = value
if size == 4
conversion = [value].pack("V").unpack("N").first
elsif size == 2
conversion = [value].pack("v").unpack("n").first
end
conversion
end
2014-04-14 23:11:17 +00:00
def cookie_decode(cookie_value)
2014-04-30 14:31:07 +00:00
back_end = ""
if cookie_value =~ /(\d{8})\.(\d{5})\./
host = $1.to_i
port = $2.to_i
host = change_endianness(host)
host = Rex::Socket.addr_itoa(host)
port = change_endianness(port, 2)
back_end = "#{host}:#{port}"
2014-04-28 21:33:01 +00:00
end
2014-04-30 14:31:07 +00:00
back_end
2014-04-14 23:11:17 +00:00
end
2014-04-28 09:32:46 +00:00
def get_cookie # request a page and extract a F5 looking cookie.
2014-04-30 14:31:07 +00:00
cookie = {}
2014-04-14 23:11:17 +00:00
res = send_request_raw({
'method' => 'GET',
'uri' => @uri
})
2014-04-30 14:31:07 +00:00
unless res.nil?
# Get the SLB session ID, like "TestCookie=2263487148.3013.0000"
m = res.get_cookies.match(/([\-\w\d]+)=((?:\d+\.){2}\d+)(?:$|,|;|\s)/)
unless m.nil?
cookie[:id] = (m.nil?) ? nil : m[1]
cookie[:value] = (m.nil?) ? nil : m[2]
end
2014-04-14 23:11:17 +00:00
end
2014-04-30 14:31:07 +00:00
cookie
2014-04-14 23:11:17 +00:00
end
def run
2014-04-30 14:31:07 +00:00
unless datastore['REQUESTS'] > 0
print_error("Please, configure more than 0 REQUESTS")
return
end
back_ends = []
@uri = normalize_uri(target_uri.path.to_s)
print_status("#{peer} - Starting request #{@uri}")
for i in 0...datastore['REQUESTS']
cookie = get_cookie() # Get the cookie
2014-04-28 21:26:29 +00:00
# If the cookie is not found, stop process
2014-04-30 14:31:07 +00:00
if cookie.empty? || cookie[:id].nil?
print_error("#{peer} - F5 Server load balancing cookie not found")
2014-04-30 14:31:07 +00:00
break
2014-04-28 21:26:29 +00:00
end
2014-04-30 14:31:07 +00:00
2014-04-28 21:26:29 +00:00
# Print the cookie name on the first request
if i == 0
print_status("#{peer} - F5 Server load balancing cookie \"#{cookie[:id]}\" found")
2014-04-28 21:26:29 +00:00
end
2014-04-30 14:31:07 +00:00
back_end = cookie_decode(cookie[:value])
unless back_ends.include?(back_end)
print_status("#{peer} - Backend #{back_end} found")
back_ends.push(back_end)
2014-04-14 23:11:17 +00:00
end
end
2014-04-30 14:31:07 +00:00
2014-04-28 21:26:29 +00:00
# Reporting found backends in database
2014-04-30 14:31:07 +00:00
unless back_ends.empty?
report_note(
:host => rhost,
:type => "f5_load_balancer_backends",
:data => back_ends
)
end
2014-04-14 23:11:17 +00:00
end
end