Land #12217, f5_bigip_cookie_disclosure module now stores the cookie in noteswq

This commit is contained in:
h00die 2022-01-08 07:03:35 -05:00
commit 7b11429b49
No known key found for this signature in database
GPG Key ID: F46E181E9B48B6CF
2 changed files with 131 additions and 46 deletions

View File

@ -0,0 +1,61 @@
## Vulnerable Application
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.
## Verification Steps
1. Start `msfconsole`
1. Do: `use auxiliary/gather/f5_bigip_cookie_disclosure`
1. Do: `set RHOSTS www.example.com`
1. Do: `run`
## Options
### REQUESTS
The number of requests to send. Default value is `10`.
## Scenarios
### F5 BIP-IP load balancing cookie not found
```
msf5 > use auxiliary/gather/f5_bigip_cookie_disclosure
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) > set RHOSTS www.example.com
RHOSTS => www.example.com
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) > run
[*] Running module against 93.184.216.34
[*] Starting request /
[-] F5 BIG-IP load balancing cookie not found
[*] Auxiliary module execution completed
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) >
```
### F5 BIP-IP load balancing cookie found
```
msf5 > use auxiliary/gather/f5_bigip_cookie_disclosure
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) > set RHOSTS vulnerable-target.com
RHOSTS => vulnerable-target.com
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) > run
[*] Running module against 1.1.1.1
[*] Starting request /
[+] F5 BIG-IP load balancing cookie "BIGipServer~DMZ~EXAMPLE~vulnarable-target-443_pool = 1214841098.47873.0000" found
[+] Load balancing pool name "~DMZ~EXAMPLE~vulnarable-target-443_pool" found
[+] Backend 10.1.105.72:443 found
[*] Auxiliary module execution completed
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) > notes
Notes
=====
Time Host Service Port Protocol Type Data
---- ---- ------- ---- -------- ---- ----
2019-08-20 21:21:02 UTC 1.1.1.1 f5_load_balancer_cookie_name "BIGipServer~DMZ~EXAMPLE~vulnarable-target-443_pool"
2019-08-20 21:21:02 UTC 1.1.1.1 f5_load_balancer_pool_name "~DMZ~EXAMPLE~vulnarable-target-443_pool"
2019-08-20 21:21:02 UTC 1.1.1.1 f5_load_balancer_backends [{:host=>"10.1.105.72", :port=>443}]
msf5 auxiliary(gather/f5_bigip_cookie_disclosure) >
```

View File

@ -8,69 +8,77 @@ class MetasploitModule < Msf::Auxiliary
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'F5 BigIP Backend Cookie Disclosure',
super(
update_info(
info,
'Name' => 'F5 BIG-IP Backend Cookie Disclosure',
'Description' => %q{
This module identifies F5 BigIP load balancers and leaks backend
information (pool name, backend's IP address and port, routed domain)
through cookies inserted by the BigIP system.
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' =>
[
'Author' => [
'Thanat0s <thanspam[at]trollprod.org>',
'Oleg Broslavsky <ovbroslavsky[at]gmail.com>',
'Nikita Oleksov <neoleksov[at]gmail.com>',
'Denis Kolegov <dnkolegov[at]gmail.com>'
'Denis Kolegov <dnkolegov[at]gmail.com>',
'Paul-Emmanuel Raoul <skyper@skyplabs.net>'
],
'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']
'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' =>
{
'DefaultOptions' => {
'SSL' => true
},
'Notes' => {
'Stability' => [CRASH_SAFE],
'Reliability' => [],
'SideEffects' => []
}
))
)
)
register_options(
[
OptInt.new('RPORT', [true, 'The BigIP service port to listen on', 443]),
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
conversion = [value].pack('V').unpack('N').first
elsif size == 2
conversion = [value].pack("v").unpack("n").first
conversion = [value].pack('v').unpack('n').first
end
conversion
end
def cookie_decode(cookie_value)
backend = {}
case
when cookie_value =~ /(\d{8,10})\.(\d{1,5})\./
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)
when cookie_value.downcase =~ /rd\d+o0{20}f{4}([a-f0-9]{8})o(\d{1,5})/
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)
when cookie_value.downcase =~ /vi([a-f0-9]{32})\.(\d{1,5})/
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)
when cookie_value.downcase =~ /rd\d+o([a-f0-9]{32})o(\d{1,5})/
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)
@ -84,9 +92,10 @@ class MetasploitModule < Msf::Auxiliary
backend
end
def get_cookie # request a page and extract a F5 looking cookie.
def fetch_cookie
# Request a page and extract a F5 looking cookie
cookie = {}
res = send_request_raw({ 'method' => 'GET', 'uri' => @uri })
res = send_request_raw('method' => 'GET', 'uri' => @uri)
unless res.nil?
# Get the SLB session IDs for all cases:
@ -96,15 +105,15 @@ class MetasploitModule < Msf::Auxiliary
# 4. IPv6 pool members in non-default route domains - "BIGipServerWEB=rd3o20010112000000000000000000000030o80"
regexp = /
([~_\.\-\w\d]+)=(((?:\d+\.){2}\d+)|
([~.\-\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]
cookie[:id] = m.nil? ? nil : m[1]
cookie[:value] = m.nil? ? nil : m[2]
end
cookie
end
@ -112,25 +121,31 @@ class MetasploitModule < Msf::Auxiliary
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 = get_cookie # Get the cookie
cookie = fetch_cookie # Get the cookie
# If the cookie is not found, stop process
if cookie.empty? || cookie[:id].nil?
print_error("F5 BigIP load balancing cookie not found")
return
print_error('F5 BIG-IP load balancing cookie not found')
return nil
end
# Print the cookie name on the first request
if i == 1
print_good("F5 BigIP load balancing cookie \"#{cookie[:id]} = #{cookie[:value]}\" found")
cookie_name = cookie[:id]
print_good("F5 BIG-IP load balancing cookie \"#{cookie_name} = #{cookie[:value]}\" found")
if cookie[:id].start_with?('BIGipServer')
print_good("Load balancing pool name \"#{cookie[:id].split('BIGipServer')[1]}\" found")
pool_name = cookie[:id].split('BIGipServer')[1]
print_good("Load balancing pool name \"#{pool_name}\" found")
end
if cookie[:value].start_with?('rd')
print_good("Route domain \"#{cookie[:value].split('rd')[1].split('o')[0]}\" found")
route_domain = cookie[:value].split('rd')[1].split('o')[0]
print_good("Route domain \"#{route_domain}\" found")
end
end
@ -141,16 +156,25 @@ class MetasploitModule < Msf::Auxiliary
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
print_error("Network connection error")
rescue ::Rex::ConnectionError
print_error("Network connection error")
rescue ::Rex::ConnectionRefused, ::Rex::ConnectionError
print_error('Network connection error')
rescue ::OpenSSL::SSL::SSLError
print_error("SSL/TLS connection error")
print_error('SSL/TLS connection error')
end
end