예제 #1
0
    def add_tgs(self,
                tgs_rep,
                enc_tgs_rep_part,
                override_pp=False):  #from AS_REP
        """
		Creates credential object from the TGS and adds to the ccache file
		The TGS is the native representation of the asn1 encoded TGS_REP data when the user requests a tgs to a specific service principal with a valid TGT

		This function doesn't do decryption of the encrypted part of the tgs_rep object, it is expected that the decrypted XXX is supplied in enc_as_rep_part

		override_pp: bool to determine if client principal should be used as the primary principal for the ccache file
		"""
        c = Credential()
        c.client = CCACHEPrincipal.from_asn1(tgs_rep['cname'],
                                             tgs_rep['crealm'])
        if override_pp == True:
            self.primary_principal = c.client
        c.server = CCACHEPrincipal.from_asn1(enc_tgs_rep_part['sname'],
                                             enc_tgs_rep_part['srealm'])
        c.time = Times.from_asn1(enc_tgs_rep_part)
        c.key = Keyblock.from_asn1(enc_tgs_rep_part['key'])
        c.is_skey = 0  #not sure!

        c.tktflags = TicketFlags(enc_tgs_rep_part['flags']).cast(
            core.IntegerBitString).native
        c.num_address = 0
        c.num_authdata = 0
        c.ticket = CCACHEOctetString.from_asn1(
            Ticket(tgs_rep['ticket']).dump())
        c.second_ticket = CCACHEOctetString.empty()

        self.credentials.append(c)
예제 #2
0
파일: aioclient.py 프로젝트: naver/PyCQuery
    def construct_apreq_from_ticket(ticket_data,
                                    sessionkey,
                                    crealm,
                                    cname,
                                    flags=None,
                                    seq_number=0,
                                    ap_opts=[],
                                    cb_data=None):
        """
		ticket: bytes of Ticket
		"""
        now = datetime.datetime.now(datetime.timezone.utc)
        authenticator_data = {}
        authenticator_data['authenticator-vno'] = krb5_pvno
        authenticator_data['crealm'] = Realm(crealm)
        authenticator_data['cname'] = PrincipalName({
            'name-type':
            NAME_TYPE.PRINCIPAL.value,
            'name-string': [cname]
        })
        authenticator_data['cusec'] = now.microsecond
        authenticator_data['ctime'] = now.replace(microsecond=0)
        if flags is not None:
            ac = AuthenticatorChecksum()
            ac.flags = flags
            ac.channel_binding = cb_data
            if cb_data is None:
                ac.channel_binding = b'\x00' * 16

            chksum = {}
            chksum['cksumtype'] = 0x8003
            chksum['checksum'] = ac.to_bytes()

            authenticator_data['cksum'] = Checksum(chksum)
            authenticator_data['seq-number'] = seq_number

        cipher = _enctype_table[sessionkey.enctype]
        authenticator_data_enc = cipher.encrypt(
            sessionkey, 11,
            Authenticator(authenticator_data).dump(), None)

        ap_req = {}
        ap_req['pvno'] = krb5_pvno
        ap_req['msg-type'] = MESSAGE_TYPE.KRB_AP_REQ.value
        ap_req['ticket'] = Ticket.load(ticket_data)
        ap_req['ap-options'] = APOptions(set(ap_opts))
        ap_req['authenticator'] = EncryptedData({
            'etype':
            sessionkey.enctype,
            'cipher':
            authenticator_data_enc
        })

        return AP_REQ(ap_req).dump()
예제 #3
0
    def get_hashes(self, all_hashes=False):
        """
		Returns a list of hashes in hashcat-firendly format for tickets with encryption type 23 (which is RC4)
		all_hashes: overrides the encryption type filtering and returns hash for all tickets

		"""
        hashes = []
        for cred in self.credentials:
            res = Ticket.load(cred.ticket.to_asn1()).native
            if int(res['enc-part']['etype']) == 23 or all_hashes == True:
                hashes.append(cred.to_hash())

        return hashes
예제 #4
0
파일: aioclient.py 프로젝트: naver/PyCQuery
    def construct_apreq(self,
                        tgs,
                        encTGSRepPart,
                        sessionkey,
                        flags=None,
                        seq_number=0,
                        ap_opts=[],
                        cb_data=None):
        now = datetime.datetime.now(datetime.timezone.utc)
        authenticator_data = {}
        authenticator_data['authenticator-vno'] = krb5_pvno
        authenticator_data['crealm'] = Realm(self.kerberos_TGT['crealm'])
        authenticator_data['cname'] = self.kerberos_TGT['cname']
        authenticator_data['cusec'] = now.microsecond
        authenticator_data['ctime'] = now.replace(microsecond=0)
        if flags is not None:
            ac = AuthenticatorChecksum()
            ac.flags = flags

            ac.channel_binding = cb_data
            if cb_data is None:
                ac.channel_binding = b'\x00' * 16

            chksum = {}
            chksum['cksumtype'] = 0x8003
            chksum['checksum'] = ac.to_bytes()

            authenticator_data['cksum'] = Checksum(chksum)
            authenticator_data['seq-number'] = seq_number

        cipher = _enctype_table[encTGSRepPart['key']['keytype']]
        authenticator_data_enc = cipher.encrypt(
            sessionkey, 11,
            Authenticator(authenticator_data).dump(), None)

        ap_req = {}
        ap_req['pvno'] = krb5_pvno
        ap_req['msg-type'] = MESSAGE_TYPE.KRB_AP_REQ.value
        ap_req['ticket'] = Ticket(tgs['ticket'])
        ap_req['ap-options'] = APOptions(set(ap_opts))
        ap_req['authenticator'] = EncryptedData({
            'etype':
            self.kerberos_cipher_type,
            'cipher':
            authenticator_data_enc
        })

        return AP_REQ(ap_req).dump()
예제 #5
0
    def add_kirbi(self, krbcred, override_pp=True, include_expired=False):
        c = Credential()
        enc_credinfo = EncKrbCredPart.load(
            krbcred['enc-part']['cipher']).native
        ticket_info = enc_credinfo['ticket-info'][0]
        """
		if ticket_info['endtime'] < datetime.datetime.now(datetime.timezone.utc):
			if include_expired == True:
				logging.debug('This ticket has most likely expired, but include_expired is forcing me to add it to cache! This can cause problems!')
			else:
				logging.debug('This ticket has most likely expired, skipping')
				return
		"""

        c.client = CCACHEPrincipal.from_asn1(ticket_info['pname'],
                                             ticket_info['prealm'])
        if override_pp == True:
            self.primary_principal = c.client

        #yaaaaay 4 additional weirdness!!!!
        #if sname name-string contains a realm as well htne impacket will crash miserably :(
        if len(ticket_info['sname']['name-string']
               ) > 2 and ticket_info['sname']['name-string'][-1].upper(
               ) == ticket_info['srealm'].upper():
            logger.debug('SNAME contains the realm as well, trimming it')
            t = ticket_info['sname']
            t['name-string'] = t['name-string'][:-1]
            c.server = CCACHEPrincipal.from_asn1(t, ticket_info['srealm'])
        else:
            c.server = CCACHEPrincipal.from_asn1(ticket_info['sname'],
                                                 ticket_info['srealm'])

        c.time = Times.from_asn1(ticket_info)
        c.key = Keyblock.from_asn1(ticket_info['key'])
        c.is_skey = 0  #not sure!

        c.tktflags = TicketFlags(ticket_info['flags']).cast(
            core.IntegerBitString).native
        c.num_address = 0
        c.num_authdata = 0
        c.ticket = CCACHEOctetString.from_asn1(
            Ticket(krbcred['tickets']
                   [0]).dump())  #kirbi only stores one ticket per file
        c.second_ticket = CCACHEOctetString.empty()

        self.credentials.append(c)
