Add support for Authenticator encoding
parent
dde45a7f53
commit
0f55a98450
|
@ -14,6 +14,7 @@ module Rex
|
|||
TGS_REP = 13
|
||||
KRB_ERROR = 30
|
||||
TICKET = 1
|
||||
AUTHENTICATOR = 2
|
||||
|
||||
# Encryption Message Id's
|
||||
ENC_KDC_REQUEST_BODY = 10
|
||||
|
@ -76,8 +77,9 @@ require 'rex/proto/kerberos/model/pre_auth_data'
|
|||
require 'rex/proto/kerberos/model/kdc_request_body'
|
||||
require 'rex/proto/kerberos/model/kdc_request'
|
||||
require 'rex/proto/kerberos/model/krb_error'
|
||||
require 'rex/proto/kerberos/model/ticket'
|
||||
require 'rex/proto/kerberos/model/encryption_key'
|
||||
require 'rex/proto/kerberos/model/authenticator'
|
||||
require 'rex/proto/kerberos/model/ticket'
|
||||
require 'rex/proto/kerberos/model/last_request'
|
||||
require 'rex/proto/kerberos/model/enc_kdc_response'
|
||||
require 'rex/proto/kerberos/model/kdc_response'
|
||||
|
|
|
@ -0,0 +1,109 @@
|
|||
# -*- coding: binary -*-
|
||||
|
||||
module Rex
|
||||
module Proto
|
||||
module Kerberos
|
||||
module Model
|
||||
class Authenticator < Element
|
||||
# @!attribute vno
|
||||
# @return [Fixnum] The authenticator version number
|
||||
attr_accessor :vno
|
||||
# @!attribute crealm
|
||||
# @return [String] The realm in which the client is registered
|
||||
attr_accessor :crealm
|
||||
# @!attribute cname
|
||||
# @return [Rex::Proto::Kerberos::Model::PrincipalName] The name part of the client's principal
|
||||
# identifier
|
||||
attr_accessor :cname
|
||||
# @!attribute checksum
|
||||
# @return [Rex::Proto::Kerberos::Model::Checksum]
|
||||
attr_accessor :checksum
|
||||
# @!attribute cusec
|
||||
# @return [Fixnum] The microsecond part of the client's timestamp
|
||||
attr_accessor :cusec
|
||||
# @!attribute ctime
|
||||
# @return [Time] The current time of the client's host
|
||||
attr_accessor :ctime
|
||||
# @!attribute subkey
|
||||
# @return [Rex::Proto::Kerberos::Model::EncryptionKey] the client's choice for an encryption
|
||||
# key which is to be used to protect this specific application session
|
||||
attr_accessor :subkey
|
||||
|
||||
def decode(input)
|
||||
raise ::RuntimeError, 'Authenticator decoding not supported'
|
||||
end
|
||||
|
||||
def encode
|
||||
elems = []
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_vno], 0, :CONTEXT_SPECIFIC)
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_crealm], 1, :CONTEXT_SPECIFIC)
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_cname], 2, :CONTEXT_SPECIFIC)
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_checksum], 3, :CONTEXT_SPECIFIC) if checksum
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_cusec], 4, :CONTEXT_SPECIFIC)
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_ctime], 5, :CONTEXT_SPECIFIC)
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_subkey], 6, :CONTEXT_SPECIFIC) if subkey
|
||||
|
||||
seq = OpenSSL::ASN1::Sequence.new(elems)
|
||||
seq_asn1 = OpenSSL::ASN1::ASN1Data.new([seq], AUTHENTICATOR, :APPLICATION)
|
||||
|
||||
seq_asn1.to_der
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Encodes the vno
|
||||
#
|
||||
# @return [OpenSSL::ASN1::Integer]
|
||||
def encode_vno
|
||||
bn = OpenSSL::BN.new(vno)
|
||||
int = OpenSSL::ASN1::Integer(bn)
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Encodes the crealm
|
||||
#
|
||||
# @return [OpenSSL::ASN1::GeneralString]
|
||||
def encode_crealm
|
||||
OpenSSL::ASN1::GeneralString.new(crealm)
|
||||
end
|
||||
|
||||
# Encodes the cname
|
||||
#
|
||||
# @return [String]
|
||||
def encode_cname
|
||||
cname.encode
|
||||
end
|
||||
|
||||
# Encodes the checksum
|
||||
#
|
||||
# @return [String]
|
||||
def encode_checksum
|
||||
checksum.encode
|
||||
end
|
||||
|
||||
# Encodes the cusec
|
||||
#
|
||||
# @return [OpenSSL::ASN1::Integer]
|
||||
def encode_cusec
|
||||
bn = OpenSSL::BN.new(cusec)
|
||||
int = OpenSSL::ASN1::Integer(bn)
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Encodes the ctime field
|
||||
#
|
||||
# @return [OpenSSL::ASN1::GeneralizedTime]
|
||||
def encode_ctime
|
||||
OpenSSL::ASN1::GeneralizedTime.new(ctime)
|
||||
end
|
||||
|
||||
def encode_subkey
|
||||
subkey.encode
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -32,8 +32,17 @@ module Rex
|
|||
self
|
||||
end
|
||||
|
||||
# Encodes a Rex::Proto::Kerberos::Model::EncryptionKey into an
|
||||
# ASN.1 String
|
||||
#
|
||||
# @return [String]
|
||||
def encode
|
||||
raise ::RuntimeError, 'EncryptionKey encoding not supported'
|
||||
elems = []
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_type], 0, :CONTEXT_SPECIFIC)
|
||||
elems << OpenSSL::ASN1::ASN1Data.new([encode_value], 1, :CONTEXT_SPECIFIC)
|
||||
seq = OpenSSL::ASN1::Sequence.new(elems)
|
||||
|
||||
seq.to_der
|
||||
end
|
||||
|
||||
private
|
||||
|
@ -72,6 +81,23 @@ module Rex
|
|||
def decode_value(input)
|
||||
input.value[0].value
|
||||
end
|
||||
|
||||
# Encodes the type field
|
||||
#
|
||||
# @return [OpenSSL::ASN1::Integer]
|
||||
def encode_type
|
||||
bn = OpenSSL::BN.new(type)
|
||||
int = OpenSSL::ASN1::Integer(bn)
|
||||
|
||||
int
|
||||
end
|
||||
|
||||
# Encodes the value field
|
||||
#
|
||||
# @return [OpenSSL::ASN1::OctetString]
|
||||
def encode_value
|
||||
OpenSSL::ASN1::OctetString.new(value)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
# -*- coding:binary -*-
|
||||
require 'spec_helper'
|
||||
|
||||
require 'rex/proto/kerberos'
|
||||
|
||||
describe Rex::Proto::Kerberos::Model::Authenticator do
|
||||
|
||||
subject(:authenticator) do
|
||||
described_class.new
|
||||
end
|
||||
|
||||
let(:rsa_md5) { 7 }
|
||||
|
||||
let(:sample) do
|
||||
"\x62\x7c\x30\x7a\xa0\x03\x02\x01\x05\xa1\x0c\x1b\x0a\x44\x45\x4d\x4f\x2e\x4c\x4f" +
|
||||
"\x43\x41\x4c\xa2\x11\x30\x0f\xa0\x03\x02\x01\x01\xa1\x08\x30\x06\x1b\x04\x6a\x75" +
|
||||
"\x61\x6e\xa3\x1b\x30\x19\xa0\x03\x02\x01\x07\xa1\x12\x04\x10\x9e\xf0\x84\xd6\x81" +
|
||||
"\xe5\x16\x02\x32\xb1\xc3\x4e\xad\x83\x1d\x43\xa4\x05\x02\x03\x0a\xf8\x98\xa5\x11" +
|
||||
"\x18\x0f\x32\x30\x31\x34\x31\x32\x31\x36\x32\x32\x35\x30\x34\x36\x5a\xa6\x1b\x30" +
|
||||
"\x19\xa0\x03\x02\x01\x17\xa1\x12\x04\x10\x7d\x63\xdd\x79\x73\x67\xce\x86\xbb\x5f" +
|
||||
"\x2b\x8a\xba\x58\xfd\x6e"
|
||||
end
|
||||
|
||||
describe "#encode" do
|
||||
it "encodes Rex::Proto::Kerberos::Model::Authenticator correctly" do
|
||||
checksum = Rex::Proto::Kerberos::Model::Checksum.new(
|
||||
type: rsa_md5,
|
||||
checksum: "\x9e\xf0\x84\xd6\x81\xe5\x16\x02\x32\xb1\xc3\x4e\xad\x83\x1d\x43"
|
||||
)
|
||||
|
||||
cname = Rex::Proto::Kerberos::Model::PrincipalName.new(
|
||||
name_type: 1,
|
||||
name_string: ['juan']
|
||||
)
|
||||
|
||||
enc_key = Rex::Proto::Kerberos::Model::EncryptionKey.new(
|
||||
type: 23,
|
||||
value: "\x7d\x63\xdd\x79\x73\x67\xce\x86\xbb\x5f\x2b\x8a\xba\x58\xfd\x6e"
|
||||
)
|
||||
|
||||
authenticator.vno = 5
|
||||
authenticator.crealm = 'DEMO.LOCAL'
|
||||
authenticator.cname = cname
|
||||
authenticator.checksum = checksum
|
||||
authenticator.cusec = 719000
|
||||
authenticator.ctime = Time.at(1418770246)
|
||||
authenticator.subkey = enc_key
|
||||
|
||||
expect(authenticator.encode).to eq(sample)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue