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.
Files changed (151) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex.rb +1 -0
  3. data/lib/rex/arch.rb +5 -0
  4. data/lib/rex/arch/x86.rb +19 -5
  5. data/lib/rex/arch/zarch.rb +17 -0
  6. data/lib/rex/compat.rb +5 -4
  7. data/lib/rex/constants.rb +3 -1
  8. data/lib/rex/encoder/alpha2/alpha_mixed.rb +70 -9
  9. data/lib/rex/encoder/alpha2/alpha_upper.rb +67 -8
  10. data/lib/rex/exploitation/cmdstager.rb +1 -0
  11. data/lib/rex/exploitation/cmdstager/certutil.rb +115 -0
  12. data/lib/rex/exploitation/cmdstager/echo.rb +6 -3
  13. data/lib/rex/exploitation/egghunter.rb +1 -1
  14. data/lib/rex/google/geolocation.rb +68 -0
  15. data/lib/rex/io/bidirectional_pipe.rb +0 -4
  16. data/lib/rex/java/serialization.rb +2 -0
  17. data/lib/rex/java/serialization/decode_error.rb +11 -0
  18. data/lib/rex/java/serialization/encode_error.rb +11 -0
  19. data/lib/rex/java/serialization/model.rb +2 -0
  20. data/lib/rex/java/serialization/model/annotation.rb +3 -3
  21. data/lib/rex/java/serialization/model/block_data.rb +3 -3
  22. data/lib/rex/java/serialization/model/block_data_long.rb +3 -3
  23. data/lib/rex/java/serialization/model/class_desc.rb +6 -6
  24. data/lib/rex/java/serialization/model/contents.rb +17 -10
  25. data/lib/rex/java/serialization/model/field.rb +12 -11
  26. data/lib/rex/java/serialization/model/long_utf.rb +3 -3
  27. data/lib/rex/java/serialization/model/new_array.rb +22 -23
  28. data/lib/rex/java/serialization/model/new_class.rb +57 -0
  29. data/lib/rex/java/serialization/model/new_class_desc.rb +15 -16
  30. data/lib/rex/java/serialization/model/new_enum.rb +5 -5
  31. data/lib/rex/java/serialization/model/new_object.rb +22 -17
  32. data/lib/rex/java/serialization/model/proxy_class_desc.rb +109 -0
  33. data/lib/rex/java/serialization/model/reference.rb +4 -4
  34. data/lib/rex/java/serialization/model/stream.rb +7 -7
  35. data/lib/rex/java/serialization/model/utf.rb +3 -3
  36. data/lib/rex/json_hash_file.rb +94 -0
  37. data/lib/rex/logging/log_sink.rb +1 -0
  38. data/lib/rex/logging/sinks/timestamp_flatfile.rb +21 -0
  39. data/lib/rex/parser/appscan_nokogiri.rb +13 -23
  40. data/lib/rex/parser/fs/ntfs.rb +10 -5
  41. data/lib/rex/parser/nmap_nokogiri.rb +3 -1
  42. data/lib/rex/parser/openvas_nokogiri.rb +70 -73
  43. data/lib/rex/parser/winscp.rb +108 -0
  44. data/lib/rex/parser/x509_certificate.rb +92 -0
  45. data/lib/rex/payloads.rb +0 -1
  46. data/lib/rex/payloads/meterpreter/config.rb +154 -0
  47. data/lib/rex/payloads/meterpreter/uri_checksum.rb +136 -0
  48. data/lib/rex/post/meterpreter.rb +1 -1
  49. data/lib/rex/post/meterpreter/client.rb +26 -3
  50. data/lib/rex/post/meterpreter/client_core.rb +387 -75
  51. data/lib/rex/post/meterpreter/extensions/android/android.rb +127 -37
  52. data/lib/rex/post/meterpreter/extensions/android/tlv.rb +46 -25
  53. data/lib/rex/post/meterpreter/extensions/extapi/extapi.rb +4 -0
  54. data/lib/rex/post/meterpreter/extensions/extapi/ntds/ntds.rb +39 -0
  55. data/lib/rex/post/meterpreter/extensions/extapi/pageant/pageant.rb +44 -0
  56. data/lib/rex/post/meterpreter/extensions/extapi/tlv.rb +9 -0
  57. data/lib/rex/post/meterpreter/extensions/kiwi/kiwi.rb +16 -1
  58. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +1 -1
  59. data/lib/rex/post/meterpreter/extensions/python/python.rb +114 -0
  60. data/lib/rex/post/meterpreter/extensions/python/tlv.rb +21 -0
  61. data/lib/rex/post/meterpreter/extensions/stdapi/fs/dir.rb +17 -14
  62. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +33 -12
  63. data/lib/rex/post/meterpreter/extensions/stdapi/fs/mount.rb +57 -0
  64. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_kernel32.rb +3 -3
  65. data/lib/rex/post/meterpreter/extensions/stdapi/stdapi.rb +3 -1
  66. data/lib/rex/post/meterpreter/extensions/stdapi/sys/config.rb +2 -0
  67. data/lib/rex/post/meterpreter/extensions/stdapi/sys/process.rb +16 -3
  68. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry.rb +29 -6
  69. data/lib/rex/post/meterpreter/extensions/stdapi/sys/registry_subsystem/registry_key.rb +5 -1
  70. data/lib/rex/post/meterpreter/extensions/stdapi/tlv.rb +18 -6
  71. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +2 -2
  72. data/lib/rex/post/meterpreter/extensions/stdapi/webcam/webcam.rb +34 -36
  73. data/lib/rex/post/meterpreter/packet.rb +29 -0
  74. data/lib/rex/post/meterpreter/packet_dispatcher.rb +20 -7
  75. data/lib/rex/post/meterpreter/ui/console.rb +1 -0
  76. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/android.rb +230 -72
  77. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +544 -34
  78. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/extapi/adsi.rb +188 -57
  79. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/kiwi.rb +115 -93
  80. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/lanattacks/dhcp.rb +1 -1
  81. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/mimikatz.rb +1 -1
  82. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/elevate.rb +49 -15
  83. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/priv/timestomp.rb +11 -2
  84. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/python.rb +187 -0
  85. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +324 -133
  86. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +52 -2
  87. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +68 -65
  88. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +9 -1
  89. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/webcam.rb +113 -118
  90. data/lib/rex/post/meterpreter/ui/console/interactive_channel.rb +3 -0
  91. data/lib/rex/powershell.rb +62 -0
  92. data/lib/rex/powershell/command.rb +359 -0
  93. data/lib/rex/{exploitation/powershell → powershell}/function.rb +0 -2
  94. data/lib/rex/{exploitation/powershell → powershell}/obfu.rb +0 -2
  95. data/lib/rex/{exploitation/powershell → powershell}/output.rb +11 -5
  96. data/lib/rex/{exploitation/powershell → powershell}/param.rb +0 -2
  97. data/lib/rex/powershell/parser.rb +182 -0
  98. data/lib/rex/powershell/payload.rb +78 -0
  99. data/lib/rex/{exploitation/powershell → powershell}/psh_methods.rb +16 -2
  100. data/lib/rex/{exploitation/powershell → powershell}/script.rb +2 -4
  101. data/lib/rex/proto/dcerpc/client.rb +6 -6
  102. data/lib/rex/proto/dcerpc/exceptions.rb +26 -0
  103. data/lib/rex/proto/http/client.rb +3 -3
  104. data/lib/rex/proto/http/client_request.rb +0 -5
  105. data/lib/rex/proto/http/response.rb +86 -0
  106. data/lib/rex/proto/ipmi/utils.rb +30 -26
  107. data/lib/rex/proto/kerberos/client.rb +1 -1
  108. data/lib/rex/proto/kerberos/model/kdc_request.rb +2 -2
  109. data/lib/rex/proto/rfb/client.rb +8 -3
  110. data/lib/rex/proto/rfb/constants.rb +1 -1
  111. data/lib/rex/proto/rmi.rb +2 -0
  112. data/lib/rex/proto/rmi/decode_error.rb +10 -0
  113. data/lib/rex/proto/rmi/exception.rb +10 -0
  114. data/lib/rex/proto/rmi/model.rb +5 -0
  115. data/lib/rex/proto/rmi/model/call.rb +4 -4
  116. data/lib/rex/proto/rmi/model/call_data.rb +137 -0
  117. data/lib/rex/proto/rmi/model/dgc_ack.rb +2 -2
  118. data/lib/rex/proto/rmi/model/element.rb +26 -11
  119. data/lib/rex/proto/rmi/model/output_header.rb +4 -4
  120. data/lib/rex/proto/rmi/model/ping.rb +2 -2
  121. data/lib/rex/proto/rmi/model/ping_ack.rb +2 -2
  122. data/lib/rex/proto/rmi/model/protocol_ack.rb +2 -2
  123. data/lib/rex/proto/rmi/model/return_data.rb +5 -5
  124. data/lib/rex/proto/rmi/model/return_value.rb +124 -0
  125. data/lib/rex/proto/rmi/model/unique_identifier.rb +77 -0
  126. data/lib/rex/proto/steam.rb +3 -0
  127. data/lib/rex/proto/steam/message.rb +125 -0
  128. data/lib/rex/proto/tftp/client.rb +35 -14
  129. data/lib/rex/random_identifier_generator.rb +2 -0
  130. data/lib/rex/ropbuilder.rb +1 -1
  131. data/lib/rex/socket/parameters.rb +9 -0
  132. data/lib/rex/socket/ssl_tcp.rb +25 -41
  133. data/lib/rex/socket/ssl_tcp_server.rb +10 -21
  134. data/lib/rex/sslscan/result.rb +20 -1
  135. data/lib/rex/text.rb +241 -55
  136. data/lib/rex/ui/output.rb +0 -3
  137. data/lib/rex/ui/subscriber.rb +0 -10
  138. data/lib/rex/ui/text/color.rb +9 -0
  139. data/lib/rex/ui/text/dispatcher_shell.rb +1 -0
  140. data/lib/rex/ui/text/output.rb +15 -4
  141. data/lib/rex/ui/text/output/file.rb +1 -0
  142. data/lib/rex/ui/text/output/stdio.rb +0 -16
  143. data/lib/rex/ui/text/shell.rb +3 -0
  144. data/lib/rex/ui/text/table.rb +85 -19
  145. data/lib/rex/user_agent.rb +118 -0
  146. data/rex.gemspec +2 -2
  147. metadata +41 -14
  148. data/lib/rex/exploitation/powershell.rb +0 -62
  149. data/lib/rex/exploitation/powershell/parser.rb +0 -183
  150. data/lib/rex/payloads/meterpreter.rb +0 -2
  151. data/lib/rex/payloads/meterpreter/patch.rb +0 -136
