コード例 #1
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()
コード例 #2
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()
コード例 #3
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
コード例 #4
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
コード例 #5
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