Skip to content

Commit 03740df

Browse files
committed
Support serialization
1 parent 785006b commit 03740df

File tree

6 files changed

+87
-6
lines changed

6 files changed

+87
-6
lines changed

lib/rex/java/serialization/model/class_desc.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ def decode(io)
3737
# @raise [RuntimeError] if serialization doesn't succeed
3838
def encode
3939
encoded = ''
40-
allowed_contents = [NullReference, NewClassDesc]
40+
allowed_contents = [NullReference, NewClassDesc, Reference]
4141

4242
unless allowed_contents.include?(description.class)
4343
raise ::RuntimeError, 'Failed to serialize ClassDesc'

lib/rex/java/serialization/model/contents.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ def encode_content(content)
8989
encoded << [TC_NULL].pack('C')
9090
when Rex::Java::Serialization::Model::Reset
9191
encoded << [TC_RESET].pack('C')
92+
when Rex::Java::Serialization::Model::Reference
93+
encoded << [TC_REFERENCE].pack('C')
9294
else
9395
raise ::RuntimeError, 'Failed to serialize content'
9496
end

lib/rex/java/serialization/model/field.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ def is_valid?(code)
122122
#
123123
# @return [String]
124124
def encode_field_type
125-
unless field_type.class == Java::Serialization::Model::Utf
125+
allowed_contents = [Utf, Reference]
126+
127+
unless allowed_contents.include?(field_type.class)
126128
raise ::RuntimeError, 'Failed to serialize Field'
127129
end
128130

@@ -137,9 +139,10 @@ def encode_field_type
137139
# @return [Java::Serialization::Model::Utf]
138140
# @raise [RuntimeError] if unserialization doesn't succeed
139141
def decode_field_type(io)
142+
allowed_contents = [Utf, Reference]
140143
type = decode_content(io, stream)
141144

142-
unless type.class == Rex::Java::Serialization::Model::Utf || type.class == Rex::Java::Serialization::Model::Reference
145+
unless allowed_contents.include?(type.class)
143146
raise ::RuntimeError, 'Failed to unserialize Field field_type'
144147
end
145148

lib/rex/java/serialization/model/new_object.rb

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,11 @@ def encode
5252
encoded << class_desc.encode
5353

5454
class_data.each do |value|
55-
encoded << encode_value(value)
55+
if value.class == Array
56+
encoded << encode_value(value)
57+
else
58+
encoded << encode_content(value)
59+
end
5660
end
5761

5862
encoded
@@ -91,7 +95,8 @@ def decode_class_fields(io, my_class_desc)
9195
if field.is_primitive?
9296
values << decode_value(io, field.type)
9397
else
94-
values << decode_content(io, stream)
98+
content = decode_content(io, stream)
99+
values << content
95100
end
96101
end
97102

lib/rex/java/serialization/model/reference.rb

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ class Reference < Element
88

99
def initialize(stream = nil)
1010
super(stream)
11-
handler = 0
11+
self.handler = 0
1212
end
1313

1414
def decode(io)
@@ -21,6 +21,17 @@ def decode(io)
2121

2222
self
2323
end
24+
25+
def encode
26+
if handler < BASE_WIRE_HANDLE
27+
raise ::RuntimeError, 'Failed to serialize Reference'
28+
end
29+
30+
encoded = ''
31+
encoded << [handler].pack('N')
32+
33+
encoded
34+
end
2435
end
2536
end
2637
end

spec/lib/rex/java/serialization/model/stream_spec.rb

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,39 @@
2424
end
2525
let(:char_array_stream_io) { StringIO.new(char_array_stream) }
2626