@@ -58,7 +58,6 @@ class Client
58
58
  'method_random_case' => 'bool',
59
59
  'version_random_valid' => 'bool',
60
60
  'version_random_invalid' => 'bool',
61
- 'version_random_case' => 'bool',
62
61
  'uri_dir_self_reference' => 'bool',
63
62
  'uri_dir_fake_relative' => 'bool',
64
63
  'uri_use_backslashes' => 'bool',
@@ -579,14 +578,15 @@ class Client
579
578
 
580
579
  rv = nil
581
580
  while (
581
+ not conn.closed? and
582
582
  rv != Packet::ParseCode::Completed and
583
583
  rv != Packet::ParseCode::Error
584
584
  )
585
585
 
586
586
  begin
587
587
 
588
- buff = conn.get_once(-1, 1)
589
- rv = resp.parse( buff || '' )
588
+ buff = conn.get_once(resp.max_data, 1)
589
+ rv = resp.parse(buff || '')
590
590
 
591
591
  # Handle unexpected disconnects
592
592
  rescue ::Errno::EPIPE, ::EOFError, ::IOError
@@ -52,7 +52,6 @@ class ClientRequest
52
52
  'method_random_case' => false, # bool
53
53
  'version_random_valid' => false, # bool
54
54
  'version_random_invalid' => false, # bool
