CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/modules/auxiliary/scanner/misc/java_rmi_server.rb
Views: 1904
1
##
2
# This module requires Metasploit: https://metasploit.com/download
3
# Current source: https://github.com/rapid7/metasploit-framework
4
##
5
6
require 'rex/java/serialization'
7
8
class MetasploitModule < Msf::Auxiliary
9
include Msf::Exploit::Remote::Java::Rmi::Client
10
include Msf::Auxiliary::Scanner
11
include Msf::Auxiliary::Report
12
13
def initialize
14
super(
15
'Name' => 'Java RMI Server Insecure Endpoint Code Execution Scanner',
16
'Description' => 'Detect Java RMI endpoints',
17
'Author' => ['mihi', 'hdm'],
18
'License' => MSF_LICENSE,
19
'References' =>
20
[
21
# RMI protocol specification
22
[ 'URL', 'http://download.oracle.com/javase/1.3/docs/guide/rmi/spec/rmi-protocol.html'],
23
[ 'URL', 'http://www.securitytracker.com/id?1026215'],
24
[ 'CVE', '2011-3556']
25
],
26
'DisclosureDate' => 'Oct 15 2011'
27
)
28
29
register_options(
30
[
31
Opt::RPORT(1099)
32
])
33
end
34
35
def run_host(target_host)
36
begin
37
connect
38
rescue Rex::ConnectionError
39
return Exploit::CheckCode::Unknown
40
end
41
42
vprint_status("Sending RMI Header...")
43
send_header
44
ack = recv_protocol_ack
45
if ack.nil?
46
print_error("Failed to negotiate RMI protocol")
47
disconnect
48
return Exploit::CheckCode::Unknown
49
end
50
51
# Determine if the instance allows remote class loading
52
vprint_status("Sending RMI Call...")
53
jar = Rex::Text.rand_text_alpha(rand(8)+1) + '.jar'
54
jar_url = "file:RMIClassLoaderSecurityTest/" + jar
55
56
dgc_interface_hash = calculate_interface_hash(
57
[
58
{
59
name: 'clean',
60
descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V',
61
exceptions: ['java.rmi.RemoteException']
62
},
63
{
64
name: 'dirty',
65
descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;',
66
exceptions: ['java.rmi.RemoteException']
67
}
68
]
69
)
70
71
# JDK 1.1 stub protocol
72
# Interface hash: 0xf6b6898d8bf28643 (sun.rmi.transport.DGCImpl_Stub)
73
# Operation: 0 (public void clean(ObjID[] paramArrayOfObjID, long paramLong, VMID paramVMID, boolean paramBoolean))
74
send_call(
75
object_number: 2,
76
uid_number: 0,
77
uid_time: 0,
78
uid_count: 0,
79
operation: 0,
80
hash: dgc_interface_hash,
81
arguments: build_dgc_clean_args(jar_url)
82
)
83
return_value = recv_return
84
85
if return_value.nil?
86
print_good("Failed to send RMI Call, anyway JAVA RMI Endpoint detected")
87
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "")
88
return Exploit::CheckCode::Detected
89
end
90
91
if return_value.is_exception? && loader_enabled?(return_value.value)
92
print_good("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Enabled")
93
svc = report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Enabled")
94
report_vuln(
95
:host => rhost,
96
:service => svc,
97
:name => self.name,
98
:info => "Module #{self.fullname} confirmed remote code execution via this RMI service",
99
:refs => self.references
100
)
101
Exploit::CheckCode::Vulnerable
102
else
103
print_status("#{rhost}:#{rport} Java RMI Endpoint Detected: Class Loader Disabled")
104
report_service(:host => rhost, :port => rport, :name => "java-rmi", :info => "Class Loader: Disabled")
105
Exploit::CheckCode::Safe
106
end
107
end
108
109
def loader_enabled?(exception_stack)
110
exception_stack.each do |exception|
111
if exception.class == Rex::Java::Serialization::Model::NewObject &&
112
exception.class_desc.description.class == Rex::Java::Serialization::Model::NewClassDesc &&
113
exception.class_desc.description.class_name.contents == 'java.lang.ClassNotFoundException'&&
114
[Rex::Java::Serialization::Model::NullReference, Rex::Java::Serialization::Model::Reference].include?(exception.class_data[0].class) &&
115
!exception.class_data[1].contents.include?('RMI class loader disabled')
116
return true
117
end
118
end
119
120
false
121
end
122
123
# class: sun.rmi.trasnport.DGC
124
# method: public void clean(ObjID[] paramArrayOfObjID, long paramLong, VMID paramVMID, boolean paramBoolean)
125
def build_dgc_clean_args(jar_url)
126
arguments = []
127
128
new_array_annotation = Rex::Java::Serialization::Model::Annotation.new
129
new_array_annotation.contents = [
130
Rex::Java::Serialization::Model::NullReference.new,
131
Rex::Java::Serialization::Model::EndBlockData.new
132
]
133
134
new_array_super = Rex::Java::Serialization::Model::ClassDesc.new
135
new_array_super.description = Rex::Java::Serialization::Model::NullReference.new
136
137
new_array_desc = Rex::Java::Serialization::Model::NewClassDesc.new
138
new_array_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, '[Ljava.rmi.server.ObjID;')
139
new_array_desc.serial_version = 0x871300b8d02c647e
140
new_array_desc.flags = 2
141
new_array_desc.fields = []
142
new_array_desc.class_annotation = new_array_annotation
143
new_array_desc.super_class = new_array_super
144
145
array_desc = Rex::Java::Serialization::Model::ClassDesc.new
146
array_desc.description = new_array_desc
147
148
new_array = Rex::Java::Serialization::Model::NewArray.new
149
new_array.type = 'java.rmi.server.ObjID;'
150
new_array.values = []
151
new_array.array_description = array_desc
152
153
# ObjID[] paramArrayOfObjID
154
arguments << new_array
155
156
# long paramLong
157
arguments << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00\x00\x00\x00\x00\x00\x00\x00")
158
159
new_class_desc = Rex::Java::Serialization::Model::NewClassDesc.new
160
new_class_desc.class_name = Rex::Java::Serialization::Model::Utf.new(nil, 'metasploit.RMILoader')
161
new_class_desc.serial_version = 0xa16544ba26f9c2f4
162
new_class_desc.flags = 2
163
new_class_desc.fields = []
164
new_class_desc.class_annotation = Rex::Java::Serialization::Model::Annotation.new
165
new_class_desc.class_annotation.contents = [
166
Rex::Java::Serialization::Model::Utf.new(nil, jar_url),
167
Rex::Java::Serialization::Model::EndBlockData.new
168
]
169
new_class_desc.super_class = Rex::Java::Serialization::Model::ClassDesc.new
170
new_class_desc.super_class.description = Rex::Java::Serialization::Model::NullReference.new
171
172
new_object = Rex::Java::Serialization::Model::NewObject.new
173
new_object.class_desc = Rex::Java::Serialization::Model::ClassDesc.new
174
new_object.class_desc.description = new_class_desc
175
new_object.class_data = []
176
177
# VMID paramVMID
178
arguments << new_object
179
180
# boolean paramBoolean
181
arguments << Rex::Java::Serialization::Model::BlockData.new(nil, "\x00")
182
183
arguments
184
end
185
end
186
187