diff --git a/lib/rex/proto/kerberos/model/message/kdc_response.rb b/lib/rex/proto/kerberos/model/message/kdc_response.rb index 21611d948d..81c36b3f1a 100644 --- a/lib/rex/proto/kerberos/model/message/kdc_response.rb +++ b/lib/rex/proto/kerberos/model/message/kdc_response.rb @@ -12,10 +12,108 @@ module Rex # @!attribute msg_type # @return [Fixnum] The type of a protocol message attr_accessor :msg_type - # @!attribute pa_data - # @return [Rex::Proto::Kerberos::Model::Field::PreAuthData] Authentication information which may - # be needed before credentials can be issued or decrypted - attr_accessor :pa_data + # @!attribute crealm + # @return [String] The realm part of the client's principal identifier + attr_accessor :crealm + # @!attribute cname + # @return [Rex::Proto::Kerberos::Type::PrincipalName] The name part of the client's principal identifier + attr_accessor :cname + # @!attribute ticket + # @return [Rex::Proto::Kerberos::Type::PrincipalName] The name part of the client's principal identifier + attr_accessor :ticket + # @!attribute enc_auth_data + # @return [Rex::Proto::Kerberos::Type::EncryptedData] The newly issued ticket + attr_accessor :enc_part + + # Decodes the Rex::Proto::Kerberos::Model::Message::KrbError from an input + # + # @param input [String, OpenSSL::ASN1::ASN1Data] the input to decode from + # @return [self] if decoding succeeds + # @raise [RuntimeError] if decoding doesn't succeed + def decode(input) + case input + when String + decode_string(input) + when OpenSSL::ASN1::ASN1Data + decode_asn1(input) + else + raise ::RuntimeError, 'Failed to decode KRB Error, invalid input' + end + + self + end + + def encode + raise ::RuntimeError, 'KrbError encoding not supported' + end + + private + + # Decodes a Rex::Proto::Kerberos::Model::Message::KrbError from an String + # + # @param input [String] the input to decode from + def decode_string(input) + asn1 = OpenSSL::ASN1.decode(input) + + decode_asn1(asn1) + end + + # Decodes a Rex::Proto::Kerberos::Model::Message::KrbError + # + # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from + # @raise [RuntimeError] if decoding doesn't succeed + def decode_asn1(input) + input.value[0].value.each do |val| + case val.tag + when 0 + self.pvno = decode_pvno(val) + when 1 + self.msg_type = decode_msg_type(val) + when 3 + self.crealm = decode_crealm(val) + when 4 + self.cname = decode_cname(val) + when 5 + self.ticket = decode_ticket(val) + when 6 + self.enc_part = decode_enc_part(val) + else + raise ::RuntimeError, 'Failed to decode KDC-RESPONSE SEQUENCE' + end + end + end + + # Decodes the pvno from an OpenSSL::ASN1::ASN1Data + # + # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from + # @return [Fixnum] + def decode_pvno(input) + input.value[0].value.to_i + end + + # Decodes the msg_type from an OpenSSL::ASN1::ASN1Data + # + # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from + # @return [Fixnum] + def decode_msg_type(input) + input.value[0].value.to_i + end + + # Decodes the crealm field + # + # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from + # @return [String] + def decode_crealm(input) + input.value[0].value + end + + # Decodes the cname field + # + # @param input [OpenSSL::ASN1::ASN1Data] the input to decode from + # @return [Rex::Proto::Kerberos::Type::PrincipalName] + def decode_cname(input) + Rex::Proto::Kerberos::Model::Type::PrincipalName.decode(input.value[0]) + end end end end