55
- 'version_random_case' => false, # bool
56
55
  'uri_dir_self_reference' => false, # bool
57
56
  'uri_dir_fake_relative' => false, # bool
58
57
  'uri_use_backslashes' => false, # bool
@@ -344,10 +343,6 @@ class ClientRequest
344
343
  ret = Rex::Text.rand_text_alphanumeric(rand(20)+1)
345
344
  end
346
345
 
347
- if (opts['version_random_case'])
348
- ret = Rex::Text.to_rand_case(ret)
349
- end
350
-
351
346
  ret << "\r\n"
352
347
  end
353
348
 
@@ -1,6 +1,8 @@
1
1
  # -*- coding: binary -*-
2
2
  require 'uri'
3
3
  require 'rex/proto/http'
4
+ require 'nokogiri'
5
+ require 'rkelly'
4
6
 
5
7
  module Rex
6
8
  module Proto
@@ -82,6 +84,90 @@ class Response < Packet
82
84
  return cookies.strip
83
85
  end
84
86
 
87
+
88
+ # Returns a parsed HTML document.
89
+ # Instead of using regexes to parse the HTML body, you should use this and use the Nokogiri API.
90
+ #
91
+ # @see http://www.nokogiri.org/
92
+ # @return [Nokogiri::HTML::Document]
93
+ def get_html_document
94
+ Nokogiri::HTML(self.body)
95
+ end
96
+
97
+ # Returns a parsed XML document.
98
+ # Instead of using regexes to parse the XML body, you should use this and use the Nokogiri API.
99
+ #
100
+ # @see http://www.nokogiri.org/
101
+ # @return [Nokogiri::XML::Document]
102
+ def get_xml_document
103
+ Nokogiri::XML(self.body)
104
+ end
105
+
106
+ # Returns a parsed json document.
107
+ # Instead of using regexes to parse the JSON body, you should use this.
108
+ #
109
+ # @return [Hash]
110
+ def get_json_document
111
+ json = []
112
+
113
+ begin
114
+ json = JSON.parse(self.body)
115
+ rescue JSON::ParserError => e
116
+ elog("#{e.class} #{e.message}\n#{e.backtrace * "\n"}")
117
+ end
118
+
119
+ json
120
+ end
121
+
122
+ # Returns meta tags.
123
+ # You will probably want to use this the web app's version info (or other stuff) can be found
124
+ # in the metadata.
125
+ #
126
+ # @return [Array<Nokogiri::XML::Element>]
127
+ def get_html_meta_elements
128
+ n = get_html_document
129
+ n.search('//meta')
130
+ end
131
+
132
+ # Returns parsed JavaScript blocks.
133
+ # The parsed version is a RKelly object that allows you to be able do advanced parsing.
134
+ #
135
+ # @see https://github.com/tenderlove/rkelly
136
+ # @return [Array<RKelly::Nodes::SourceElementsNode>]
137
+ def get_html_scripts
138
+ n = get_html_document
139
+ rkelly = RKelly::Parser.new
140
+ n.search('//script').map { |s| rkelly.parse(s.text) }
141
+ end
142
+
143
+
144
+ # Returns a collection of found hidden inputs
145
+ #
146
+ # @return [Array<Hash>] An array, each element represents a form that contains a hash of found hidden inputs
147
+ # * 'name' [String] The hidden input's original name. The value is the hidden input's original value.
148
+ # @example
149
+ # res = send_request_cgi('uri'=>'/')
150
+ # inputs = res.get_hidden_inputs
151
+ # session_id = inputs[0]['sessionid'] # The first form's 'sessionid' hidden input
152
+ def get_hidden_inputs
153
+ forms = []
154
+ noko = get_html_document
155
+ noko.search("form").each_entry do |form|
156
+ found_inputs = {}
157
+ form.search("input").each_entry do |input|
158
+ input_type = input.attributes['type'] ? input.attributes['type'].value : ''
159
+ next if input_type !~ /hidden/i
160
+
161
+ input_name = input.attributes['name'] ? input.attributes['name'].value : ''
162
+ input_value = input.attributes['value'] ? input.attributes['value'].value : ''
163
+ found_inputs[input_name] = input_value unless input_name.empty?
164
+ end
165
+ forms << found_inputs unless found_inputs.empty?
166
+ end
167
+
168
+ forms
169
+ end
170
+
85
171
  #
