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.
- checksums.yaml +4 -4
- data/lib/rex/exploitation/egghunter.rb +4 -6
- data/lib/rex/exploitation/powershell/psh_methods.rb +9 -0
- data/lib/rex/java/serialization.rb +2 -1
- data/lib/rex/java/serialization/builder.rb +94 -0
- data/lib/rex/java/serialization/model.rb +29 -18
- data/lib/rex/java/serialization/model/annotation.rb +2 -2
- data/lib/rex/java/serialization/model/field.rb +2 -2
- data/lib/rex/java/serialization/model/new_array.rb +8 -3
- data/lib/rex/java/serialization/model/new_class_desc.rb +3 -3
- data/lib/rex/java/serialization/model/new_enum.rb +4 -4
- data/lib/rex/java/serialization/model/new_object.rb +17 -10
- data/lib/rex/ole/direntry.rb +1 -1
- data/lib/rex/ole/samples/create_ole.rb +0 -0
- data/lib/rex/ole/samples/dir.rb +0 -0
- data/lib/rex/ole/samples/dump_stream.rb +0 -0
- data/lib/rex/ole/samples/ole_info.rb +0 -0
- data/lib/rex/parser/foundstone_nokogiri.rb +1 -1
- data/lib/rex/parser/fs/ntfs.rb +252 -0
- data/lib/rex/parser/openvas_nokogiri.rb +2 -0
- data/lib/rex/payloads/win32/kernel.rb +3 -3
- data/lib/rex/post/meterpreter/client_core.rb +172 -64
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +3 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +12 -10
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/api_constants.rb +64 -37
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/dll.rb +8 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/ui.rb +15 -3
- data/lib/rex/post/meterpreter/packet.rb +41 -38
- data/lib/rex/post/meterpreter/packet_dispatcher.rb +7 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +17 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +11 -4
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/ui.rb +1 -1
- data/lib/rex/proto.rb +2 -0
- data/lib/rex/proto/acpp.rb +17 -0
- data/lib/rex/proto/acpp/client.rb +29 -0
- data/lib/rex/proto/acpp/message.rb +183 -0
- data/lib/rex/proto/http/client.rb +1 -2
- data/lib/rex/proto/iax2/call.rb +22 -3
- data/lib/rex/proto/iax2/client.rb +1 -0
- data/lib/rex/proto/kerberos.rb +13 -0
- data/lib/rex/proto/kerberos/client.rb +213 -0
- data/lib/rex/proto/kerberos/credential_cache.rb +19 -0
- data/lib/rex/proto/kerberos/credential_cache/cache.rb +81 -0
- data/lib/rex/proto/kerberos/credential_cache/credential.rb +151 -0
- data/lib/rex/proto/kerberos/credential_cache/element.rb +49 -0
- data/lib/rex/proto/kerberos/credential_cache/key_block.rb +62 -0
- data/lib/rex/proto/kerberos/credential_cache/principal.rb +70 -0
- data/lib/rex/proto/kerberos/credential_cache/time.rb +69 -0
- data/lib/rex/proto/kerberos/crypto.rb +21 -0
- data/lib/rex/proto/kerberos/crypto/rc4_hmac.rb +65 -0
- data/lib/rex/proto/kerberos/crypto/rsa_md5.rb +15 -0
- data/lib/rex/proto/kerberos/model.rb +133 -0
- data/lib/rex/proto/kerberos/model/ap_req.rb +98 -0
- data/lib/rex/proto/kerberos/model/authenticator.rb +143 -0
- data/lib/rex/proto/kerberos/model/authorization_data.rb +85 -0
- data/lib/rex/proto/kerberos/model/checksum.rb +59 -0
- data/lib/rex/proto/kerberos/model/element.rb +67 -0
- data/lib/rex/proto/kerberos/model/enc_kdc_response.rb +215 -0
- data/lib/rex/proto/kerberos/model/encrypted_data.rb +171 -0
- data/lib/rex/proto/kerberos/model/encryption_key.rb +106 -0
- data/lib/rex/proto/kerberos/model/kdc_request.rb +166 -0
- data/lib/rex/proto/kerberos/model/kdc_request_body.rb +315 -0
- data/lib/rex/proto/kerberos/model/kdc_response.rb +141 -0
- data/lib/rex/proto/kerberos/model/krb_error.rb +219 -0
- data/lib/rex/proto/kerberos/model/last_request.rb +82 -0
- data/lib/rex/proto/kerberos/model/pre_auth_data.rb +104 -0
- data/lib/rex/proto/kerberos/model/pre_auth_enc_time_stamp.rb +126 -0
- data/lib/rex/proto/kerberos/model/pre_auth_pac_request.rb +81 -0
- data/lib/rex/proto/kerberos/model/principal_name.rb +116 -0
- data/lib/rex/proto/kerberos/model/ticket.rb +151 -0
- data/lib/rex/proto/kerberos/pac.rb +36 -0
- data/lib/rex/proto/kerberos/pac/client_info.rb +53 -0
- data/lib/rex/proto/kerberos/pac/element.rb +52 -0
- data/lib/rex/proto/kerberos/pac/logon_info.rb +566 -0
- data/lib/rex/proto/kerberos/pac/priv_svr_checksum.rb +29 -0
- data/lib/rex/proto/kerberos/pac/server_checksum.rb +30 -0
- data/lib/rex/proto/kerberos/pac/type.rb +121 -0
- data/lib/rex/proto/rmi.rb +7 -0
- data/lib/rex/proto/rmi/model.rb +31 -0
- data/lib/rex/proto/rmi/model/call.rb +60 -0
- data/lib/rex/proto/rmi/model/continuation.rb +76 -0
- data/lib/rex/proto/rmi/model/dgc_ack.rb +62 -0
- data/lib/rex/proto/rmi/model/element.rb +143 -0
- data/lib/rex/proto/rmi/model/output_header.rb +86 -0
- data/lib/rex/proto/rmi/model/ping.rb +41 -0
- data/lib/rex/proto/rmi/model/ping_ack.rb +41 -0
- data/lib/rex/proto/rmi/model/protocol_ack.rb +100 -0
- data/lib/rex/proto/rmi/model/return_data.rb +60 -0
- data/lib/rex/socket.rb +9 -1
- data/lib/rex/socket/tcp_server.rb +3 -0
- data/lib/rex/ui/text/dispatcher_shell.rb +4 -4
- data/lib/rex/ui/text/output/tee.rb +2 -0
- data/lib/rex/zip/samples/comment.rb +0 -0
- data/lib/rex/zip/samples/mkwar.rb +0 -0
- data/lib/rex/zip/samples/mkzip.rb +0 -0
- data/lib/rex/zip/samples/recursive.rb +0 -0
- data/rex.gemspec +1 -1
- metadata +56 -2
|
@@ -0,0 +1,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
|