예제 #6
0
    def to_tgs(self):
        """
		Returns the native format of an AS_REP message and the sessionkey in EncryptionKey native format
		"""
        enc_part = EncryptedData({'etype': 1, 'cipher': b''})

        tgt_rep = {}
        tgt_rep['pvno'] = krb5_pvno
        tgt_rep['msg-type'] = MESSAGE_TYPE.KRB_AS_REP.value
        tgt_rep['crealm'] = self.server.realm.to_string()
        tgt_rep['cname'] = self.client.to_asn1()[0]
        tgt_rep['ticket'] = Ticket.load(self.ticket.to_asn1()).native
        tgt_rep['enc-part'] = enc_part.native

        t = EncryptionKey(self.key.to_asn1()).native

        return tgt_rep, t
예제 #7
0
    def to_kirbi(self):
        filename = '%s@%s_%s' % (
            self.client.to_string(), self.server.to_string(),
            hashlib.sha1(self.ticket.to_asn1()).hexdigest()[:8])
        krbcredinfo = {}
        krbcredinfo['key'] = EncryptionKey(self.key.to_asn1())
        krbcredinfo['prealm'] = self.client.realm.to_string()
        krbcredinfo['pname'] = self.client.to_asn1()[0]
        krbcredinfo['flags'] = core.IntegerBitString(
            self.tktflags).cast(TicketFlags)
        if self.time.authtime != 0:  #this parameter is not mandatory, and most of the time not present
            krbcredinfo['authtime'] = datetime.datetime.fromtimestamp(
                self.time.authtime, datetime.timezone.utc)
        if self.time.starttime != 0:
            krbcredinfo['starttime'] = datetime.datetime.fromtimestamp(
                self.time.starttime, datetime.timezone.utc)
        if self.time.endtime != 0:
            krbcredinfo['endtime'] = datetime.datetime.fromtimestamp(
                self.time.endtime, datetime.timezone.utc)
        if self.time.renew_till != 0:  #this parameter is not mandatory, and sometimes it's not present
            krbcredinfo['renew-till'] = datetime.datetime.fromtimestamp(
                self.time.authtime, datetime.timezone.utc)
        krbcredinfo['srealm'] = self.server.realm.to_string()
        krbcredinfo['sname'] = self.server.to_asn1()[0]

        enc_krbcred = {}
        enc_krbcred['ticket-info'] = [KrbCredInfo(krbcredinfo)]

        krbcred = {}
        krbcred['pvno'] = krb5_pvno
        krbcred['msg-type'] = MESSAGE_TYPE.KRB_CRED.value
        krbcred['tickets'] = [Ticket.load(self.ticket.to_asn1())]
        krbcred['enc-part'] = EncryptedData({
            'etype':
            EncryptionType.NULL.value,
            'cipher':
            EncKrbCredPart(enc_krbcred).dump()
        })

        kirbi = KRBCRED(krbcred)
        return kirbi, filename
예제 #8
0
 def to_hash(self):
     res = Ticket.load(self.ticket.to_asn1()).native
     tgs_encryption_type = int(res['enc-part']['etype'])
     t = len(res['sname']['name-string'])
     if t == 1:
         tgs_name_string = res['sname']['name-string'][0]
     else:
         tgs_name_string = res['sname']['name-string'][1]
     tgs_realm = res['realm']
     if tgs_encryption_type == EncryptionType.AES256_CTS_HMAC_SHA1_96.value:
         tgs_checksum = res['enc-part']['cipher'][-12:]
         tgs_encrypted_data2 = res['enc-part']['cipher'][:-12]
         return '$krb5tgs$%s$%s$%s$%s$%s' % (
             tgs_encryption_type, tgs_name_string, tgs_realm,
             tgs_checksum.hex(), tgs_encrypted_data2.hex())
     else:
         tgs_checksum = res['enc-part']['cipher'][:16]
         tgs_encrypted_data2 = res['enc-part']['cipher'][16:]
         return '$krb5tgs$%s$*%s$%s$spn*$%s$%s' % (
             tgs_encryption_type, tgs_name_string, tgs_realm,
             tgs_checksum.hex(), tgs_encrypted_data2.hex())
예제 #9
0
파일: client.py 프로젝트: naver/PyCQuery
    def S4U2proxy(self,
                  s4uself_ticket,
                  spn_user,
                  supp_enc_methods=[
                      EncryptionType.DES_CBC_CRC, EncryptionType.DES_CBC_MD4,
                      EncryptionType.DES_CBC_MD5, EncryptionType.DES3_CBC_SHA1,
                      EncryptionType.ARCFOUR_HMAC_MD5,
                      EncryptionType.AES256_CTS_HMAC_SHA1_96,
                      EncryptionType.AES128_CTS_HMAC_SHA1_96
                  ]):
        logger.debug('[S4U2proxy] Impersonating %s' %
                     '/'.join(spn_user.get_principalname()))
        now = datetime.datetime.now(datetime.timezone.utc)
        supp_enc = self.usercreds.get_preferred_enctype(supp_enc_methods)

        pa_pac_opts = {}
        pa_pac_opts['padata-type'] = int(PADATA_TYPE('PA-PAC-OPTIONS'))
        pa_pac_opts['padata-value'] = PA_PAC_OPTIONS({
            'value':
            PA_PAC_OPTIONSTypes(set(['resource-based constrained delegation']))
        }).dump()

        authenticator_data = {}
        authenticator_data['authenticator-vno'] = krb5_pvno
        authenticator_data['crealm'] = Realm(self.kerberos_TGT['crealm'])
        authenticator_data['cname'] = self.kerberos_TGT['cname']
        authenticator_data['cusec'] = now.microsecond
        authenticator_data['ctime'] = now.replace(microsecond=0)

        authenticator_data_enc = self.kerberos_cipher.encrypt(
            self.kerberos_session_key, 7,
            Authenticator(authenticator_data).dump(), None)

        ap_req = {}
        ap_req['pvno'] = krb5_pvno
        ap_req['msg-type'] = MESSAGE_TYPE.KRB_AP_REQ.value
        ap_req['ap-options'] = APOptions(set())
        ap_req['ticket'] = Ticket(self.kerberos_TGT['ticket'])
        ap_req['authenticator'] = EncryptedData({
            'etype':
            self.kerberos_cipher_type,
            'cipher':
            authenticator_data_enc
        })

        pa_tgs_req = {}
        pa_tgs_req['padata-type'] = PaDataType.TGS_REQ.value
        pa_tgs_req['padata-value'] = AP_REQ(ap_req).dump()

        krb_tgs_body = {}
        krb_tgs_body['kdc-options'] = KDCOptions(
            set([
                'forwardable', 'renewable', 'constrained-delegation',
                'canonicalize'
            ]))
        krb_tgs_body['sname'] = PrincipalName({
            'name-type':
            NAME_TYPE.SRV_INST.value,
            'name-string':
            spn_user.get_principalname()
        })
        krb_tgs_body['realm'] = self.usercreds.domain.upper()
        krb_tgs_body['till'] = (now + datetime.timedelta(days=1)).replace(
            microsecond=0)
        krb_tgs_body['nonce'] = secrets.randbits(31)
        krb_tgs_body['etype'] = [
            supp_enc.value
        ]  #selecting according to server's preferences
        krb_tgs_body['additional-tickets'] = [s4uself_ticket]

        krb_tgs_req = {}
        krb_tgs_req['pvno'] = krb5_pvno
        krb_tgs_req['msg-type'] = MESSAGE_TYPE.KRB_TGS_REQ.value
        krb_tgs_req['padata'] = [pa_tgs_req, pa_pac_opts]
        krb_tgs_req['req-body'] = KDC_REQ_BODY(krb_tgs_body)

        req = TGS_REQ(krb_tgs_req)
        logger.debug('[S4U2proxy] Sending request to server')
        try:
            reply = self.ksoc.sendrecv(req.dump())
        except KerberosError as e:
            if e.errorcode.value == 16:
                logger.error(
                    'S4U2proxy: Failed to get S4U2proxy! Error code (16) indicates that delegation is not enabled for this account! Full error: %s'
                    % e)

            raise e
        logger.debug('[S4U2proxy] Got server reply, decrypting...')
        tgs = reply.native

        encTGSRepPart = EncTGSRepPart.load(
            self.kerberos_cipher.decrypt(self.kerberos_session_key, 8,
                                         tgs['enc-part']['cipher'])).native
        key = Key(encTGSRepPart['key']['keytype'],
                  encTGSRepPart['key']['keyvalue'])

        self.ccache.add_tgs(tgs, encTGSRepPart)
        logger.debug('[S4U2proxy] Got valid TGS reply')

        return tgs, encTGSRepPart, key
예제 #10
0
파일: client.py 프로젝트: naver/PyCQuery
    def S4U2self(self,
                 user_to_impersonate,
                 supp_enc_methods=[
                     EncryptionType.DES_CBC_CRC, EncryptionType.DES_CBC_MD4,
                     EncryptionType.DES_CBC_MD5, EncryptionType.DES3_CBC_SHA1,
                     EncryptionType.ARCFOUR_HMAC_MD5,
                     EncryptionType.AES256_CTS_HMAC_SHA1_96,
                     EncryptionType.AES128_CTS_HMAC_SHA1_96
                 ]):
        """
		user_to_impersonate : KerberosTarget class
		"""

        if not self.kerberos_TGT:
            logger.debug('[S4U2self] TGT is not available! Fetching TGT...')
            self.get_TGT()

        supp_enc = self.usercreds.get_preferred_enctype(supp_enc_methods)
        auth_package_name = 'Kerberos'
        now = datetime.datetime.now(datetime.timezone.utc)

        ###### Calculating authenticator data
        authenticator_data = {}
        authenticator_data['authenticator-vno'] = krb5_pvno
        authenticator_data['crealm'] = Realm(self.kerberos_TGT['crealm'])
        authenticator_data['cname'] = self.kerberos_TGT['cname']
        authenticator_data['cusec'] = now.microsecond
        authenticator_data['ctime'] = now.replace(microsecond=0)

        authenticator_data_enc = self.kerberos_cipher.encrypt(
            self.kerberos_session_key, 7,
            Authenticator(authenticator_data).dump(), None)

        ap_req = {}
        ap_req['pvno'] = krb5_pvno
        ap_req['msg-type'] = MESSAGE_TYPE.KRB_AP_REQ.value
        ap_req['ap-options'] = APOptions(set())
        ap_req['ticket'] = Ticket(self.kerberos_TGT['ticket'])
        ap_req['authenticator'] = EncryptedData({
            'etype':
            self.kerberos_cipher_type,
            'cipher':
            authenticator_data_enc
        })

        pa_data_auth = {}
        pa_data_auth['padata-type'] = PaDataType.TGS_REQ.value
        pa_data_auth['padata-value'] = AP_REQ(ap_req).dump()

        ###### Calculating checksum data

        S4UByteArray = NAME_TYPE.PRINCIPAL.value.to_bytes(4,
                                                          'little',
                                                          signed=False)
        S4UByteArray += user_to_impersonate.username.encode()
        S4UByteArray += user_to_impersonate.domain.encode()
        S4UByteArray += auth_package_name.encode()
        logger.debug('[S4U2self] S4UByteArray: %s' % S4UByteArray.hex())
        logger.debug('[S4U2self] S4UByteArray: %s' % S4UByteArray)

        chksum_data = _HMACMD5.checksum(self.kerberos_session_key, 17,
                                        S4UByteArray)
        logger.debug('[S4U2self] chksum_data: %s' % chksum_data.hex())

        chksum = {}
        chksum['cksumtype'] = int(CKSUMTYPE('HMAC_MD5'))
        chksum['checksum'] = chksum_data

        ###### Filling out PA-FOR-USER data for impersonation
        pa_for_user_enc = {}
        pa_for_user_enc['userName'] = PrincipalName({
            'name-type':
            NAME_TYPE.PRINCIPAL.value,
            'name-string':
            user_to_impersonate.get_principalname()
        })
        pa_for_user_enc['userRealm'] = user_to_impersonate.domain
        pa_for_user_enc['cksum'] = Checksum(chksum)
        pa_for_user_enc['auth-package'] = auth_package_name

        pa_for_user = {}
        pa_for_user['padata-type'] = int(PADATA_TYPE('PA-FOR-USER'))
        pa_for_user['padata-value'] = PA_FOR_USER_ENC(pa_for_user_enc).dump()

        ###### Constructing body

        krb_tgs_body = {}
        krb_tgs_body['kdc-options'] = KDCOptions(
            set(['forwardable', 'renewable', 'canonicalize']))
        krb_tgs_body['sname'] = PrincipalName({
            'name-type':
            NAME_TYPE.UNKNOWN.value,
            'name-string': [self.usercreds.username]
        })
        krb_tgs_body['realm'] = self.usercreds.domain.upper()
        krb_tgs_body['till'] = (now + datetime.timedelta(days=1)).replace(
            microsecond=0)
        krb_tgs_body['nonce'] = secrets.randbits(31)
        krb_tgs_body['etype'] = [
            supp_enc.value
        ]  #selecting according to server's preferences

        krb_tgs_req = {}
        krb_tgs_req['pvno'] = krb5_pvno
        krb_tgs_req['msg-type'] = MESSAGE_TYPE.KRB_TGS_REQ.value
        krb_tgs_req['padata'] = [pa_data_auth, pa_for_user]
        krb_tgs_req['req-body'] = KDC_REQ_BODY(krb_tgs_body)

        req = TGS_REQ(krb_tgs_req)

        logger.debug('[S4U2self] Sending request to server')
        try:
            reply = self.ksoc.sendrecv(req.dump())
        except KerberosError as e:
            if e.errorcode.value == 16:
                logger.error(
                    '[S4U2self] Failed to get S4U2self! Error code (16) indicates that delegation is not enabled for this account! Full error: %s'
                    % e)

            raise e

        logger.debug('[S4U2self] Got reply, decrypting...')
        tgs = reply.native

        encTGSRepPart = EncTGSRepPart.load(
            self.kerberos_cipher.decrypt(self.kerberos_session_key, 8,
                                         tgs['enc-part']['cipher'])).native
        key = Key(encTGSRepPart['key']['keytype'],
                  encTGSRepPart['key']['keyvalue'])

        self.ccache.add_tgs(tgs, encTGSRepPart)
        logger.debug('[S4U2self] Got valid TGS reply')
        self.kerberos_TGS = tgs
        return tgs, encTGSRepPart, key