86
172
  # Updates the various parts of the HTTP response command string.
87
173
  #
@@ -15,8 +15,8 @@ class Utils
15
15
  def self.create_ipmi_getchannel_probe
16
16
  [ # Get Channel Authentication Capabilities
17
17
  0x06, 0x00, 0xff, 0x07, # RMCP Header
18
- 0x00, 0x00, 0x00, 0x00,
19
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x18,
18
+ 0x00, 0x00, 0x00, 0x00,
19
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x20, 0x18,
20
20
  0xc8, 0x81, 0x00, 0x38, 0x8e, 0x04, 0xb5
21
21
  ].pack("C*")
22
22
  end
@@ -36,20 +36,20 @@ class Utils
36
36
  0x00, 0x00,
37
37
  # Reserved
38
38
  0x00, 0x00
39
- ].pack("C*") +
39
+ ].pack("C*") +
40
40
  console_session_id +
41
41
  [
42
- 0x00, 0x00, 0x00, 0x08,
42
+ 0x00, 0x00, 0x00, 0x08,
43
43
  0x01, 0x00, 0x00, 0x00,
44
- 0x01, 0x00, 0x00, 0x08,
44
+ 0x01, 0x00, 0x00, 0x08,
45
45
  # HMAC-SHA1
46
- 0x01, 0x00, 0x00, 0x00,
47
- 0x02, 0x00, 0x00, 0x08,
46
+ 0x01, 0x00, 0x00, 0x00,
47
+ 0x02, 0x00, 0x00, 0x08,
48
48
  # AES Encryption
49
49
  0x01, 0x00, 0x00, 0x00
50
50
  ].pack("C*")
