rex 2.0.5 → 2.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rex/exploitation/egghunter.rb +4 -6
- data/lib/rex/exploitation/powershell/psh_methods.rb +9 -0
- data/lib/rex/java/serialization.rb +2 -1
- data/lib/rex/java/serialization/builder.rb +94 -0
- data/lib/rex/java/serialization/model.rb +29 -18
- data/lib/rex/java/serialization/model/annotation.rb +2 -2
- data/lib/rex/java/serialization/model/field.rb +2 -2
- data/lib/rex/java/serialization/model/new_array.rb +8 -3
- data/lib/rex/java/serialization/model/new_class_desc.rb +3 -3
- data/lib/rex/java/serialization/model/new_enum.rb +4 -4
- data/lib/rex/java/serialization/model/new_object.rb +17 -10
- data/lib/rex/ole/direntry.rb +1 -1
- data/lib/rex/ole/samples/create_ole.rb +0 -0
- data/lib/rex/ole/samples/dir.rb +0 -0
- data/lib/rex/ole/samples/dump_stream.rb +0 -0
- data/lib/rex/ole/samples/ole_info.rb +0 -0
- data/lib/rex/parser/foundstone_nokogiri.rb +1 -1
- data/lib/rex/parser/fs/ntfs.rb +252 -0
- data/lib/rex/parser/openvas_nokogiri.rb +2 -0
- data/lib/rex/payloads/win32/kernel.rb +3 -3
- data/lib/rex/post/meterpreter/client_core.rb +172 -64
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +3 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +12 -10
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +64 -37
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +8 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +15 -3
- data/lib/rex/post/meterpreter/packet.rb +41 -38
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +7 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +17 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +11 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +1 -1
- data/lib/rex/proto.rb +2 -0
- data/lib/rex/proto/acpp.rb +17 -0
- data/lib/rex/proto/acpp/client.rb +29 -0
- data/lib/rex/proto/acpp/message.rb +183 -0
- data/lib/rex/proto/http/client.rb +1 -2
- data/lib/rex/proto/iax2/call.rb +22 -3
- data/lib/rex/proto/iax2/client.rb +1 -0
- data/lib/rex/proto/kerberos.rb +13 -0
- data/lib/rex/proto/kerberos/client.rb +213 -0
- data/lib/rex/proto/kerberos/credential_cache.rb +19 -0
- data/lib/rex/proto/kerberos/credential_cache/cache.rb +81 -0
- data/lib/rex/proto/kerberos/credential_cache/credential.rb +151 -0
- data/lib/rex/proto/kerberos/credential_cache/element.rb +49 -0
- data/lib/rex/proto/kerberos/credential_cache/key_block.rb +62 -0
- data/lib/rex/proto/kerberos/credential_cache/principal.rb +70 -0
- data/lib/rex/proto/kerberos/credential_cache/time.rb +69 -0
- data/lib/rex/proto/kerberos/crypto.rb +21 -0
- data/lib/rex/proto/kerberos/crypto/rc4_hmac.rb +65 -0
- data/lib/rex/proto/kerberos/crypto/rsa_md5.rb +15 -0
- data/lib/rex/proto/kerberos/model.rb +133 -0
- data/lib/rex/proto/kerberos/model/ap_req.rb +98 -0
- data/lib/rex/proto/kerberos/model/authenticator.rb +143 -0
- data/lib/rex/proto/kerberos/model/authorization_data.rb +85 -0
- data/lib/rex/proto/kerberos/model/checksum.rb +59 -0
- data/lib/rex/proto/kerberos/model/element.rb +67 -0
- data/lib/rex/proto/kerberos/model/enc_kdc_response.rb +215 -0
- data/lib/rex/proto/kerberos/model/encrypted_data.rb +171 -0
- data/lib/rex/proto/kerberos/model/encryption_key.rb +106 -0
- data/lib/rex/proto/kerberos/model/kdc_request.rb +166 -0
- data/lib/rex/proto/kerberos/model/kdc_request_body.rb +315 -0
- data/lib/rex/proto/kerberos/model/kdc_response.rb +141 -0
- data/lib/rex/proto/kerberos/model/krb_error.rb +219 -0
- data/lib/rex/proto/kerberos/model/last_request.rb +82 -0
- data/lib/rex/proto/kerberos/model/pre_auth_data.rb +104 -0
- data/lib/rex/proto/kerberos/model/pre_auth_enc_time_stamp.rb +126 -0
- data/lib/rex/proto/kerberos/model/pre_auth_pac_request.rb +81 -0
- data/lib/rex/proto/kerberos/model/principal_name.rb +116 -0
- data/lib/rex/proto/kerberos/model/ticket.rb +151 -0
- data/lib/rex/proto/kerberos/pac.rb +36 -0
- data/lib/rex/proto/kerberos/pac/client_info.rb +53 -0
- data/lib/rex/proto/kerberos/pac/element.rb +52 -0
- data/lib/rex/proto/kerberos/pac/logon_info.rb +566 -0
- data/lib/rex/proto/kerberos/pac/priv_svr_checksum.rb +29 -0
- data/lib/rex/proto/kerberos/pac/server_checksum.rb +30 -0
- data/lib/rex/proto/kerberos/pac/type.rb +121 -0
- data/lib/rex/proto/rmi.rb +7 -0
- data/lib/rex/proto/rmi/model.rb +31 -0
- data/lib/rex/proto/rmi/model/call.rb +60 -0
- data/lib/rex/proto/rmi/model/continuation.rb +76 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +62 -0
- data/lib/rex/proto/rmi/model/element.rb +143 -0
- data/lib/rex/proto/rmi/model/output_header.rb +86 -0
- data/lib/rex/proto/rmi/model/ping.rb +41 -0
- data/lib/rex/proto/rmi/model/ping_ack.rb +41 -0
- data/lib/rex/proto/rmi/model/protocol_ack.rb +100 -0
- data/lib/rex/proto/rmi/model/return_data.rb +60 -0
- data/lib/rex/socket.rb +9 -1
- data/lib/rex/socket/tcp_server.rb +3 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +4 -4
- data/lib/rex/ui/text/output/tee.rb +2 -0
- data/lib/rex/zip/samples/comment.rb +0 -0
- data/lib/rex/zip/samples/mkwar.rb +0 -0
- data/lib/rex/zip/samples/mkzip.rb +0 -0
- data/lib/rex/zip/samples/recursive.rb +0 -0
- data/rex.gemspec +1 -1
- metadata +56 -2
@@ -0,0 +1,29 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Kerberos
|
6
|
+
module Pac
|
7
|
+
# This class provides a representation of a PAC_PRIVSVR_CHECKSUM structure, which contains the
|
8
|
+
# checksum using the key of the KDC.
|
9
|
+
class PrivSvrChecksum < Element
|
10
|
+
|
11
|
+
# @!attribute version
|
12
|
+
# @return [Fixnum] The checksum type
|
13
|
+
attr_accessor :checksum
|
14
|
+
|
15
|
+
# Encodes the Rex::Proto::Kerberos::Pac::PacPrivSvrChecksum
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
def encode
|
19
|
+
encoded = ''
|
20
|
+
encoded << [checksum].pack('V')
|
21
|
+
encoded << "\x00" * 16
|
22
|
+
|
23
|
+
encoded
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Kerberos
|
6
|
+
module Pac
|
7
|
+
# This class provides a representation of a PAC_SERVER_CHECKSUM structure, which contains the
|
8
|
+
# checksum using the key of the server.
|
9
|
+
class ServerChecksum < Element
|
10
|
+
|
11
|
+
# @!attribute version
|
12
|
+
# @return [Fixnum] The checksum type
|
13
|
+
attr_accessor :checksum
|
14
|
+
|
15
|
+
# Encodes the Rex::Proto::Kerberos::Pac::ServerChecksum
|
16
|
+
#
|
17
|
+
# @return [String]
|
18
|
+
def encode
|
19
|
+
encoded = ''
|
20
|
+
encoded << [checksum].pack('V')
|
21
|
+
encoded << "\x00" * 16
|
22
|
+
|
23
|
+
encoded
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,121 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Kerberos
|
6
|
+
module Pac
|
7
|
+
# This class provides a representation of a PAC_TYPE structure, the topmost structure
|
8
|
+
# of the PAC.
|
9
|
+
class Type < Element
|
10
|
+
|
11
|
+
# @!attribute buffers
|
12
|
+
# @return [Array<Rex::Proto::Kerberos::Pac::Element>] The array of PAC_INFO_BUFFER structures
|
13
|
+
attr_accessor :buffers
|
14
|
+
# @!attribute checksum
|
15
|
+
# @return [Fixnum] The type of checksum to use when encoding PAC-TYPE
|
16
|
+
attr_accessor :checksum
|
17
|
+
|
18
|
+
# Encodes the Rex::Proto::Kerberos::Pac::Type
|
19
|
+
#
|
20
|
+
# @return [String]
|
21
|
+
def encode
|
22
|
+
offset_one = 0
|
23
|
+
offset_two = 0
|
24
|
+
|
25
|
+
draft = ''
|
26
|
+
draft << encode_buffers_length
|
27
|
+
draft << encode_version
|
28
|
+
draft << encode_pac_info_buffers
|
29
|
+
|
30
|
+
# Encode buffers
|
31
|
+
buffers.each do |buffer|
|
32
|
+
if buffer.class == ServerChecksum
|
33
|
+
offset_one = draft.length + 4
|
34
|
+
elsif buffer.class == PrivSvrChecksum
|
35
|
+
offset_two = draft.length + 4
|
36
|
+
end
|
37
|
+
|
38
|
+
buffer_encoded = buffer.encode
|
39
|
+
draft << buffer_encoded
|
40
|
+
draft << "\x00" * ((buffer_encoded.length + 7) / 8 * 8 - buffer_encoded.length)
|
41
|
+
end
|
42
|
+
|
43
|
+
checksum_draft = make_checksum(draft)
|
44
|
+
double_checksum = make_checksum(checksum_draft)
|
45
|
+
|
46
|
+
encoded = ''
|
47
|
+
encoded << draft[0..(offset_one - 1)]
|
48
|
+
encoded << checksum_draft
|
49
|
+
encoded << draft[(offset_one + checksum_draft.length)..(offset_two - 1)]
|
50
|
+
encoded << double_checksum
|
51
|
+
encoded << draft[(offset_two + double_checksum.length)..(draft.length - 1)]
|
52
|
+
|
53
|
+
encoded
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
# Encodes the number of buffers contained in the PAC
|
59
|
+
#
|
60
|
+
# @return [String]
|
61
|
+
def encode_buffers_length
|
62
|
+
[buffers.length].pack('V')
|
63
|
+
end
|
64
|
+
|
65
|
+
# Encodes the PAC version
|
66
|
+
#
|
67
|
+
# @return [String]
|
68
|
+
def encode_version
|
69
|
+
[VERSION].pack('V')
|
70
|
+
end
|
71
|
+
|
72
|
+
# Encodes the PAC_INFO_BUFFER data
|
73
|
+
#
|
74
|
+
# @return [String]
|
75
|
+
def encode_pac_info_buffers
|
76
|
+
offset = 8 + buffers.length * 16
|
77
|
+
encoded = ''
|
78
|
+
buffers.each do |buffer|
|
79
|
+
case buffer
|
80
|
+
when ClientInfo
|
81
|
+
encoded << [PAC_CLIENT_INFO].pack('V')
|
82
|
+
when LogonInfo
|
83
|
+
encoded << [PAC_LOGON_INFO].pack('V')
|
84
|
+
when PrivSvrChecksum
|
85
|
+
encoded << [PAC_PRIVSVR_CHECKSUM].pack('V')
|
86
|
+
when ServerChecksum
|
87
|
+
encoded << [PAC_SERVER_CHECKSUM].pack('V')
|
88
|
+
end
|
89
|
+
|
90
|
+
buffer_length = buffer.encode.length
|
91
|
+
|
92
|
+
encoded << [buffer_length].pack('V')
|
93
|
+
encoded << [offset].pack('Q<')
|
94
|
+
|
95
|
+
offset = (offset + buffer_length + 7) / 8 * 8
|
96
|
+
end
|
97
|
+
|
98
|
+
encoded
|
99
|
+
end
|
100
|
+
|
101
|
+
# Calculates the checksum for the PAC data
|
102
|
+
#
|
103
|
+
# @param data [String] the data to checksum
|
104
|
+
# @return [String] the checksum result
|
105
|
+
# @raise [NotImplementedError] if checksum schema isn't supported
|
106
|
+
def make_checksum(data)
|
107
|
+
res = ''
|
108
|
+
case checksum
|
109
|
+
when RSA_MD5
|
110
|
+
res = checksum_rsa_md5(data)
|
111
|
+
else
|
112
|
+
raise ::NotImplementedError, 'PAC-TYPE checksum not supported'
|
113
|
+
end
|
114
|
+
|
115
|
+
res
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Rmi
|
6
|
+
module Model
|
7
|
+
SIGNATURE = 'JRMI'
|
8
|
+
STREAM_PROTOCOL = 0x4b
|
9
|
+
SINGLE_OP_PROTOCOL = 0x4c
|
10
|
+
MULTIPLEX_PROTOCOL = 0x4d
|
11
|
+
CALL_MESSAGE = 0x50
|
12
|
+
PING_MESSAGE = 0x52
|
13
|
+
DGC_ACK_MESSAGE = 0x54
|
14
|
+
PROTOCOL_ACK = 0x4e
|
15
|
+
PROTOCOL_NOT_SUPPORTED = 0x4f
|
16
|
+
RETURN_DATA = 0x51
|
17
|
+
PING_ACK = 0x53
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
require 'rex/proto/rmi/model/element'
|
24
|
+
require 'rex/proto/rmi/model/output_header'
|
25
|
+
require 'rex/proto/rmi/model/protocol_ack'
|
26
|
+
require 'rex/proto/rmi/model/continuation'
|
27
|
+
require 'rex/proto/rmi/model/call'
|
28
|
+
require 'rex/proto/rmi/model/return_data'
|
29
|
+
require 'rex/proto/rmi/model/dgc_ack'
|
30
|
+
require 'rex/proto/rmi/model/ping'
|
31
|
+
require 'rex/proto/rmi/model/ping_ack'
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Rmi
|
6
|
+
module Model
|
7
|
+
# This class provides a representation of an RMI call message
|
8
|
+
class Call < Element
|
9
|
+
|
10
|
+
# @!attribute message_id
|
11
|
+
# @return [Fixnum] the message id
|
12
|
+
attr_accessor :message_id
|
13
|
+
# @!attribute call_data
|
14
|
+
# @return [Rex::Java::Serialization::Model::Stream] the serialized call data
|
15
|
+
attr_accessor :call_data
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# Reads the message id from the IO
|
20
|
+
#
|
21
|
+
# @param io [IO] the IO to read from
|
22
|
+
# @return [String]
|
23
|
+
# @raise [RuntimeError] if fails to decode the message id
|
24
|
+
def decode_message_id(io)
|
25
|
+
message_id = read_byte(io)
|
26
|
+
unless message_id == CALL_MESSAGE
|
27
|
+
raise ::RuntimeError, 'Failed to decode Call message id'
|
28
|
+
end
|
29
|
+
|
30
|
+
message_id
|
31
|
+
end
|
32
|
+
|
33
|
+
# Reads and deserializes the call data from the IO
|
34
|
+
#
|
35
|
+
# @param io [IO] the IO to read from
|
36
|
+
# @return [Rex::Java::Serialization::Model::Stream]
|
37
|
+
def decode_call_data(io)
|
38
|
+
call_data = Rex::Java::Serialization::Model::Stream.decode(io)
|
39
|
+
|
40
|
+
call_data
|
41
|
+
end
|
42
|
+
|
43
|
+
# Encodes the message_id field
|
44
|
+
#
|
45
|
+
# @return [String]
|
46
|
+
def encode_message_id
|
47
|
+
[message_id].pack('C')
|
48
|
+
end
|
49
|
+
|
50
|
+
# Encodes the address field
|
51
|
+
#
|
52
|
+
# @return [String]
|
53
|
+
def encode_call_data
|
54
|
+
call_data.encode
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,76 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Rmi
|
6
|
+
module Model
|
7
|
+
# This class provides a representation of an RMI continuation stream
|
8
|
+
class Continuation < Element
|
9
|
+
|
10
|
+
# @!attribute length
|
11
|
+
# @return [Fixnum] the end point address length
|
12
|
+
attr_accessor :length
|
13
|
+
# @!attribute address
|
14
|
+
# @return [String] the end point address
|
15
|
+
attr_accessor :address
|
16
|
+
# @!attribute port
|
17
|
+
# @return [Fixnum] the end point port
|
18
|
+
attr_accessor :port
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
# Reads the end point identifier address length from the IO
|
23
|
+
#
|
24
|
+
# @param io [IO] the IO to read from
|
25
|
+
# @return [Fixnum]
|
26
|
+
def decode_length(io)
|
27
|
+
length = read_short(io)
|
28
|
+
|
29
|
+
length
|
30
|
+
end
|
31
|
+
|
32
|
+
# Reads the end point address from the IO
|
33
|
+
#
|
34
|
+
# @param io [IO] the IO to read from
|
35
|
+
# @return [String]
|
36
|
+
def decode_address(io)
|
37
|
+
version = read_string(io, length)
|
38
|
+
|
39
|
+
version
|
40
|
+
end
|
41
|
+
|
42
|
+
# Reads the end point port from the IO
|
43
|
+
#
|
44
|
+
# @param io [IO] the IO to read from
|
45
|
+
# @return [Fixnum]
|
46
|
+
def decode_port(io)
|
47
|
+
port = read_int(io)
|
48
|
+
|
49
|
+
port
|
50
|
+
end
|
51
|
+
|
52
|
+
# Encodes the length field
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
def encode_length
|
56
|
+
[length].pack('n')
|
57
|
+
end
|
58
|
+
|
59
|
+
# Encodes the address field
|
60
|
+
#
|
61
|
+
# @return [String]
|
62
|
+
def encode_address
|
63
|
+
address
|
64
|
+
end
|
65
|
+
|
66
|
+
# Encodes the port field
|
67
|
+
#
|
68
|
+
# @return [String]
|
69
|
+
def encode_port
|
70
|
+
[port].pack('N')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Rmi
|
6
|
+
module Model
|
7
|
+
# This class provides a representation of an RMI DbgACK stream. It is an acknowledgement
|
8
|
+
# directed to a server's distributed garbage collector that indicates that remote objects
|
9
|
+
# in a return value from a server have been received by the client.
|
10
|
+
class DgcAck < Element
|
11
|
+
|
12
|
+
# @!attribute stream_id
|
13
|
+
# @return [Fixnum] the input stream id
|
14
|
+
attr_accessor :stream_id
|
15
|
+
# @!attribute unique_identifier
|
16
|
+
# @return [String] the unique identifier
|
17
|
+
attr_accessor :unique_identifier
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
# Reads the stream id from the IO
|
22
|
+
#
|
23
|
+
# @param io [IO] the IO to read from
|
24
|
+
# @return [String]
|
25
|
+
# @raise [RuntimeError] if fails to decode stream id
|
26
|
+
def decode_stream_id(io)
|
27
|
+
stream_id = read_byte(io)
|
28
|
+
unless stream_id == DGC_ACK_MESSAGE
|
29
|
+
raise ::RuntimeError, 'Failed to decode DgcAck stream id'
|
30
|
+
end
|
31
|
+
|
32
|
+
stream_id
|
33
|
+
end
|
34
|
+
|
35
|
+
# Reads the unique identifier from the IO
|
36
|
+
#
|
37
|
+
# @param io [IO] the IO to read from
|
38
|
+
# @return [String]
|
39
|
+
def decode_unique_identifier(io)
|
40
|
+
unique_identifier = read_string(io, 14)
|
41
|
+
|
42
|
+
unique_identifier
|
43
|
+
end
|
44
|
+
|
45
|
+
# Encodes the stream_id field
|
46
|
+
#
|
47
|
+
# @return [String]
|
48
|
+
def encode_stream_id
|
49
|
+
[stream_id].pack('C')
|
50
|
+
end
|
51
|
+
|
52
|
+
# Encodes the unique_identifier field
|
53
|
+
#
|
54
|
+
# @return [String]
|
55
|
+
def encode_unique_identifier
|
56
|
+
unique_identifier
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,143 @@
|
|
1
|
+
# -*- coding: binary -*-
|
2
|
+
|
3
|
+
module Rex
|
4
|
+
module Proto
|
5
|
+
module Rmi
|
6
|
+
module Model
|
7
|
+
class Element
|
8
|
+
|
9
|
+
include Rex::Proto::Rmi::Model
|
10
|
+
|
11
|
+
def self.attr_accessor(*vars)
|
12
|
+
@attributes ||= []
|
13
|
+
@attributes.concat vars
|
14
|
+
super(*vars)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Retrieves the element class fields
|
18
|
+
#
|
19
|
+
# @return [Array]
|
20
|
+
def self.attributes
|
21
|
+
@attributes
|
22
|
+
end
|
23
|
+
|
24
|
+
# Creates a Rex::Proto::Rmi::Model::Element with data from the IO.
|
25
|
+
#
|
26
|
+
# @param io [IO] the IO to read data from
|
27
|
+
# @return [Rex::Proto::Rmi::Model::Element]
|
28
|
+
def self.decode(io)
|
29
|
+
elem = self.new
|
30
|
+
elem.decode(io)
|
31
|
+
|
32
|
+
elem
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(options = {})
|
36
|
+
self.class.attributes.each do |attr|
|
37
|
+
if options.has_key?(attr)
|
38
|
+
m = (attr.to_s + '=').to_sym
|
39
|
+
self.send(m, options[attr])
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Retrieves the element instance fields
|
45
|
+
#
|
46
|
+
# @return [Array]
|
47
|
+
def attributes
|
48
|
+
self.class.attributes
|
49
|
+
end
|
50
|
+
|
51
|
+
# Decodes the Rex::Proto::Rmi::Model::Element from the input.
|
52
|
+
#
|
53
|
+
# @raise [NoMethodError]
|
54
|
+
# @return [Rex::Proto::Rmi::Model::Element]
|
55
|
+
def decode(io)
|
56
|
+
self.class.attributes.each do |attr|
|
57
|
+
dec_method = ("decode_#{attr}").to_sym
|
58
|
+
decoded = self.send(dec_method, io)
|
59
|
+
assign_method = (attr.to_s + '=').to_sym
|
60
|
+
self.send(assign_method, decoded)
|
61
|
+
end
|
62
|
+
|
63
|
+
self
|
64
|
+
end
|
65
|
+
|
66
|
+
# Encodes the Rex::Proto::Rmi::Model::Element into an String.
|
67
|
+
#
|
68
|
+
# @raise [NoMethodError]
|
69
|
+
# @return [String]
|
70
|
+
def encode
|
71
|
+
encoded = ''
|
72
|
+
self.class.attributes.each do |attr|
|
73
|
+
m = ("encode_#{attr}").to_sym
|
74
|
+
encoded << self.send(m) if self.send(attr)
|
75
|
+
end
|
76
|
+
|
77
|
+
encoded
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# Reads a byte from an IO
|
83
|
+
#
|
84
|
+
# @param io [IO] the IO to read from
|
85
|
+
# @return [Fixnum]
|
86
|
+
# @raise [RuntimeError] if the byte can't be read from io
|
87
|
+
def read_byte(io)
|
88
|
+
raw = io.read(1)
|
89
|
+
raise ::RuntimeError, 'Failed to read byte' unless raw
|
90
|
+
|
91
|
+
raw.unpack('C')[0]
|
92
|
+
end
|
93
|
+
|
94
|
+
# Reads a two bytes short from an IO
|
95
|
+
#
|
96
|
+
# @param io [IO] the IO to read from
|
97
|
+
# @return [Fixnum]
|
98
|
+
# @raise [RuntimeError] if the short can't be read from io
|
99
|
+
def read_short(io)
|
100
|
+
raw = io.read(2)
|
101
|
+
|
102
|
+
unless raw && raw.length == 2
|
103
|
+
raise ::RuntimeError, 'Failed to read short'
|
104
|
+
end
|
105
|
+
|
106
|
+
raw.unpack('n')[0]
|
107
|
+
end
|
108
|
+
|
109
|
+
# Reads a four bytes int from an IO
|
110
|
+
#
|
111
|
+
# @param io [IO] the IO to read from
|
112
|
+
# @return [Fixnum]
|
113
|
+
# @raise [RuntimeError] if the int can't be read from io
|
114
|
+
def read_int(io)
|
115
|
+
raw = io.read(4)
|
116
|
+
|
117
|
+
unless raw && raw.length == 4
|
118
|
+
raise ::RuntimeError, 'Failed to read short'
|
119
|
+
end
|
120
|
+
|
121
|
+
raw.unpack('N')[0]
|
122
|
+
end
|
123
|
+
|
124
|
+
# Reads an string from an IO
|
125
|
+
#
|
126
|
+
# @param io [IO] the IO to read from
|
127
|
+
# @param length [Fixnum] the string length
|
128
|
+
# @return [String]
|
129
|
+
# @raise [RuntimeError] if the string can't be read from io
|
130
|
+
def read_string(io, length)
|
131
|
+
raw = io.read(length)
|
132
|
+
|
133
|
+
unless raw && raw.length == length
|
134
|
+
raise ::RuntimeError, 'Failed to read string'
|
135
|
+
end
|
136
|
+
|
137
|
+
raw
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|