Skip to content

Commit 0540e25

Browse files
committed
Calculate the java/rmi/registry/RegistryImpl_Stub hash dinamically
1 parent a5c39db commit 0540e25

File tree

6 files changed

+68
-25
lines changed

6 files changed

+68
-25
lines changed

lib/msf/java/rmi/client/registry.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,44 @@ def send_registry_list(opts = {})
8484

8585
names
8686
end
87+
88+
# Calculates the hash to make RMI calls for the
89+
# java/rmi/registry/RegistryImpl_Stub interface
90+
#
91+
# @return [Fixnum] The interface's hash
92+
def registry_interface_hash
93+
hash = calculate_interface_hash(
94+
[
95+
{
96+
name: 'bind',
97+
descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V',
98+
exceptions: ['java.rmi.AccessException', 'java.rmi.AlreadyBoundException', 'java.rmi.RemoteException']
99+
},
100+
{
101+
name: 'list',
102+
descriptor: '()[Ljava/lang/String;',
103+
exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException']
104+
},
105+
{
106+
name: 'lookup',
107+
descriptor: '(Ljava/lang/String;)Ljava/rmi/Remote;',
108+
exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException']
109+
},
110+
{
111+
name: 'rebind',
112+
descriptor: '(Ljava/lang/String;Ljava/rmi/Remote;)V',
113+
exceptions: ['java.rmi.AccessException', 'java.rmi.RemoteException']
114+
},
115+
{
116+
name: 'unbind',
117+
descriptor: '(Ljava/lang/String;)V',
118+
exceptions: ['java.rmi.AccessException', 'java.rmi.NotBoundException', 'java.rmi.RemoteException']
119+
}
120+
]
121+
)
122+
123+
hash
124+
end
87125
end
88126
end
89127
end

lib/msf/java/rmi/client/registry/builder.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ def build_registry_lookup(opts = {})
2727
uid_time: uid_time,
2828
uid_count: uid_count,
2929
operation: 2, # java.rmi.Remote lookup(java.lang.String)
30-
hash: 0x44154dc9d4e63bdf, # RegistryImpl_Stub
30+
hash: registry_interface_hash,
3131
arguments: [Rex::Java::Serialization::Model::Utf.new(nil, name)]
3232
)
3333

@@ -52,7 +52,7 @@ def build_registry_list(opts = {})
5252
uid_time: uid_time,
5353
uid_count: uid_count,
5454
operation: 1, # java.lang.String list()[]
55-
hash: 0x44154dc9d4e63bdf, # RegistryImpl_Stub
55+
hash: registry_interface_hash,
5656
arguments: []
5757
)
5858

lib/msf/java/rmi/util.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def calculate_method_hash(signature)
2525
# @param exceptions [Array] set of declared exceptions
2626
# @return [Fixnum] The interface hash
2727
# @see http://docs.oracle.com/javase/8/docs/platform/rmi/spec/rmi-stubs24.html The RemoteRef Interface documentation to understand how interface hashes are calculated
28-
def calculate_interface_hash(methods, exceptions)
28+
def calculate_interface_hash(methods)
2929
stream = ''
3030
stream << [1].pack('N') # stub version number
3131

@@ -34,7 +34,7 @@ def calculate_interface_hash(methods, exceptions)
3434
utf_descriptor = Rex::Java::Serialization::Model::Utf.new(nil, m[:descriptor])
3535
stream << utf_method.encode
3636
stream << utf_descriptor.encode
37-
exceptions.each do |e|
37+
m[:exceptions].each do |e|
3838
utf_exception = Rex::Java::Serialization::Model::Utf.new(nil, e)
3939
stream << utf_exception.encode
4040
end

modules/auxiliary/scanner/misc/java_rmi_server.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,10 +53,17 @@ def run_host(target_host)
5353

5454
dgc_interface_hash = calculate_interface_hash(
5555
[
56-
{name: 'clean', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V'},
57-
{name: 'dirty', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;'}
58-
],
59-
['java.rmi.RemoteException']
56+
{
57+
name: 'clean',
58+
descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V',
59+
exceptions: ['java.rmi.RemoteException']
60+
},
61+
{
62+
name: 'dirty',
63+
descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;',
64+
exceptions: ['java.rmi.RemoteException']
65+
}
66+
]
6067
)
6168

6269
# JDK 1.1 stub protocol

spec/lib/msf/java/rmi/client/registry_spec.rb

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,5 +227,11 @@
227227
end
228228
end
229229
end
230+
231+
describe "#registry_interface_hash" do
232+
it "calculates the hash for the java/rmi/registry/RegistryImpl_Stub correctly" do
233+
expect(mod.registry_interface_hash).to eq(4905912898345647071)
234+
end
235+
end
230236
end
231237

spec/lib/msf/java/rmi/util_spec.rb

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,18 +12,14 @@
1212
mod
1313
end
1414

15-
let(:interface_methods) do
15+
let(:example_interface) do
1616
[
17-
{name: 'sayHello', descriptor: '()Ljava/lang/String;'},
18-
{name: 'sayHelloTwo', descriptor: '(Ljava/lang/String;)Ljava/lang/String;'}
17+
{name: 'sayHello', descriptor: '()Ljava/lang/String;', exceptions: ['java.rmi.RemoteException']},
18+
{name: 'sayHelloTwo', descriptor: '(Ljava/lang/String;)Ljava/lang/String;', exceptions: ['java.rmi.RemoteException']}
1919
]
2020
end
2121

22-
let(:interface_exceptions) do
23-
['java.rmi.RemoteException']
24-
end
25-
26-
let(:interface_hash) do
22+
let(:example_hash) do
2723
0x3e664fcbd9e953bb
2824
end
2925

@@ -35,17 +31,13 @@
3531
0x53e0822d3e3724df
3632
end
3733

38-
let(:dgc_methods) do
34+
let(:dgc_interface) do
3935
[
40-
{name: 'clean', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V'},
41-
{name: 'dirty', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;'}
36+
{name: 'clean', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/VMID;Z)V', exceptions: ['java.rmi.RemoteException']},
37+
{name: 'dirty', descriptor: '([Ljava/rmi/server/ObjID;JLjava/rmi/dgc/Lease;)Ljava/rmi/dgc/Lease;', exceptions: ['java.rmi.RemoteException']}
4238
]
4339
end
4440

45-
let(:dgc_exceptions) do
46-
['java.rmi.RemoteException']
47-
end
48-
4941
let(:dgc_hash) do
5042
0xf6b6898d8bf28643
5143
end
@@ -83,13 +75,13 @@
8375
describe "#calculate_interface_hash" do
8476
context "when an example interface is provided" do
8577
it "generates a correct interface hash" do
86-
expect(mod.calculate_interface_hash(interface_methods, interface_exceptions)).to eq(interface_hash)
78+
expect(mod.calculate_interface_hash(example_interface)).to eq(example_hash)
8779
end
8880
end
8981

9082
context "when a DGC interface is provided" do
9183
it "generates a correct interface hash" do
92-
expect(mod.calculate_interface_hash(dgc_methods, dgc_exceptions)).to eq(dgc_hash)
84+
expect(mod.calculate_interface_hash(dgc_interface)).to eq(dgc_hash)
9385
end
9486
end
9587
end

0 commit comments

Comments
 (0)