51
51
 
52
- head + [data.length].pack('v') + data
52
+ head + [data.length].pack('v') + data
53
53
  end
54
54
 
55
55
 
@@ -68,39 +68,43 @@ class Utils
68
68
  0x00, 0x00,
69
69
  # Reserved
70
70
  0x00, 0x00
71
- ].pack("C*") +
71
+ ].pack("C*") +
72
72
  console_session_id +
73
73
  [
74
- 0x00, 0x00, 0x00, 0x08,
74
+ 0x00, 0x00, 0x00, 0x08,
75
75
  # Cipher 0
76
76
  0x00, 0x00, 0x00, 0x00,
77
77
  0x01, 0x00, 0x00, 0x08,
78
78
  # Cipher 0
79
79
  0x00, 0x00, 0x00, 0x00,
80
80
  0x02, 0x00, 0x00, 0x08,
81
- # No Encryption
81
+ # No Encryption
82
82
  0x00, 0x00, 0x00, 0x00
83
83
  ].pack("C*")
84
84
 
85
- head + [data.length].pack('v') + data
85
+ head + [data.length].pack('v') + data
86
86
  end
87
87
 
88
88
  def self.create_ipmi_rakp_1(bmc_session_id, console_random_id, username)
89
- [
89
+ head = [
90
90
  0x06, 0x00, 0xff, 0x07, # RMCP Header
91
91
  0x06, # RMCP+ Authentication Type
92
92
  PAYLOAD_RAKP1, # Payload Type
93
- 0x00, 0x00,
94
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00,
95
- 0x00, 0x00, 0x00, 0x00
96
- ].pack("C*") +
97
- bmc_session_id +
98
- console_random_id +
99
- [
100
- 0x14, 0x00, 0x00,
101
- username.length
102
- ].pack("C*") +
103
- username
93
+ 0x00, 0x00, 0x00, 0x00,
94
+ 0x00, 0x00, 0x00, 0x00,
95
+ ].pack("C*")
96
+
97
+ data =
98
+ [0x00, 0x00, 0x00, 0x00].pack("C*") +
99
+ bmc_session_id +
100
+ console_random_id +
101
+ [
102
+ 0x14, 0x00, 0x00,
103
+ username.length
104
+ ].pack("C*") +
105
+ username
106
+
107
+ head + [data.length].pack('v') + data
104
108
  end
