rex 2.0.5 → 2.0.7

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 (98) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rex/exploitation/egghunter.rb +4 -6
  3. data/lib/rex/exploitation/powershell/psh_methods.rb +9 -0
  4. data/lib/rex/java/serialization.rb +2 -1
  5. data/lib/rex/java/serialization/builder.rb +94 -0
  6. data/lib/rex/java/serialization/model.rb +29 -18
  7. data/lib/rex/java/serialization/model/annotation.rb +2 -2
  8. data/lib/rex/java/serialization/model/field.rb +2 -2
  9. data/lib/rex/java/serialization/model/new_array.rb +8 -3
  10. data/lib/rex/java/serialization/model/new_class_desc.rb +3 -3
  11. data/lib/rex/java/serialization/model/new_enum.rb +4 -4
  12. data/lib/rex/java/serialization/model/new_object.rb +17 -10
  13. data/lib/rex/ole/direntry.rb +1 -1
  14. data/lib/rex/ole/samples/create_ole.rb +0 -0
  15. data/lib/rex/ole/samples/dir.rb +0 -0
  16. data/lib/rex/ole/samples/dump_stream.rb +0 -0
  17. data/lib/rex/ole/samples/ole_info.rb +0 -0
  18. data/lib/rex/parser/foundstone_nokogiri.rb +1 -1
  19. data/lib/rex/parser/fs/ntfs.rb +252 -0
  20. data/lib/rex/parser/openvas_nokogiri.rb +2 -0
  21. data/lib/rex/payloads/win32/kernel.rb +3 -3
  22. data/lib/rex/post/meterpreter/client_core.rb +172 -64
  23. data/lib/rex/post/meterpreter/extensions/priv/priv.rb +3 -2
  24. data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +12 -10
  25. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +64 -37
  26. data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +8 -2
  27. data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +15 -3
  28. data/lib/rex/post/meterpreter/packet.rb +41 -38
  29. data/lib/rex/post/meterpreter/packet_dispatcher.rb +7 -1
  30. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +17 -4
  31. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +11 -4
  32. data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +1 -1
  33. data/lib/rex/proto.rb +2 -0
  34. data/lib/rex/proto/acpp.rb +17 -0
  35. data/lib/rex/proto/acpp/client.rb +29 -0
  36. data/lib/rex/proto/acpp/message.rb +183 -0
  37. data/lib/rex/proto/http/client.rb +1 -2
  38. data/lib/rex/proto/iax2/call.rb +22 -3
  39. data/lib/rex/proto/iax2/client.rb +1 -0
  40. data/lib/rex/proto/kerberos.rb +13 -0
  41. data/lib/rex/proto/kerberos/client.rb +213 -0
  42. data/lib/rex/proto/kerberos/credential_cache.rb +19 -0
  43. data/lib/rex/proto/kerberos/credential_cache/cache.rb +81 -0
  44. data/lib/rex/proto/kerberos/credential_cache/credential.rb +151 -0
  45. data/lib/rex/proto/kerberos/credential_cache/element.rb +49 -0
  46. data/lib/rex/proto/kerberos/credential_cache/key_block.rb +62 -0
  47. data/lib/rex/proto/kerberos/credential_cache/principal.rb +70 -0
  48. data/lib/rex/proto/kerberos/credential_cache/time.rb +69 -0
  49. data/lib/rex/proto/kerberos/crypto.rb +21 -0
  50. data/lib/rex/proto/kerberos/crypto/rc4_hmac.rb +65 -0
  51. data/lib/rex/proto/kerberos/crypto/rsa_md5.rb +15 -0
  52. data/lib/rex/proto/kerberos/model.rb +133 -0
  53. data/lib/rex/proto/kerberos/model/ap_req.rb +98 -0
  54. data/lib/rex/proto/kerberos/model/authenticator.rb +143 -0
  55. data/lib/rex/proto/kerberos/model/authorization_data.rb +85 -0
  56. data/lib/rex/proto/kerberos/model/checksum.rb +59 -0
  57. data/lib/rex/proto/kerberos/model/element.rb +67 -0
  58. data/lib/rex/proto/kerberos/model/enc_kdc_response.rb +215 -0
  59. data/lib/rex/proto/kerberos/model/encrypted_data.rb +171 -0
  60. data/lib/rex/proto/kerberos/model/encryption_key.rb +106 -0
  61. data/lib/rex/proto/kerberos/model/kdc_request.rb +166 -0
  62. data/lib/rex/proto/kerberos/model/kdc_request_body.rb +315 -0
  63. data/lib/rex/proto/kerberos/model/kdc_response.rb +141 -0
  64. data/lib/rex/proto/kerberos/model/krb_error.rb +219 -0
  65. data/lib/rex/proto/kerberos/model/last_request.rb +82 -0
  66. data/lib/rex/proto/kerberos/model/pre_auth_data.rb +104 -0
  67. data/lib/rex/proto/kerberos/model/pre_auth_enc_time_stamp.rb +126 -0
  68. data/lib/rex/proto/kerberos/model/pre_auth_pac_request.rb +81 -0
  69. data/lib/rex/proto/kerberos/model/principal_name.rb +116 -0
  70. data/lib/rex/proto/kerberos/model/ticket.rb +151 -0
  71. data/lib/rex/proto/kerberos/pac.rb +36 -0
  72. data/lib/rex/proto/kerberos/pac/client_info.rb +53 -0
  73. data/lib/rex/proto/kerberos/pac/element.rb +52 -0
  74. data/lib/rex/proto/kerberos/pac/logon_info.rb +566 -0
  75. data/lib/rex/proto/kerberos/pac/priv_svr_checksum.rb +29 -0
  76. data/lib/rex/proto/kerberos/pac/server_checksum.rb +30 -0
  77. data/lib/rex/proto/kerberos/pac/type.rb +121 -0
  78. data/lib/rex/proto/rmi.rb +7 -0
  79. data/lib/rex/proto/rmi/model.rb +31 -0
  80. data/lib/rex/proto/rmi/model/call.rb +60 -0
  81. data/lib/rex/proto/rmi/model/continuation.rb +76 -0
  82. data/lib/rex/proto/rmi/model/dgc_ack.rb +62 -0
  83. data/lib/rex/proto/rmi/model/element.rb +143 -0
  84. data/lib/rex/proto/rmi/model/output_header.rb +86 -0
  85. data/lib/rex/proto/rmi/model/ping.rb +41 -0
  86. data/lib/rex/proto/rmi/model/ping_ack.rb +41 -0
  87. data/lib/rex/proto/rmi/model/protocol_ack.rb +100 -0
  88. data/lib/rex/proto/rmi/model/return_data.rb +60 -0
  89. data/lib/rex/socket.rb +9 -1
  90. data/lib/rex/socket/tcp_server.rb +3 -0
  91. data/lib/rex/ui/text/dispatcher_shell.rb +4 -4
  92. data/lib/rex/ui/text/output/tee.rb +2 -0
  93. data/lib/rex/zip/samples/comment.rb +0 -0
  94. data/lib/rex/zip/samples/mkwar.rb +0 -0
  95. data/lib/rex/zip/samples/mkzip.rb +0 -0
  96. data/lib/rex/zip/samples/recursive.rb +0 -0
  97. data/rex.gemspec +1 -1
  98. metadata +56 -2
