rex 2.0.8 → 2.0.9

Sign up to get free protection for your applications and to get access to all the features.
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