105
109
 
106
110
 
@@ -109,7 +113,7 @@ class Utils
109
113
  bmc_sid +
110
114
  con_rid +
111
115
  bmc_rid +
112
- bmc_gid +
116
+ bmc_gid +
113
117
  [ auth_level ].pack("C") +
114
118
  [ username.length ].pack("C") +
115
119
  username
@@ -122,4 +126,4 @@ class Utils
122
126
  end
123
127
  end
124
128
  end
125
- end
129
+ end
@@ -187,7 +187,7 @@ module Rex
187
187
 
188
188
  # Decodes a Kerberos response
189
189
  #
190
- # @param input [String] the raw response message
190
+ # @param data [String] the raw response message
191
191
  # @return [<Rex::Proto::Kerberos::Model::KrbError, Rex::Proto::Kerberos::Model::KdcResponse>] the kerberos message response
192
192
  # @raise [RuntimeError] if the response can't be processed
193
193
  def decode_kerb_response(data)
@@ -118,7 +118,7 @@ module Rex
118
118
  when 4
119
119
  self.req_body = decode_asn1_req_body(val)
120
120
  else
121
- raise ::RuntimeError, 'Filed to decode KdcRequest SEQUENCE'
121
+ raise ::RuntimeError, 'Failed to decode KdcRequest SEQUENCE'
122
122
  end
123
123
  end
124
124
  end
@@ -163,4 +163,4 @@ module Rex
163
163
  end
164
164
  end
165
165
  end
166
- end
166
+ end
@@ -24,7 +24,7 @@ class Client
24
24
  @opts = opts
25
25
 
26
26
  @banner = nil
27
- @majver = MajorVersion
27
+ @majver = MajorVersions
28
28
  @minver = -1
29
29
  @auth_types = []
30
30
  end
@@ -50,7 +50,7 @@ class Client
50
50
 
51
51
  if @banner =~ /RFB ([0-9]{3})\.([0-9]{3})/
52
52
  maj = $1.to_i
53
- if maj != MajorVersion
53
+ unless MajorVersions.include?(maj)
54
54
  @error = "Invalid major version number: #{maj}"
55
55
  return false
56
56
  end
@@ -61,7 +61,12 @@ class Client
61
61
 
62
62
  @minver = $2.to_i
63
63
 
64
- our_ver = "RFB %03d.%03d\n" % [MajorVersion, @minver]
64
+ # Forces version 3 to be used. This adds support for version 4 servers.
65
+ # It may be necessary to hardcode minver as well.
66
+ # TODO: Add support for Version 4.
67
+ # Version 4 adds additional information to the packet regarding supported
68
+ # authentication types.
69
+ our_ver = "RFB %03d.%03d\n" % [3, @minver]
65
70
  @sock.put(our_ver)
