rex 2.0.8 → 2.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/rex.rb +1 -0
- data/lib/rex/arch.rb +5 -0
- data/lib/rex/arch/x86.rb +19 -5
- data/lib/rex/arch/zarch.rb +17 -0
- data/lib/rex/compat.rb +5 -4
- data/lib/rex/constants.rb +3 -1
- data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
- data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
- data/lib/rex/exploitation/cmdstager.rb +1 -0
- data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
- data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
- data/lib/rex/exploitation/egghunter.rb +1 -1
- data/lib/rex/google/geolocation.rb +68 -0
- data/lib/rex/io/bidirectional_pipe.rb +0 -4
- data/lib/rex/java/serialization.rb +2 -0
- data/lib/rex/java/serialization/decode_error.rb +11 -0
- data/lib/rex/java/serialization/encode_error.rb +11 -0
- data/lib/rex/java/serialization/model.rb +2 -0
- data/lib/rex/java/serialization/model/annotation.rb +3 -3
- data/lib/rex/java/serialization/model/block_data.rb +3 -3
- data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
- data/lib/rex/java/serialization/model/class_desc.rb +6 -6
- data/lib/rex/java/serialization/model/contents.rb +17 -10
- data/lib/rex/java/serialization/model/field.rb +12 -11
- data/lib/rex/java/serialization/model/long_utf.rb +3 -3
- data/lib/rex/java/serialization/model/new_array.rb +22 -23
- data/lib/rex/java/serialization/model/new_class.rb +57 -0
- data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
- data/lib/rex/java/serialization/model/new_enum.rb +5 -5
- data/lib/rex/java/serialization/model/new_object.rb +22 -17
- data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
- data/lib/rex/java/serialization/model/reference.rb +4 -4
- data/lib/rex/java/serialization/model/stream.rb +7 -7
- data/lib/rex/java/serialization/model/utf.rb +3 -3
- data/lib/rex/json_hash_file.rb +94 -0
- data/lib/rex/logging/log_sink.rb +1 -0
- data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
- data/lib/rex/parser/appscan_nokogiri.rb +13 -23
- data/lib/rex/parser/fs/ntfs.rb +10 -5
- data/lib/rex/parser/nmap_nokogiri.rb +3 -1
- data/lib/rex/parser/openvas_nokogiri.rb +70 -73
- data/lib/rex/parser/winscp.rb +108 -0
- data/lib/rex/parser/x509_certificate.rb +92 -0
- data/lib/rex/payloads.rb +0 -1
- data/lib/rex/payloads/meterpreter/config.rb +154 -0
- data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
- data/lib/rex/post/meterpreter.rb +1 -1
- data/lib/rex/post/meterpreter/client.rb +26 -3
- data/lib/rex/post/meterpreter/client_core.rb +387 -75
- data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
- data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
- data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
- data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
- data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
- data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
- data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
- data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
- data/lib/rex/post/meterpreter/packet.rb +29 -0
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
- data/lib/rex/post/meterpreter/ui/console.rb +1 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
- data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
- data/lib/rex/powershell.rb +62 -0
- data/lib/rex/powershell/command.rb +359 -0
- data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
- data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
- data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
- data/lib/rex/powershell/parser.rb +182 -0
- data/lib/rex/powershell/payload.rb +78 -0
- data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
- data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
- data/lib/rex/proto/dcerpc/client.rb +6 -6
- data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
- data/lib/rex/proto/http/client.rb +3 -3
- data/lib/rex/proto/http/client_request.rb +0 -5
- data/lib/rex/proto/http/response.rb +86 -0
- data/lib/rex/proto/ipmi/utils.rb +30 -26
- data/lib/rex/proto/kerberos/client.rb +1 -1
- data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
- data/lib/rex/proto/rfb/client.rb +8 -3
- data/lib/rex/proto/rfb/constants.rb +1 -1
- data/lib/rex/proto/rmi.rb +2 -0
- data/lib/rex/proto/rmi/decode_error.rb +10 -0
- data/lib/rex/proto/rmi/exception.rb +10 -0
- data/lib/rex/proto/rmi/model.rb +5 -0
- data/lib/rex/proto/rmi/model/call.rb +4 -4
- data/lib/rex/proto/rmi/model/call_data.rb +137 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/element.rb +26 -11
- data/lib/rex/proto/rmi/model/output_header.rb +4 -4
- data/lib/rex/proto/rmi/model/ping.rb +2 -2
- data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
- data/lib/rex/proto/rmi/model/return_data.rb +5 -5
- data/lib/rex/proto/rmi/model/return_value.rb +124 -0
- data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
- data/lib/rex/proto/steam.rb +3 -0
- data/lib/rex/proto/steam/message.rb +125 -0
- data/lib/rex/proto/tftp/client.rb +35 -14
- data/lib/rex/random_identifier_generator.rb +2 -0
- data/lib/rex/ropbuilder.rb +1 -1
- data/lib/rex/socket/parameters.rb +9 -0
- data/lib/rex/socket/ssl_tcp.rb +25 -41
- data/lib/rex/socket/ssl_tcp_server.rb +10 -21
- data/lib/rex/sslscan/result.rb +20 -1
- data/lib/rex/text.rb +241 -55
- data/lib/rex/ui/output.rb +0 -3
- data/lib/rex/ui/subscriber.rb +0 -10
- data/lib/rex/ui/text/color.rb +9 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
- data/lib/rex/ui/text/output.rb +15 -4
- data/lib/rex/ui/text/output/file.rb +1 -0
- data/lib/rex/ui/text/output/stdio.rb +0 -16
- data/lib/rex/ui/text/shell.rb +3 -0
- data/lib/rex/ui/text/table.rb +85 -19
- data/lib/rex/user_agent.rb +118 -0
- data/rex.gemspec +2 -2
- metadata +41 -14
- data/lib/rex/exploitation/powershell.rb +0 -62
- data/lib/rex/exploitation/powershell/parser.rb +0 -183
- data/lib/rex/payloads/meterpreter.rb +0 -2
- data/lib/rex/payloads/meterpreter/patch.rb +0 -136
|
@@ -22,11 +22,11 @@ module Rex
|
|
|
22
22
|
#
|
|
23
23
|
# @param io [IO] the IO to read from
|
|
24
24
|
# @return [String]
|
|
25
|
-
# @raise [
|
|
25
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode stream id
|
|
26
26
|
def decode_stream_id(io)
|
|
27
27
|
stream_id = read_byte(io)
|
|
28
28
|
unless stream_id == DGC_ACK_MESSAGE
|
|
29
|
-
raise ::
|
|
29
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode DgcAck stream id'
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
stream_id
|
|
@@ -83,42 +83,57 @@ module Rex
|
|
|
83
83
|
#
|
|
84
84
|
# @param io [IO] the IO to read from
|
|
85
85
|
# @return [Fixnum]
|
|
86
|
-
# @raise [
|
|
86
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if the byte can't be read from io
|
|
87
87
|
def read_byte(io)
|
|
88
88
|
raw = io.read(1)
|
|
89
|
-
raise ::
|
|
89
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to read byte' unless raw
|
|
90
90
|
|
|
91
|
-
raw.unpack('
|
|
91
|
+
raw.unpack('c')[0]
|
|
92
92
|
end
|
|
93
93
|
|
|
94
94
|
# Reads a two bytes short from an IO
|
|
95
95
|
#
|
|
96
96
|
# @param io [IO] the IO to read from
|
|
97
97
|
# @return [Fixnum]
|
|
98
|
-
# @raise [
|
|
98
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if the short can't be read from io
|
|
99
99
|
def read_short(io)
|
|
100
100
|
raw = io.read(2)
|
|
101
101
|
|
|
102
102
|
unless raw && raw.length == 2
|
|
103
|
-
raise ::
|
|
103
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to read short'
|
|
104
104
|
end
|
|
105
105
|
|
|
106
|
-
raw.unpack('
|
|
106
|
+
raw.unpack('s>')[0]
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# Reads a four bytes int from an IO
|
|
110
110
|
#
|
|
111
111
|
# @param io [IO] the IO to read from
|
|
112
112
|
# @return [Fixnum]
|
|
113
|
-
# @raise [
|
|
113
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if the int can't be read from io
|
|
114
114
|
def read_int(io)
|
|
115
115
|
raw = io.read(4)
|
|
116
116
|
|
|
117
117
|
unless raw && raw.length == 4
|
|
118
|
-
raise ::
|
|
118
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to read int'
|
|
119
119
|
end
|
|
120
120
|
|
|
121
|
-
raw.unpack('
|
|
121
|
+
raw.unpack('l>')[0]
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# Reads a 8 bytes long from an IO
|
|
125
|
+
#
|
|
126
|
+
# @param io [IO] the IO to read from
|
|
127
|
+
# @return [Fixnum]
|
|
128
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if the long can't be read from io
|
|
129
|
+
def read_long(io)
|
|
130
|
+
raw = io.read(8)
|
|
131
|
+
|
|
132
|
+
unless raw && raw.length == 8
|
|
133
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to read long'
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
raw.unpack('q>')[0]
|
|
122
137
|
end
|
|
123
138
|
|
|
124
139
|
# Reads an string from an IO
|
|
@@ -126,12 +141,12 @@ module Rex
|
|
|
126
141
|
# @param io [IO] the IO to read from
|
|
127
142
|
# @param length [Fixnum] the string length
|
|
128
143
|
# @return [String]
|
|
129
|
-
# @raise [
|
|
144
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if the string can't be read from io
|
|
130
145
|
def read_string(io, length)
|
|
131
146
|
raw = io.read(length)
|
|
132
147
|
|
|
133
148
|
unless raw && raw.length == length
|
|
134
|
-
raise ::
|
|
149
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to read string'
|
|
135
150
|
end
|
|
136
151
|
|
|
137
152
|
raw
|
|
@@ -23,11 +23,11 @@ module Rex
|
|
|
23
23
|
#
|
|
24
24
|
# @param io [IO] the IO to read from
|
|
25
25
|
# @return [String]
|
|
26
|
-
# @raise [
|
|
26
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode signature
|
|
27
27
|
def decode_signature(io)
|
|
28
28
|
signature = read_string(io, 4)
|
|
29
29
|
unless signature == SIGNATURE
|
|
30
|
-
raise ::
|
|
30
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode OutputHeader signature'
|
|
31
31
|
end
|
|
32
32
|
|
|
33
33
|
signature
|
|
@@ -47,13 +47,13 @@ module Rex
|
|
|
47
47
|
#
|
|
48
48
|
# @param io [IO] the IO to read from
|
|
49
49
|
# @return [Fixnum]
|
|
50
|
-
# @raise [
|
|
50
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode the protocol
|
|
51
51
|
def decode_protocol(io)
|
|
52
52
|
valid_protocols = [STREAM_PROTOCOL, SINGLE_OP_PROTOCOL, MULTIPLEX_PROTOCOL]
|
|
53
53
|
protocol = read_byte(io)
|
|
54
54
|
|
|
55
55
|
unless valid_protocols.include?(protocol)
|
|
56
|
-
raise ::
|
|
56
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode OutputHeader protocol'
|
|
57
57
|
end
|
|
58
58
|
|
|
59
59
|
protocol
|
|
@@ -18,11 +18,11 @@ module Rex
|
|
|
18
18
|
#
|
|
19
19
|
# @param io [IO] the IO to read from
|
|
20
20
|
# @return [String]
|
|
21
|
-
# @raise [
|
|
21
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode stream id
|
|
22
22
|
def decode_stream_id(io)
|
|
23
23
|
stream_id = read_byte(io)
|
|
24
24
|
unless stream_id == PING_MESSAGE
|
|
25
|
-
raise ::
|
|
25
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode Ping stream id'
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
stream_id
|
|
@@ -18,11 +18,11 @@ module Rex
|
|
|
18
18
|
#
|
|
19
19
|
# @param io [IO] the IO to read from
|
|
20
20
|
# @return [String]
|
|
21
|
-
# @raise [
|
|
21
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode stream id
|
|
22
22
|
def decode_stream_id(io)
|
|
23
23
|
stream_id = read_byte(io)
|
|
24
24
|
unless stream_id == PING_ACK
|
|
25
|
-
raise ::
|
|
25
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode PingAck stream id'
|
|
26
26
|
end
|
|
27
27
|
|
|
28
28
|
stream_id
|
|
@@ -26,11 +26,11 @@ module Rex
|
|
|
26
26
|
#
|
|
27
27
|
# @param io [IO] the IO to read from
|
|
28
28
|
# @return [String]
|
|
29
|
-
# @raise [
|
|
29
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode stream id
|
|
30
30
|
def decode_stream_id(io)
|
|
31
31
|
stream_id = read_byte(io)
|
|
32
32
|
unless stream_id == PROTOCOL_ACK
|
|
33
|
-
raise ::
|
|
33
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode ProtocolAck stream id'
|
|
34
34
|
end
|
|
35
35
|
|
|
36
36
|
stream_id
|
|
@@ -11,7 +11,7 @@ module Rex
|
|
|
11
11
|
# @return [Fixnum] the stream id
|
|
12
12
|
attr_accessor :stream_id
|
|
13
13
|
# @!attribute return value
|
|
14
|
-
# @return [Rex::
|
|
14
|
+
# @return [Rex::Proto::Rmi::Model::ReturnValue] the return value
|
|
15
15
|
attr_accessor :return_value
|
|
16
16
|
|
|
17
17
|
private
|
|
@@ -20,11 +20,11 @@ module Rex
|
|
|
20
20
|
#
|
|
21
21
|
# @param io [IO] the IO to read from
|
|
22
22
|
# @return [String]
|
|
23
|
-
# @raise [
|
|
23
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode the stream id
|
|
24
24
|
def decode_stream_id(io)
|
|
25
25
|
stream_id = read_byte(io)
|
|
26
26
|
unless stream_id == RETURN_DATA
|
|
27
|
-
raise ::
|
|
27
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode ReturnData stream id'
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
stream_id
|
|
@@ -33,9 +33,9 @@ module Rex
|
|
|
33
33
|
# Reads and deserializes the return value from the IO
|
|
34
34
|
#
|
|
35
35
|
# @param io [IO] the IO to read from
|
|
36
|
-
# @return [Rex::
|
|
36
|
+
# @return [Rex::Proto::Rmi::Model::ReturnValue]
|
|
37
37
|
def decode_return_value(io)
|
|
38
|
-
return_value = Rex::
|
|
38
|
+
return_value = Rex::Proto::Rmi::Model::ReturnValue.decode(io)
|
|
39
39
|
|
|
40
40
|
return_value
|
|
41
41
|
end
|
|
@@ -0,0 +1,124 @@
|
|
|
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 return value
|
|
8
|
+
class ReturnValue < Element
|
|
9
|
+
|
|
10
|
+
# @!attribute code
|
|
11
|
+
# @return [Fixnum] the return code
|
|
12
|
+
attr_accessor :code
|
|
13
|
+
# @!attribute uid
|
|
14
|
+
# @return [Rex::Proto::Rmi::Model::UniqueIdentifier] unique identifier of the returned value
|
|
15
|
+
attr_accessor :uid
|
|
16
|
+
# @!attribute value
|
|
17
|
+
# @return [Array] the returned exception or value according to code
|
|
18
|
+
attr_accessor :value
|
|
19
|
+
|
|
20
|
+
# Encodes the Rex::Proto::Rmi::Model::ReturnValue into an String.
|
|
21
|
+
#
|
|
22
|
+
# @return [String]
|
|
23
|
+
def encode
|
|
24
|
+
stream = Rex::Java::Serialization::Model::Stream.new
|
|
25
|
+
block_data = Rex::Java::Serialization::Model::BlockData.new(nil, encode_code + encode_uid)
|
|
26
|
+
|
|
27
|
+
stream.contents << block_data
|
|
28
|
+
value.each do |v|
|
|
29
|
+
stream.contents << v
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
stream.encode
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Decodes the Rex::Proto::Rmi::Model::ReturnValue from the input.
|
|
36
|
+
#
|
|
37
|
+
# @param io [IO] the IO to read from
|
|
38
|
+
# @return [Rex::Proto::Rmi::Model::ReturnValue]
|
|
39
|
+
def decode(io)
|
|
40
|
+
stream = Rex::Java::Serialization::Model::Stream.decode(io)
|
|
41
|
+
|
|
42
|
+
block_data = stream.contents[0]
|
|
43
|
+
block_data_io = StringIO.new(block_data.contents, 'rb')
|
|
44
|
+
|
|
45
|
+
self.code = decode_code(block_data_io)
|
|
46
|
+
self.uid = decode_uid(block_data_io)
|
|
47
|
+
self.value = []
|
|
48
|
+
|
|
49
|
+
stream.contents[1..stream.contents.length - 1].each do |content|
|
|
50
|
+
self.value << content
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
self
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Answers if the ReturnValue is an exception
|
|
57
|
+
#
|
|
58
|
+
# @return [Boolean]
|
|
59
|
+
def is_exception?
|
|
60
|
+
code == RETURN_EXCEPTION
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# The object/exception class of the returned value
|
|
64
|
+
#
|
|
65
|
+
# @return [String, NilClass] the returned value class, nil it cannot be retrieved
|
|
66
|
+
def get_class_name
|
|
67
|
+
unless value[0] && value[0].is_a?(Rex::Java::Serialization::Model::NewObject)
|
|
68
|
+
return nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
case value[0].class_desc.description
|
|
72
|
+
when Rex::Java::Serialization::Model::NewClassDesc
|
|
73
|
+
return value[0].class_desc.description.class_name.contents
|
|
74
|
+
when Rex::Java::Serialization::Model::ProxyClassDesc
|
|
75
|
+
return value[0].class_desc.description.interfaces[0].contents
|
|
76
|
+
else
|
|
77
|
+
return nil
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
private
|
|
82
|
+
|
|
83
|
+
# Reads the return code from the IO
|
|
84
|
+
#
|
|
85
|
+
# @param io [IO] the IO to read from
|
|
86
|
+
# @return [String]
|
|
87
|
+
# @raise [Rex::Proto::Rmi::DecodeError] if fails to decode the return code
|
|
88
|
+
def decode_code(io)
|
|
89
|
+
code = read_byte(io)
|
|
90
|
+
unless code == RETURN_VALUE || code == RETURN_EXCEPTION
|
|
91
|
+
raise Rex::Proto::Rmi::DecodeError, 'Failed to decode the ReturnValue code'
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
code
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Reads and deserializes the uid from the IO
|
|
98
|
+
#
|
|
99
|
+
# @param io [IO] the IO to read from
|
|
100
|
+
# @return [Rex::Proto::Rmi::Model::UniqueIdentifier]
|
|
101
|
+
def decode_uid(io)
|
|
102
|
+
uid = Rex::Proto::Rmi::Model::UniqueIdentifier.decode(io)
|
|
103
|
+
|
|
104
|
+
uid
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
# Encodes the code field
|
|
108
|
+
#
|
|
109
|
+
# @return [String]
|
|
110
|
+
def encode_code
|
|
111
|
+
[code].pack('c')
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# Encodes the uid field
|
|
115
|
+
#
|
|
116
|
+
# @return [String]
|
|
117
|
+
def encode_uid
|
|
118
|
+
uid.encode
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
|
|
3
|
+
module Rex
|
|
4
|
+
module Proto
|
|
5
|
+
module Rmi
|
|
6
|
+
module Model
|
|
7
|
+
# This class provides a representation of UniqueIdentifier as used in RMI calls
|
|
8
|
+
class UniqueIdentifier < Element
|
|
9
|
+
|
|
10
|
+
# @!attribute number
|
|
11
|
+
# @return [Fixnum] Identifies the VM where an object is generated
|
|
12
|
+
attr_accessor :number
|
|
13
|
+
# @!attribute time
|
|
14
|
+
# @return [Fixnum] Time where the object was generated
|
|
15
|
+
attr_accessor :time
|
|
16
|
+
# @!attribute count
|
|
17
|
+
# @return [Fixnum] Identifies different instance of the same object generated from the same VM
|
|
18
|
+
# at the same time
|
|
19
|
+
attr_accessor :count
|
|
20
|
+
|
|
21
|
+
private
|
|
22
|
+
|
|
23
|
+
# Reads the number from the IO
|
|
24
|
+
#
|
|
25
|
+
# @param io [IO] the IO to read from
|
|
26
|
+
# @return [Fixnum]
|
|
27
|
+
def decode_number(io)
|
|
28
|
+
number = read_int(io)
|
|
29
|
+
|
|
30
|
+
number
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# Reads the time from the IO
|
|
34
|
+
#
|
|
35
|
+
# @param io [IO] the IO to read from
|
|
36
|
+
# @return [Fixnum]
|
|
37
|
+
def decode_time(io)
|
|
38
|
+
time = read_long(io)
|
|
39
|
+
|
|
40
|
+
time
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Reads the count from the IO
|
|
44
|
+
#
|
|
45
|
+
# @param io [IO] the IO to read from
|
|
46
|
+
# @return [Fixnum]
|
|
47
|
+
def decode_count(io)
|
|
48
|
+
count = read_short(io)
|
|
49
|
+
|
|
50
|
+
count
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Encodes the number field
|
|
54
|
+
#
|
|
55
|
+
# @return [String]
|
|
56
|
+
def encode_number
|
|
57
|
+
[number].pack('l>')
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
# Encodes the time field
|
|
61
|
+
#
|
|
62
|
+
# @return [String]
|
|
63
|
+
def encode_time
|
|
64
|
+
[time].pack('q>')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# Encodes the count field
|
|
68
|
+
#
|
|
69
|
+
# @return [String]
|
|
70
|
+
def encode_count
|
|
71
|
+
[count].pack('s>')
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
# -*- coding: binary -*-
|
|
2
|
+
|
|
3
|
+
module Rex
|
|
4
|
+
module Proto
|
|
5
|
+
##
|
|
6
|
+
#
|
|
7
|
+
# Steam protocol support, taken from https://developer.valvesoftware.com/wiki/Server_queries
|
|
8
|
+
#
|
|
9
|
+
##
|
|
10
|
+
module Steam
|
|
11
|
+
# The Steam header ussed when the message is fragmented.
|
|
12
|
+
FRAGMENTED_HEADER = 0xFFFFFFFE
|
|
13
|
+
# The Steam header ussed when the message is not fragmented.
|
|
14
|
+
UNFRAGMENTED_HEADER = 0xFFFFFFFF
|
|
15
|
+
|
|
16
|
+
# Decodes a Steam response message.
|
|
17
|
+
#
|
|
18
|
+
# @param message [String] the message to decode
|
|
19
|
+
# @return [Array] the message type and body
|
|
20
|
+
def decode_message(message)
|
|
21
|
+
# minimum size is header (4) + type (1)
|
|
22
|
+
return if message.length < 5
|
|
23
|
+
header, type = message.unpack('NC')
|
|
24
|
+
# TODO: handle fragmented responses
|
|
25
|
+
return if header != UNFRAGMENTED_HEADER
|
|
26
|
+
[type, message[5, message.length]]
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# Encodes a Steam message.
|
|
30
|
+
#
|
|
31
|
+
# @param type [String, Fixnum] the message type
|
|
32
|
+
# @param body [String] the message body
|
|
33
|
+
# @return [String] the encoded Steam message
|
|
34
|
+
def encode_message(type, body)
|
|
35
|
+
if type.is_a? Fixnum
|
|
36
|
+
type_num = type
|
|
37
|
+
elsif type.is_a? String
|
|
38
|
+
type_num = type.ord
|
|
39
|
+
else
|
|
40
|
+
fail ArgumentError, 'type must be a String or Fixnum'
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
[UNFRAGMENTED_HEADER, type_num ].pack('NC') + body
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Builds an A2S_INFO message
|
|
47
|
+
#
|
|
48
|
+
# @return [String] the A2S_INFO message
|
|
49
|
+
def a2s_info
|
|
50
|
+
encode_message('T', "Source Engine Query\x00")
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Decodes an A2S_INFO response message
|
|
54
|
+
#
|
|
55
|
+
# @parameter response [String] the A2S_INFO resposne to decode
|
|
56
|
+
# @return [Hash] the fields extracted from the response
|
|
57
|
+
def a2s_info_decode(response)
|
|
58
|
+
# abort if it is impossibly short
|
|
59
|
+
return nil if response.length < 19
|
|
60
|
+
message_type, body = decode_message(response)
|
|
61
|
+
# abort if it isn't a valid Steam response
|
|
62
|
+
return nil if message_type != 0x49 # 'I'
|
|
63
|
+
info = {}
|
|
64
|
+
info[:version], info[:name], info[:map], info[:folder], info[:game_name],
|
|
65
|
+
info[:game_id], players, players_max, info[:bots],
|
|
66
|
+
type, env, vis, vac, info[:game_version], _edf = body.unpack("CZ*Z*Z*Z*SCCCCCCCZ*C")
|
|
67
|
+
|
|
68
|
+
# translate type
|
|
69
|
+
case type
|
|
70
|
+
when 100 # d
|
|
71
|
+
server_type = 'Dedicated'
|
|
72
|
+
when 108 # l
|
|
73
|
+
server_type = 'Non-dedicated'
|
|
74
|
+
when 112 # p
|
|
75
|
+
server_type = 'SourceTV relay (proxy)'
|
|
76
|
+
else
|
|
77
|
+
server_type = "Unknown (#{type})"
|
|
78
|
+
end
|
|
79
|
+
info[:type] = server_type
|
|
80
|
+
|
|
81
|
+
# translate environment
|
|
82
|
+
case env
|
|
83
|
+
when 108 # l
|
|
84
|
+
server_env = 'Linux'
|
|
85
|
+
when 119 # w
|
|
86
|
+
server_env = 'Windows'
|
|
87
|
+
when 109 # m
|
|
88
|
+
when 111 # o
|
|
89
|
+
server_env = 'Mac'
|
|
90
|
+
else
|
|
91
|
+
server_env = "Unknown (#{env})"
|
|
92
|
+
end
|
|
93
|
+
info[:environment] = server_env
|
|
94
|
+
|
|
95
|
+
# translate visibility
|
|
96
|
+
case vis
|
|
97
|
+
when 0
|
|
98
|
+
server_vis = 'public'
|
|
99
|
+
when 1
|
|
100
|
+
server_vis = 'private'
|
|
101
|
+
else
|
|
102
|
+
server_vis = "Unknown (#{vis})"
|
|
103
|
+
end
|
|
104
|
+
info[:visibility] = server_vis
|
|
105
|
+
|
|
106
|
+
# translate VAC
|
|
107
|
+
case vac
|
|
108
|
+
when 0
|
|
109
|
+
server_vac = 'unsecured'
|
|
110
|
+
when 1
|
|
111
|
+
server_vac = 'secured'
|
|
112
|
+
else
|
|
113
|
+
server_vac = "Unknown (#{vac})"
|
|
114
|
+
end
|
|
115
|
+
info[:VAC] = server_vac
|
|
116
|
+
|
|
117
|
+
# format players/max
|
|
118
|
+
info[:players] = "#{players}/#{players_max}"
|
|
119
|
+
|
|
120
|
+
# TODO: parse EDF
|
|
121
|
+
info
|
|
122
|
+
end
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
end
|