27+
let(:complex_stream) do
28+
"\xac\xed\x00\x05\x77\x22\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00" +
29+
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01" +
30+
"\xf6\xb6\x89\x8d\x8b\xf2\x86\x43\x75\x72\x00\x18\x5b\x4c\x6a\x61" +
31+
"\x76\x61\x2e\x72\x6d\x69\x2e\x73\x65\x72\x76\x65\x72\x2e\x4f\x62" +
32+
"\x6a\x49\x44\x3b\x87\x13\x00\xb8\xd0\x2c\x64\x7e\x02\x00\x00\x70" +
33+
"\x78\x70\x00\x00\x00\x01\x73\x72\x00\x15\x6a\x61\x76\x61\x2e\x72" +
34+
"\x6d\x69\x2e\x73\x65\x72\x76\x65\x72\x2e\x4f\x62\x6a\x49\x44\xa7" +
35+
"\x5e\xfa\x12\x8d\xdc\xe5\x5c\x02\x00\x02\x4a\x00\x06\x6f\x62\x6a" +
36+
"\x4e\x75\x6d\x4c\x00\x05\x73\x70\x61\x63\x65\x74\x00\x15\x4c\x6a" +
37+
"\x61\x76\x61\x2f\x72\x6d\x69\x2f\x73\x65\x72\x76\x65\x72\x2f\x55" +
38+
"\x49\x44\x3b\x70\x78\x70\x0d\xc1\x1e\x2a\x94\x5e\x2f\xb2\x73\x72" +
39+
"\x00\x13\x6a\x61\x76\x61\x2e\x72\x6d\x69\x2e\x73\x65\x72\x76\x65" +
40+
"\x72\x2e\x55\x49\x44\x0f\x12\x70\x0d\xbf\x36\x4f\x12\x02\x00\x03" +
41+
"\x53\x00\x05\x63\x6f\x75\x6e\x74\x4a\x00\x04\x74\x69\x6d\x65\x49" +
42+
"\x00\x06\x75\x6e\x69\x71\x75\x65\x70\x78\x70\x80\x16\x00\x00\x01" +
43+
"\x49\xb5\xe4\x92\x78\xd2\x4f\xdf\x47\x77\x08\x80\x00\x00\x00\x00" +
44+
"\x00\x00\x01\x73\x72\x00\x12\x6a\x61\x76\x61\x2e\x72\x6d\x69\x2e" +
45+
"\x64\x67\x63\x2e\x4c\x65\x61\x73\x65\xb0\xb5\xe2\x66\x0c\x4a\xdc" +
46+
"\x34\x02\x00\x02\x4a\x00\x05\x76\x61\x6c\x75\x65\x4c\x00\x04\x76" +
47+
"\x6d\x69\x64\x74\x00\x13\x4c\x6a\x61\x76\x61\x2f\x72\x6d\x69\x2f" +
48+
"\x64\x67\x63\x2f\x56\x4d\x49\x44\x3b\x70\x78\x70\x00\x00\x00\x00" +
49+
"\x00\x09\x27\xc0\x73\x72\x00\x11\x6a\x61\x76\x61\x2e\x72\x6d\x69" +
50+
"\x2e\x64\x67\x63\x2e\x56\x4d\x49\x44\xf8\x86\x5b\xaf\xa4\xa5\x6d" +
51+
"\xb6\x02\x00\x02\x5b\x00\x04\x61\x64\x64\x72\x74\x00\x02\x5b\x42" +
52+
"\x4c\x00\x03\x75\x69\x64\x71\x00\x7e\x00\x03\x70\x78\x70\x75\x72" +
53+
"\x00\x02\x5b\x42\xac\xf3\x17\xf8\x06\x08\x54\xe0\x02\x00\x00\x70" +
54+
"\x78\x70\x00\x00\x00\x08\x6b\x02\xc7\x72\x60\x1c\xc7\x95\x73\x71" +
55+
"\x00\x7e\x00\x05\x80\x01\x00\x00\x01\x49\xb5\xf8\x00\xea\xe9\x62" +
56+
"\xc1\xc0"
57+
end
58+
let(:complex_stream_io) { StringIO.new(complex_stream) }
59+
2760
describe ".new" do
2861
it "Rex::Java::Serialization::Model::Stream" do
2962
expect(stream).to be_a(Rex::Java::Serialization::Model::Stream)
@@ -36,6 +69,10 @@
3669
it "initializes version with java serialized stream default version " do
3770
expect(stream.version).to eq(Rex::Java::Serialization::STREAM_VERSION)
3871
end
72+
73+
it "initializes stream to nil by default" do
74+
expect(stream.stream).to be_nil
75+
end
3976
end
4077

4178
describe "#decode" do
@@ -70,6 +107,22 @@
70107
expect(stream.contents[0]).to be_an(Rex::Java::Serialization::Model::NewArray)
71108
end
72109
end
110+
111+
context "when deserializing a complex stream with references" do
112+
it "deserializes an Stream" do
113+
expect(stream.decode(complex_stream_io)).to be_a(Rex::Java::Serialization::Model::Stream)
114+
end
115+
116+
it "deserializes all the contents in the Stream" do
117+
stream.decode(complex_stream_io)
118+
expect(stream.contents.length).to eq(4)
119+
end
120+
121+
it "deserializes object contents" do
122+
stream.decode(complex_stream_io)
123+
expect(stream.contents[3]).to be_a(Rex::Java::Serialization::Model::NewObject)
124+
end
125+
end
73126
end
74127

75128
describe "#encode" do
@@ -119,6 +172,13 @@
119172
expect(stream.encode.unpack("C*")).to eq(char_array_stream.unpack("C*"))
120173
end
121174
end
175+
176+
context "when reserializing a complex stream" do
177+
it "reserializes the original stream" do
178+
stream.decode(complex_stream_io)
179+
expect(stream.encode.unpack("C*")).to eq(complex_stream.unpack("C*"))
180+
end
181+
end
122182
end
123183

124184
end

0 commit comments

Comments
 (0)