|
3 | 3 | require 'metasploit/framework/hashes/identify' |
4 | 4 |
|
5 | 5 | module Msf |
6 | | -### |
7 | | -# |
8 | | -# This module provides methods for working with Juniper equipment |
9 | | -# |
10 | | -### |
| 6 | + ### |
| 7 | + # |
| 8 | + # This module provides methods for working with Juniper equipment |
| 9 | + # |
| 10 | + ### |
11 | 11 | module Auxiliary::Juniper |
12 | 12 | include Msf::Auxiliary::Report |
13 | 13 |
|
@@ -145,118 +145,117 @@ def juniper_screenos_config_eater(thost, tport, config) |
145 | 145 | end |
146 | 146 |
|
147 | 147 | def juniper_junos_config_eater(thost, tport, config) |
148 | | - report_host({ |
149 | | - host: thost, |
| 148 | + report_host({ |
| 149 | + host: thost, |
150 | 150 | os_name: 'Juniper JunOS' |
151 | | - }) |
152 | | - |
| 151 | + }) |
153 | 152 |
|
154 | | - if framework.db.active |
155 | | - credential_data = { |
156 | | - address: thost, |
157 | | - port: tport, |
158 | | - protocol: 'tcp', |
159 | | - workspace_id: myworkspace_id, |
160 | | - origin_type: :service, |
161 | | - private_type: :nonreplayable_hash, |
162 | | - service_name: '', |
163 | | - module_fullname: fullname, |
164 | | - status: Metasploit::Model::Login::Status::UNTRIED |
165 | | - } |
166 | | - end |
| 153 | + if framework.db.active |
| 154 | + credential_data = { |
| 155 | + address: thost, |
| 156 | + port: tport, |
| 157 | + protocol: 'tcp', |
| 158 | + workspace_id: myworkspace_id, |
| 159 | + origin_type: :service, |
| 160 | + private_type: :nonreplayable_hash, |
| 161 | + service_name: '', |
| 162 | + module_fullname: fullname, |
| 163 | + status: Metasploit::Model::Login::Status::UNTRIED |
| 164 | + } |
| 165 | + end |
167 | 166 |
|
168 | | - store_loot('juniper.junos.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper JunOS Configuration') |
| 167 | + store_loot('juniper.junos.config', 'text/plain', thost, config.strip, 'config.txt', 'Juniper JunOS Configuration') |
169 | 168 |
|
170 | 169 | # we'll take out the pretty format so its easier to regex |
171 | | - config = config.split("\n").join('') |
| 170 | + config = config.split("\n").join('') |
172 | 171 |
|
173 | 172 | # Example: |
174 | 173 | # system { |
175 | 174 | # root-authentication { |
176 | 175 | # encrypted-password "$1$pz9b1.fq$foo5r85Ql8mXdoRUe0C1E."; ## SECRET-DATA |
177 | 176 | # } |
178 | 177 | # } |
179 | | - if /root-authentication\s+\{\s+encrypted-password "(?<root_hash>[^"]+)";/i =~ config |
180 | | - root_hash = root_hash.strip |
181 | | - jtr_format = identify_hash root_hash |
182 | | - |
183 | | - print_good("root password hash: #{root_hash}") |
184 | | - if framework.db.active |
185 | | - cred = credential_data.dup |
186 | | - cred[:username] = 'root' |
187 | | - cred[:jtr_format] = jtr_format |
188 | | - cred[:private_data] = root_hash |
189 | | - create_credential_and_login(cred) |
190 | | - end |
191 | | - end |
| 178 | + if /root-authentication\s+\{\s+encrypted-password "(?<root_hash>[^"]+)";/i =~ config |
| 179 | + root_hash = root_hash.strip |
| 180 | + jtr_format = identify_hash root_hash |
| 181 | + |
| 182 | + print_good("root password hash: #{root_hash}") |
| 183 | + if framework.db.active |
| 184 | + cred = credential_data.dup |
| 185 | + cred[:username] = 'root' |
| 186 | + cred[:jtr_format] = jtr_format |
| 187 | + cred[:private_data] = root_hash |
| 188 | + create_credential_and_login(cred) |
| 189 | + end |
| 190 | + end |
192 | 191 |
|
193 | 192 | # access privileges https://kb.juniper.net/InfoCenter/index?page=content&id=KB10902 |
194 | | - config.scan(/user (?<user_name>[^\s]+) {\s+ uid (?<user_uid>\d+);\s+ class (?<user_permission>super-user|operator|read-only|unauthorized);\s+ authentication {\s+encrypted-password "(?<user_hash>[^\s]+)";/i).each do |result| |
195 | | - user_name = result[0].strip |
196 | | - user_uid = result[1].strip |
197 | | - user_permission = result[2].strip |
198 | | - user_hash = result[3].strip |
199 | | - jtr_format = identify_hash user_hash |
| 193 | + config.scan(/user (?<user_name>[^\s]+) {(\s+ full-name (?<fullname>[^;]+);)?\s+ uid (?<user_uid>\d+);\s+ class (?<user_permission>super-user|operator|read-only|unauthorized|[^;]+);\s+ authentication {\s+encrypted-password "(?<user_hash>[^\s]+)";/i).each do |result| |
| 194 | + user_name = result[0].strip |
| 195 | + user_uid = result[2].strip |
| 196 | + user_permission = result[3].strip |
| 197 | + user_hash = result[4].strip |
| 198 | + jtr_format = identify_hash user_hash |
200 | 199 |
|
201 | | - print_good("User #{user_uid} named #{user_name} in group #{user_permission} found with password hash #{user_hash}.") |
202 | | - next unless framework.db.active |
| 200 | + print_good("User #{user_uid} named #{user_name} in group #{user_permission} found with password hash #{user_hash}.") |
| 201 | + next unless framework.db.active |
203 | 202 |
|
204 | | - cred = credential_data.dup |
205 | | - cred[:username] = user_name |
206 | | - cred[:jtr_format] = jtr_format |
207 | | - cred[:private_data] = user_hash |
208 | | - create_credential_and_login(cred) |
209 | | - end |
| 203 | + cred = credential_data.dup |
| 204 | + cred[:username] = user_name |
| 205 | + cred[:jtr_format] = jtr_format |
| 206 | + cred[:private_data] = user_hash |
| 207 | + create_credential_and_login(cred) |
| 208 | + end |
210 | 209 |
|
211 | 210 | # https://supportf5.com/csp/article/K6449 special characters allowed in snmp community strings |
212 | | - config.scan(%r{community "?(?<snmp_community>[\w\d\s().*/-:_?=@,&%$]+)"? {(\s+view [\w\-]+;)?\s+authorization read-(?<snmp_permission>only|write)}i).each do |result| |
213 | | - snmp_community = result[0].strip |
214 | | - snmp_permissions = result[1].strip |
215 | | - print_good("SNMP community #{snmp_community} with permissions read-#{snmp_permissions}") |
216 | | - next unless framework.db.active |
| 211 | + config.scan(%r{community "?(?<snmp_community>[\w\d\s().*/-:_?=@,&%$+!]+)"? \{(\s+view [\w\-]+;)?\s+authorization read-(?<snmp_permission>only|write)}i).each do |result| |
| 212 | + snmp_community = result[0].strip |
| 213 | + snmp_permissions = result[1].strip |
| 214 | + print_good("SNMP community #{snmp_community} with permissions read-#{snmp_permissions}") |
| 215 | + next unless framework.db.active |
217 | 216 |
|
218 | | - cred = credential_data.dup |
219 | | - if snmp_permissions.downcase == 'write' |
220 | | - cred[:access_level] = 'RW' |
221 | | - else |
222 | | - cred[:access_level] = 'RO' |
223 | | - end |
224 | | - cred[:protocol] = 'udp' |
225 | | - cred[:port] = 161 |
226 | | - cred[:private_data] = snmp_community |
227 | | - cred[:private_type] = :password |
228 | | - cred[:service_name] = 'snmp' |
229 | | - create_credential_and_login(cred) |
230 | | - end |
| 217 | + cred = credential_data.dup |
| 218 | + if snmp_permissions.downcase == 'write' |
| 219 | + cred[:access_level] = 'RW' |
| 220 | + else |
| 221 | + cred[:access_level] = 'RO' |
| 222 | + end |
| 223 | + cred[:protocol] = 'udp' |
| 224 | + cred[:port] = 161 |
| 225 | + cred[:private_data] = snmp_community |
| 226 | + cred[:private_type] = :password |
| 227 | + cred[:service_name] = 'snmp' |
| 228 | + create_credential_and_login(cred) |
| 229 | + end |
231 | 230 |
|
232 | | - config.scan(/radius-server \{\s+(?<radius_server>[0-9.]{7,15}) secret "(?<radius_hash>[^"]+)";/i).each do |result| |
233 | | - radius_hash = result[1].strip |
234 | | - radius_server = result[0].strip |
235 | | - print_good("radius server #{radius_server} password hash: #{radius_hash}") |
236 | | - next unless framework.db.active |
| 231 | + config.scan(/radius-server \{\s+(?<radius_server>[0-9.]{7,15}) secret "(?<radius_hash>[^"]+)";/i).each do |result| |
| 232 | + radius_hash = result[1].strip |
| 233 | + radius_server = result[0].strip |
| 234 | + print_good("radius server #{radius_server} password hash: #{radius_hash}") |
| 235 | + next unless framework.db.active |
237 | 236 |
|
238 | | - cred = credential_data.dup |
239 | | - cred[:address] = radius_server |
240 | | - cred[:port] = 1812 |
241 | | - cred[:protocol] = 'udp' |
242 | | - cred[:private_data] = radius_hash |
243 | | - cred[:service_name] = 'radius' |
244 | | - create_credential_and_login(cred) |
245 | | - end |
| 237 | + cred = credential_data.dup |
| 238 | + cred[:address] = radius_server |
| 239 | + cred[:port] = 1812 |
| 240 | + cred[:protocol] = 'udp' |
| 241 | + cred[:private_data] = radius_hash |
| 242 | + cred[:service_name] = 'radius' |
| 243 | + create_credential_and_login(cred) |
| 244 | + end |
246 | 245 |
|
247 | | - config.scan(/pap {\s+local-name "(?<ppp_username>.+)";\s+local-password "(?<ppp_hash>[^"]+)";/i).each do |result| |
248 | | - ppp_username = result[0].strip |
249 | | - ppp_hash = result[1].strip |
250 | | - print_good("PPTP username #{ppp_username} hash #{ppp_hash} via PAP") |
251 | | - next unless framework.db.active |
| 246 | + config.scan(/pap {\s+local-name "(?<ppp_username>.+)";\s+local-password "(?<ppp_hash>[^"]+)";/i).each do |result| |
| 247 | + ppp_username = result[0].strip |
| 248 | + ppp_hash = result[1].strip |
| 249 | + print_good("PPTP username #{ppp_username} hash #{ppp_hash} via PAP") |
| 250 | + next unless framework.db.active |
252 | 251 |
|
253 | | - cred = credential_data.dup |
254 | | - cred[:username] = ppp_username |
255 | | - cred[:private_data] = ppp_hash |
256 | | - cred[:service_name] = 'pptp' |
257 | | - cred[:port] = 1723 |
258 | | - create_credential_and_login(cred) |
259 | | - end |
| 252 | + cred = credential_data.dup |
| 253 | + cred[:username] = ppp_username |
| 254 | + cred[:private_data] = ppp_hash |
| 255 | + cred[:service_name] = 'pptp' |
| 256 | + cred[:port] = 1723 |
| 257 | + create_credential_and_login(cred) |
| 258 | + end |
260 | 259 | end |
261 | 260 | end |
262 | 261 | end |
0 commit comments