66
71
 
67
72
  true
@@ -19,7 +19,7 @@ module RFB
19
19
  DefaultPort = 5900
20
20
 
21
21
  # Version information
22
- MajorVersion = 3
22
+ MajorVersions = [3, 4]
23
23
  # NOTE: We will emulate whatever minor version the server reports.
24
24
 
25
25
  # Security types
data/lib/rex/proto/rmi.rb CHANGED
@@ -3,5 +3,7 @@
3
3
  # JAVA RMI Wire protocol implementation
4
4
  # http://docs.oracle.com/javase/7/docs/platform/rmi/spec/rmi-protocol.html
5
5
 
6
+ require 'rex/proto/rmi/exception'
7
+ require 'rex/proto/rmi/decode_error'
6
8
  require 'rex/proto/rmi/model'
7
9
 
@@ -0,0 +1,10 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Rmi
6
+ class DecodeError < ::RuntimeError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Rmi
6
+ class Exception < ::RuntimeError
7
+ end
8
+ end
9
+ end
10
+ end
@@ -15,6 +15,8 @@ module Rex
15
15
  PROTOCOL_NOT_SUPPORTED = 0x4f
16
16
  RETURN_DATA = 0x51
17
17
  PING_ACK = 0x53
18
+ RETURN_VALUE = 1
19
+ RETURN_EXCEPTION = 2
18
20
  end
19
21
  end
20
22
  end
@@ -24,7 +26,10 @@ require 'rex/proto/rmi/model/element'
24
26
  require 'rex/proto/rmi/model/output_header'
25
27
  require 'rex/proto/rmi/model/protocol_ack'
26
28
  require 'rex/proto/rmi/model/continuation'
29
+ require 'rex/proto/rmi/model/unique_identifier'
30
+ require 'rex/proto/rmi/model/call_data'
27
31
  require 'rex/proto/rmi/model/call'
32
+ require 'rex/proto/rmi/model/return_value'
28
33
  require 'rex/proto/rmi/model/return_data'
29
34
  require 'rex/proto/rmi/model/dgc_ack'
30
35
  require 'rex/proto/rmi/model/ping'
@@ -11,7 +11,7 @@ module Rex
11
11
  # @return [Fixnum] the message id
12
12
  attr_accessor :message_id
13
13
  # @!attribute call_data
14
- # @return [Rex::Java::Serialization::Model::Stream] the serialized call data
14
+ # @return [Rex::Proto::Rmi::Model::CallData] the call data
15
15
  attr_accessor :call_data
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 [RuntimeError] if fails to decode the message id
23
+ # @raise [Rex::Proto::Rmi::DecodeError] if fails to decode the message id
24
24
  def decode_message_id(io)
25
25
  message_id = read_byte(io)
26
26
  unless message_id == CALL_MESSAGE
27
- raise ::RuntimeError, 'Failed to decode Call message id'
27
+ raise Rex::Proto::Rmi::DecodeError, 'Failed to decode Call message id'
28
28
  end
29
29
 
30
30
  message_id
@@ -35,7 +35,7 @@ module Rex
35
35
  # @param io [IO] the IO to read from
36
36
  # @return [Rex::Java::Serialization::Model::Stream]
37
37
  def decode_call_data(io)
38
- call_data = Rex::Java::Serialization::Model::Stream.decode(io)
38
+ call_data = Rex::Proto::Rmi::Model::CallData.decode(io)
39
39
 
40
40
  call_data
41
41
  end