예제 #11
0
파일: client.py 프로젝트: naver/PyCQuery
    def get_TGS(self, spn_user, override_etype=None, is_linux=False):
        """
		Requests a TGS ticket for the specified user.
		Returns the TGS ticket, end the decrpyted encTGSRepPart.

		spn_user: KerberosTarget: the service user you want to get TGS for.
		override_etype: None or list of etype values (int) Used mostly for kerberoasting, will override the AP_REQ supported etype values (which is derived from the TGT) to be able to recieve whatever tgs tiecket 
		"""

        logger.debug('[getTGS] Constructing request for user %s' %
                     spn_user.get_formatted_pname())
        now = datetime.datetime.now(datetime.timezone.utc)
        kdc_req_body = {}
        kdc_req_body['kdc-options'] = KDCOptions(
            set(['forwardable', 'renewable', 'renewable_ok', 'canonicalize']))
        kdc_req_body['realm'] = spn_user.domain.upper()
        kdc_req_body['sname'] = PrincipalName({
            'name-type':
            NAME_TYPE.SRV_INST.value,
            'name-string':
            spn_user.get_principalname()
        })
        kdc_req_body['till'] = (now + datetime.timedelta(days=1)).replace(
            microsecond=0)
        kdc_req_body['nonce'] = secrets.randbits(31)
        if override_etype:
            kdc_req_body['etype'] = override_etype
        else:
            kdc_req_body['etype'] = [self.kerberos_cipher_type]

        authenticator_data = {}
        authenticator_data['authenticator-vno'] = krb5_pvno
        authenticator_data['crealm'] = Realm(self.kerberos_TGT['crealm'])
        authenticator_data['cname'] = self.kerberos_TGT['cname']
        authenticator_data['cusec'] = now.microsecond
        authenticator_data['ctime'] = now.replace(microsecond=0)
        authenticator_data['seq-number'] = 0

        if is_linux:
            ac = AuthenticatorChecksum()
            ac.flags = 0
            ac.channel_binding = b'\x00' * 16

            chksum = {}
            chksum['cksumtype'] = 0x8003
            chksum['checksum'] = ac.to_bytes()

            authenticator_data['cksum'] = Checksum(chksum)
        else:
            from pycquery_krb.protocol.encryption import Enctype, Cksumtype, make_checksum
            if Enctype.AES256 == self.kerberos_session_key.enctype:
                authenticator_data['cksum'] = Checksum({
                    'cksumtype':
                    Cksumtype.SHA1_AES256,
                    'checksum':
                    make_checksum(Cksumtype.SHA1_AES256,
                                  self.kerberos_session_key, 6,
                                  KDC_REQ_BODY(kdc_req_body).dump())
                })

        authenticator_data_enc = self.kerberos_cipher.encrypt(
            self.kerberos_session_key, 7,
            Authenticator(authenticator_data).dump(), None)

        ap_req = {}
        ap_req['pvno'] = krb5_pvno
        ap_req['msg-type'] = MESSAGE_TYPE.KRB_AP_REQ.value
        ap_req['ap-options'] = APOptions(set())
        ap_req['ticket'] = Ticket(self.kerberos_TGT['ticket'])
        ap_req['authenticator'] = EncryptedData({
            'etype':
            self.kerberos_cipher_type,
            'cipher':
            authenticator_data_enc
        })

        pa_data_1 = {}
        pa_data_1['padata-type'] = PaDataType.TGS_REQ.value
        pa_data_1['padata-value'] = AP_REQ(ap_req).dump()

        kdc_req = {}
        kdc_req['pvno'] = krb5_pvno
        kdc_req['msg-type'] = MESSAGE_TYPE.KRB_TGS_REQ.value
        kdc_req['padata'] = [pa_data_1]
        kdc_req['req-body'] = KDC_REQ_BODY(kdc_req_body)

        req = TGS_REQ(kdc_req)
        logger.debug('[getTGS] Constructing request to server')
        rep = self.ksoc.sendrecv(req.dump())
        logger.debug('[getTGS] Got reply, decrypting...')
        tgs = rep.native

        encTGSRepPart = EncTGSRepPart.load(
            self.kerberos_cipher.decrypt(self.kerberos_session_key, 8,
                                         tgs['enc-part']['cipher'])).native
        key = Key(encTGSRepPart['key']['keytype'],
                  encTGSRepPart['key']['keyvalue'])

        self.ccache.add_tgs(tgs, encTGSRepPart)
        logger.debug('[getTGS] Got valid reply')
        self.kerberos_TGS = tgs
        return tgs, encTGSRepPart, key