@@ -0,0 +1,85 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Kerberos
6
+ module Model
7
+ # This class provides a representation of a Kerberos AuthorizationData data
8
+ # definition.
9
+ class AuthorizationData < Element
10
+ # @!attribute elements
11
+ # @return [Hash{Symbol => <Fixnum, String>}] The type of the authorization data
12
+ # @option [Fixnum] :type
13
+ # @option [String] :data
14
+ attr_accessor :elements
15
+
16
+ # Rex::Proto::Kerberos::Model::AuthorizationData decoding isn't supported
17
+ #
18
+ # @raise [NotImplementedError]
19
+ def decode(input)
20
+ raise ::NotImplementedError, 'Authorization Data decoding not supported'
21
+ end
22
+
23
+ # Encodes a Rex::Proto::Kerberos::Model::AuthorizationData into an ASN.1 String
24
+ #
25
+ # @return [String]
26
+ def encode
27
+ seqs = []
28
+ elements.each do |elem|
29
+ elems = []
30
+ type_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_type(elem[:type])], 0, :CONTEXT_SPECIFIC)
31
+ elems << type_asn1
32
+ data_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_data(elem[:data])], 1, :CONTEXT_SPECIFIC)
33
+ elems << data_asn1
34
+ seqs << OpenSSL::ASN1::Sequence.new(elems)
35
+ end
36
+
37
+ seq = OpenSSL::ASN1::Sequence.new(seqs)
38
+
39
+ seq.to_der
40
+ end
41
+
42
+ # Encrypts the Rex::Proto::Kerberos::Model::AuthorizationData
43
+ #
44
+ # @param etype [Fixnum] the crypto schema to encrypt
45
+ # @param key [String] the key to encrypt
46
+ # @return [String] the encrypted result
47
+ # @raise [NotImplementedError] if encryption schema isn't supported
48
+ def encrypt(etype, key)
49
+ data = self.encode
50
+
51
+ res = ''
52
+ case etype
53
+ when RC4_HMAC
54
+ res = encrypt_rc4_hmac(data, key, 5)
55
+ else
56
+ raise ::NotImplementedError, 'EncryptedData schema is not supported'
57
+ end
58
+
59
+ res
60
+ end
61
+
62
+
63
+ private
64
+
65
+ # Encodes the type
66
+ #
67
+ # @return [OpenSSL::ASN1::Integer]
68
+ def encode_type(type)
69
+ bn = OpenSSL::BN.new(type.to_s)
70
+ int = OpenSSL::ASN1::Integer.new(bn)
71
+
72
+ int
73
+ end
74
+
75
+ # Encodes the data
76
+ #
77
+ # @return [OpenSSL::ASN1::OctetString]
78
+ def encode_data(data)
79
+ OpenSSL::ASN1::OctetString.new(data)
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,59 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Kerberos
6
+ module Model
7
+ # This class provides a representation of a Kerberos Checksum definition.
8
+ class Checksum < Element
9
+
10
+ # @!attribute type
11
+ # @return [Fixnum] The algorithm used to generate the checksum
12
+ attr_accessor :type
13
+ # @!attribute checksum
14
+ # @return [String] The checksum itself
15
+ attr_accessor :checksum
16
+
17
+ # Rex::Proto::Kerberos::Model::Checksum decoding isn't supported
18
+ #
19
+ # @raise [NotImplementedError]
20
+ def decode(input)
21
+ raise ::NotImplementedError, 'Checksum decoding not supported'
22
+ end
23
+
24
+ # Encodes a Rex::Proto::Kerberos::Model::Checksum into an ASN.1 String
25
+ #
26
+ # @return [String]
27
+ def encode
28
+ elems = []
29
+ elems << OpenSSL::ASN1::ASN1Data.new([encode_type], 0, :CONTEXT_SPECIFIC)
30
+ elems << OpenSSL::ASN1::ASN1Data.new([encode_checksum], 1, :CONTEXT_SPECIFIC)
31
+
32
+ seq = OpenSSL::ASN1::Sequence.new(elems)
33
+
34
+ seq.to_der
35
+ end
36
+
37
+ private
38
+
39
+ # Encodes the type field
40
+ #
41
+ # @return [OpenSSL::ASN1::Integer]
42
+ def encode_type
43
+ bn = OpenSSL::BN.new(type.to_s)
44
+ int = OpenSSL::ASN1::Integer.new(bn)
45
+
46
+ int
47
+ end
48
+
49
+ # Encodes the checksum field
50
+ #
51
+ # @return [OpenSSL::ASN1::OctetString]
52
+ def encode_checksum
53
+ OpenSSL::ASN1::OctetString.new(checksum)
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,67 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Kerberos
6
+ module Model
7
+ # This class provides a representation of a principal, an asset (e.g., a
8
+ # workstation user or a network server) on a network.
9
+ class Element
10
+
11
+ include Rex::Proto::Kerberos::Crypto
12
+ include Rex::Proto::Kerberos::Model
13
+
14
+ def self.attr_accessor(*vars)
15
+ @attributes ||= []
16
+ @attributes.concat vars
17
+ super(*vars)
18
+ end
19
+
20
+ # Retrieves the element class fields
21
+ #
22
+ # @return [Array]
23
+ def self.attributes
24
+ @attributes
25
+ end
26
+
27
+ def self.decode(input)
28
+ elem = self.new
29
+ elem.decode(input)
30
+ end
31
+
32
+ def initialize(options = {})
33
+ self.class.attributes.each do |attr|
34
+ if options.has_key?(attr)
35
+ m = (attr.to_s + '=').to_sym
36
+ self.send(m, options[attr])
37
+ end
38
+ end
39
+ end
40
+
41
+ # Retrieves the element instance fields
42
+ #
43
+ # @return [Array]
44
+ def attributes
45
+ self.class.attributes
46
+ end
47
+
48
+ # Decodes the Rex::Proto::Kerberos::Model::Element from the input. This
49
+ # method has been designed to be overridden by subclasses.
50
+ #
51
+ # @raise [NoMethodError]
52
+ def decode(input)
53
+ raise ::NoMethodError, 'Method designed to be overridden'
54
+ end
55
+
56
+ # Encodes the Rex::Proto::Kerberos::Model::Element into an ASN.1 String. This
57
+ # method has been designed to be overridden by subclasses.
58
+ #
59
+ # @raise [NoMethodError]
60
+ def encode
61
+ raise ::NoMethodError, 'Method designed to be overridden'
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,215 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Kerberos
6
+ module Model
7
+ class EncKdcResponse < Element
8
+ # @!attribute key
9
+ # @return [Rex::Proto::Kerberos::Model::EncryptionKey] The session key
10
+ attr_accessor :key
11
+ # @!attribute last_req
12
+ # @return [Array<Rex::Proto::Kerberos::Model::LastRequest>] This field is returned by the KDC and specifies the time(s)
13
+ # of the last request by a principal
14
+ attr_accessor :last_req
15
+ # @!attribute nonce
16
+ # @return [Fixnum] random number
17
+ attr_accessor :nonce
18
+ # @!attribute key_expiration
19
+ # @return [Time] The key-expiration field is part of the response from the
20
+ # KDC and specifies the time that the client's secret key is due to expire
21
+ attr_accessor :key_expiration
22
+ # @!attribute flags
23
+ # @return [Fixnum] This field indicates which of various options were used or
24
+ # requested when the ticket was issued
25
+ attr_accessor :flags
26
+ # @!attribute auth_time
27
+ # @return [Time] the time of initial authentication for the named principal
28
+ attr_accessor :auth_time
29
+ # @!attribute start_time
30
+ # @return [Time] Specifies the time after which the ticket is valid
31
+ attr_accessor :start_time
32
+ # @!attribute end_time
33
+ # @return [Time] This field contains the time after which the ticket will
34
+ # not be honored (its expiration time)
35
+ attr_accessor :end_time
36
+ # @!attribute renew_till
37
+ # @return [Time] This field is only present in tickets that have the
38
+ # RENEWABLE flag set in the flags field. It indicates the maximum
39
+ # endtime that may be included in a renewal
40
+ attr_accessor :renew_till
41
+ # @!attribute srealm
42
+ # @return [String] The realm part of the server's principal identifier
43
+ attr_accessor :srealm
44
+ # @!attribute sname
45
+ # @return [Rex::Proto::Kerberos::Model::PrincipalName] The name part of the server's identity
46
+ attr_accessor :sname
47
+
48
+ # Decodes the Rex::Proto::Kerberos::Model::EncKdcResponse from an input
49
+ #
50
+ # @param input [String, OpenSSL::ASN1::ASN1Data] the input to decode from
51
+ # @return [self] if decoding succeeds
52
+ # @raise [RuntimeError] if decoding doesn't succeed
53
+ def decode(input)
54
+ case input
55
+ when String
56
+ decode_string(input)
57
+ when OpenSSL::ASN1::ASN1Data
58
+ decode_asn1(input)
59
+ else
60
+ raise ::RuntimeError, 'Failed to decode EncKdcResponse, invalid input'
61
+ end
62
+
63
+ self
64
+ end
65
+
66
+ # Rex::Proto::Kerberos::Model::EncKdcResponse encoding isn't supported
67
+ #
68
+ # @raise [NotImplementedError]
69
+ def encode
70
+ raise ::NotImplementedError, 'EncKdcResponse encoding not supported'
71
+ end
72
+
73
+ private
74
+
75
+ # Decodes a Rex::Proto::Kerberos::Model::EncKdcResponse from an String
76
+ #
77
+ # @param input [String] the input to decode from
78
+ def decode_string(input)
79
+ asn1 = OpenSSL::ASN1.decode(input)
80
+
81
+ decode_asn1(asn1)
82
+ end
83
+
84
+ # Decodes a Rex::Proto::Kerberos::Model::EncKdcResponse
85
+ #
86
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
87
+ # @raise [RuntimeError] if decoding doesn't succeed
88
+ def decode_asn1(input)
89
+ input.value[0].value.each do |val|
90
+ case val.tag
91
+ when 0
92
+ self.key = decode_key(val)
93
+ when 1
94
+ self.last_req = decode_last_req(val)
95
+ when 2
96
+ self.nonce = decode_nonce(val)
97
+ when 3
98
+ self.key_expiration = decode_key_expiration(val)
99
+ when 4
100
+ self.flags = decode_flags(val)
101
+ when 5
102
+ self.auth_time = decode_auth_time(val)
103
+ when 6
104
+ self.start_time = decode_start_time(val)
105
+ when 7
106
+ self.end_time = decode_end_time(val)
107
+ when 8
108
+ self.renew_till = decode_renew_till(val)
109
+ when 9
110
+ self.srealm = decode_srealm(val)
111
+ when 10
112
+ self.sname = decode_sname(val)
113
+ else
114
+ raise ::RuntimeError, 'Failed to decode ENC-KDC-RESPONSE SEQUENCE'
115
+ end
116
+ end
117
+ end
118
+
119
+ # Decodes the key from an OpenSSL::ASN1::ASN1Data
120
+ #
121
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
122
+ # @return [EncryptionKey]
123
+ def decode_key(input)
124
+ Rex::Proto::Kerberos::Model::EncryptionKey.decode(input.value[0])
125
+ end
126
+
127
+ # Decodes the last_req from an OpenSSL::ASN1::ASN1Data
128
+ #
129
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
130
+ # @return [Array<Rex::Proto::Kerberos::Model::LastRequest>]
131
+ def decode_last_req(input)
132
+ last_requests = []
133
+ input.value[0].value.each do |last_request|
134
+ last_requests << Rex::Proto::Kerberos::Model::LastRequest.decode(last_request)
135
+ end
136
+
137
+ last_requests
138
+ end
139
+
140
+ # Decodes the nonce field
141
+ #
142
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
143
+ # @return [Fixnum]
144
+ def decode_nonce(input)
145
+ input.value[0].value.to_i
146
+ end
147
+
148
+ # Decodes the key_expiration field
149
+ #
150
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
151
+ # @return [Time]
152
+ def decode_key_expiration(input)
153
+ input.value[0].value
154
+ end
155
+
156
+ # Decodes the flags field
157
+ #
158
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
159
+ # @return [Fixnum]
160
+ def decode_flags(input)
161
+ input.value[0].value.to_i
162
+ end
163
+
164
+ # Decodes the auth_time field
165
+ #
166
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
167
+ # @return [Time]
168
+ def decode_auth_time(input)
169
+ input.value[0].value
170
+ end
171
+
172
+ # Decodes the start_time field
173
+ #
174
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
175
+ # @return [Time]
176
+ def decode_start_time(input)
177
+ input.value[0].value
178
+ end
179
+
180
+ # Decodes the end_time field
181
+ #
182
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
183
+ # @return [Time]
184
+ def decode_end_time(input)
185
+ input.value[0].value
186
+ end
187
+
188
+ # Decodes the renew_till field
189
+ #
190
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
191
+ # @return [Time]
192
+ def decode_renew_till(input)
193
+ input.value[0].value
194
+ end
195
+
196
+ # Decodes the srealm field
197
+ #
198
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
199
+ # @return [String]
200
+ def decode_srealm(input)
201
+ input.value[0].value
202
+ end
203
+
204
+ # Decodes the sname field
205
+ #
206
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
207
+ # @return [Rex::Proto::Kerberos::Type::PrincipalName]
208
+ def decode_sname(input)
209
+ Rex::Proto::Kerberos::Model::PrincipalName.decode(input.value[0])
210
+ end
211
+ end
212
+ end
213
+ end
214
+ end
215
+ end
@@ -0,0 +1,171 @@
1
+ # -*- coding: binary -*-
2
+
3
+ module Rex
4
+ module Proto
5
+ module Kerberos
6
+ module Model
7
+ # This class provides a representation of an encrypted message.
8
+ class EncryptedData < Element
9
+ # @!attribute name_type
10
+ # @return [Fixnum] The encryption algorithm
11
+ attr_accessor :etype
12
+ # @!attribute kvno
13
+ # @return [Fixnum] The version number of the key
14
+ attr_accessor :kvno
15
+ # @!attribute cipher
16
+ # @return [String] The enciphered text
17
+ attr_accessor :cipher
18
+
19
+ # Decodes a Rex::Proto::Kerberos::Model::EncryptedData
20
+ #
21
+ # @param input [String, OpenSSL::ASN1::Sequence] the input to decode from
22
+ # @return [self]
23
+ # @raise [RuntimeError] if decoding doesn't succeed
24
+ def decode(input)
25
+ case input
26
+ when String
27
+ decode_string(input)
28
+ when OpenSSL::ASN1::Sequence
29
+ decode_asn1(input)
30
+ else
31
+ raise ::RuntimeError, 'Failed to decode EncryptedData Name, invalid input'
32
+ end
33
+
34
+ self
35
+ end
36
+
37
+ # Encodes a Rex::Proto::Kerberos::Model::EncryptedData into an ASN.1 String
38
+ #
39
+ # @return [String]
40
+ def encode
41
+ elems = []
42
+ etype_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_etype], 0, :CONTEXT_SPECIFIC)
43
+ elems << etype_asn1
44
+
45
+ if kvno
46
+ kvno_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_kvno], 1, :CONTEXT_SPECIFIC)
47
+ elems << kvno_asn1
48
+ end
49
+
50
+ cipher_asn1 = OpenSSL::ASN1::ASN1Data.new([encode_cipher], 2, :CONTEXT_SPECIFIC)
51
+ elems << cipher_asn1
52
+
53
+ seq = OpenSSL::ASN1::Sequence.new(elems)
54
+
55
+ seq.to_der
56
+ end
57
+
58
+ # Decrypts the cipher with etype encryption schema
59
+ #
60
+ # @param key [String] the key to decrypt
61
+ # @param msg_type [Fixnum] the message type
62
+ # @return [String] the decrypted `cipher`
63
+ # @raise [RuntimeError] if decryption doesn't succeed
64
+ # @raise [NotImplementedError] if encryption isn't supported
65
+ def decrypt(key, msg_type)
66
+ if cipher.nil? || cipher.empty?
67
+ return ''
68
+ end
69
+
70
+ res = ''
71
+ case etype
72
+ when RC4_HMAC
73
+ res = decrypt_rc4_hmac(cipher, key, msg_type)
74
+ raise ::RuntimeError, 'EncryptedData failed to decrypt' if res.length < 8
75
+ res = res[8, res.length - 1]
76
+ else
77
+ raise ::NotImplementedError, 'EncryptedData schema is not supported'
78
+ end
79
+
80
+ res
81
+ end
82
+
83
+ private
84
+
85
+ # Encodes the etype
86
+ #
87
+ # @return [OpenSSL::ASN1::Integer]
88
+ def encode_etype
89
+ bn = OpenSSL::BN.new(etype.to_s)
90
+ int = OpenSSL::ASN1::Integer.new(bn)
91
+
92
+ int
93
+ end
94
+
95
+ # Encodes the kvno
96
+ #
97
+ # @raise [RuntimeError]
98
+ def encode_kvno
99
+ bn = OpenSSL::BN.new(kvno.to_s)
100
+ int = OpenSSL::ASN1::Integer.new(bn)
101
+
102
+ int
103
+ end
104
+
105
+ # Encodes the cipher
106
+ #
107
+ # @return [OpenSSL::ASN1::OctetString]
108
+ def encode_cipher
109
+ OpenSSL::ASN1::OctetString.new(cipher)
110
+ end
111
+
112
+ # Decodes a Rex::Proto::Kerberos::Model::EncryptedData from an String
113
+ #
114
+ # @param input [String] the input to decode from
115
+ def decode_string(input)
116
+ asn1 = OpenSSL::ASN1.decode(input)
117
+
118
+ decode_asn1(asn1)
119
+ end
120
+
121
+ # Decodes a Rex::Proto::Kerberos::Model::EncryptedData from an
122
+ # OpenSSL::ASN1::Sequence
123
+ #
124
+ # @param input [OpenSSL::ASN1::Sequence] the input to decode from
125
+ # @raise [RuntimeError] if decoding doesn't succeed
126
+ def decode_asn1(input)
127
+ seq_values = input.value
128
+
129
+ seq_values.each do |val|
130
+ case val.tag
131
+ when 0
132
+ self.etype = decode_etype(val)
133
+ when 1
134
+ self.kvno = decode_kvno(val)
135
+ when 2
136
+ self.cipher = decode_cipher(val)
137
+ else
138
+ raise ::RuntimeError, 'Failed to decode EncryptedData SEQUENCE'
139
+ end
140
+ end
141
+ end
142
+
143
+ # Decodes the etype from an OpenSSL::ASN1::ASN1Data
144
+ #
145
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
146
+ # @return [Fixnum]
147
+ def decode_etype(input)
148
+ input.value[0].value.to_i
149
+ end
150
+
151
+ # Decodes the kvno from an OpenSSL::ASN1::ASN1Data
152
+ #
153
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
154
+ # @return [Fixnum]
155
+ def decode_kvno(input)
156
+ input.value[0].value.to_i
157
+ end
158
+
159
+ # Decodes the cipher from an OpenSSL::ASN1::ASN1Data
160
+ #
161
+ # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from
162
+ # @return [Sting]
163
+ def decode_cipher(input)
164
+ input.value[0].value
165
+ end
166
+
167
+ end
168
+ end
169
+ end
170
+ end
171
+ end