@@ -0,0 +1,137 @@
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 CallData < Element
9
+
10
+ # @!attribute object_number
11
+ # @return [Fixnum] Random to identify the object being called
12
+ attr_accessor :object_number
13
+ # @!attribute uid
14
+ # @return [Rex::Proto::Rmi::Model::UniqueIdentifier] unique identifier for the target to call
15
+ attr_accessor :uid
16
+ # @!attribute operation
17
+ # @return [Fixnum] On JDK 1.1 stub protocol the operation index in the interface. On JDK 1.2
18
+ # it is -1.
19
+ attr_accessor :operation
20
+ # @!attribute hash
21
+ # @return [Fixnum] On JDK 1.1 stub protocol the stub's interface hash. On JDK1.2 is a hash
22
+ # representing the method to call.
23
+ attr_accessor :hash
24
+ # @!attribute arguments
25
+ # @return [Array] the returned exception or value according to code
26
+ attr_accessor :arguments
27
+
28
+ # Encodes the Rex::Proto::Rmi::Model::CallData into an String.
29
+ #
30
+ # @return [String]
31
+ def encode
32
+ stream = Rex::Java::Serialization::Model::Stream.new
33
+ block_data = Rex::Java::Serialization::Model::BlockData.new(nil, encode_object_number + encode_uid + encode_operation + encode_hash)
34
+
35
+ stream.contents << block_data
36
+ stream.contents += arguments
37
+
38
+ stream.encode
39
+ end
40
+
41
+ # Decodes the Rex::Proto::Rmi::Model::CallData from the input.
42
+ #
43
+ # @param io [IO] the IO to read from
44
+ # @return [Rex::Proto::Rmi::Model::CallData]
45
+ def decode(io)
46
+ stream = Rex::Java::Serialization::Model::Stream.decode(io)
47
+
48
+ block_data = stream.contents[0]
49
+ block_data_io = StringIO.new(block_data.contents, 'rb')
50
+
51
+ self.object_number = decode_object_number(block_data_io)
52
+ self.uid = decode_uid(block_data_io)
53
+ self.operation = decode_operation(block_data_io)
54
+ self.hash = decode_hash(block_data_io)
55
+ self.arguments = []
56
+
57
+ stream.contents[1..stream.contents.length - 1].each do |content|
58
+ self.arguments << content
59
+ end
60
+
61
+ self
62
+ end
63
+
64
+ private
65
+
66
+ # Reads the object number from the IO
67
+ #
68
+ # @param io [IO] the IO to read from
69
+ # @return [Fixnum]
70
+ def decode_object_number(io)
71
+ object_number = read_long(io)
72
+
73
+ object_number
74
+ end
75
+
76
+ # Reads and deserializes the uid from the IO
77
+ #
78
+ # @param io [IO] the IO to read from
79
+ # @return [Rex::Proto::Rmi::Model::UniqueIdentifier]
80
+ def decode_uid(io)
81
+ uid = Rex::Proto::Rmi::Model::UniqueIdentifier.decode(io)
82
+
83
+ uid
84
+ end
85
+
86
+ # Reads the operation from the IO
87
+ #
88
+ # @param io [IO] the IO to read from
89
+ # @return [Fixnum]
90
+ def decode_operation(io)
91
+ operation = read_int(io)
92
+
93
+ operation
94
+ end
95
+
96
+ # Reads the hash from the IO
97
+ #
98
+ # @param io [IO] the IO to read from
99
+ # @return [Fixnum]
100
+ def decode_hash(io)
101
+ hash = read_long(io)
102
+
103
+ hash
104
+ end
105
+
106
+ # Encodes the code field
107
+ #
108
+ # @return [String]
109
+ def encode_object_number
110
+ [object_number].pack('q>')
111
+ end
112
+
113
+ # Encodes the uid field
114
+ #
115
+ # @return [String]
116
+ def encode_uid
117
+ uid.encode
118
+ end
119
+
120
+ # Encodes the operation field
121
+ #
122
+ # @return [String]
123
+ def encode_operation
124
+ [operation].pack('l>')
125
+ end
126
+
127
+ # Encodes the hash field
128
+ #
129
+ # @return [String]
130
+ def encode_hash
131
+ [hash].pack('q>')
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end