Beispiel #1
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        try:
            status, ctxattr, apreq, err = await self.sspi.authenticate(
                'KERBEROS',
                '',
                self.settings.target.to_target_string(),
                3,
                self.flags.value,
                authdata=b'')
            if err is not None:
                raise err

            self.flags = ISC_REQ(ctxattr)

            self.session_key, err = await self.sspi.get_sessionkey()
            if err is not None:
                return None, None, err

            unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
            aprep = AP_REQ.load(unwrap.data[2:]).native
            subkey = Key(aprep['ticket']['enc-part']['etype'],
                         self.session_key)
            self.gssapi = get_gssapi(subkey)

            if aprep['ticket']['enc-part']['etype'] != 23:
                if ISC_REQ.CONFIDENTIALITY in self.flags:
                    raw_seq_data, err = await self.sspi.get_sequenceno()
                    if err is not None:
                        return None, None, err
                    self.seq_number = GSSWrapToken.from_bytes(
                        raw_seq_data[16:]).SND_SEQ

            return unwrap.data[2:], False, None
        except Exception as e:
            return None, None, e
Beispiel #2
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        #authdata is only for api compatibility reasons
        if self.ksspi is None:
            await self.start_remote_kerberos()
        try:
            apreq, res = await self.ksspi.authenticate(
                self.settings.target.to_target_string(),
                flags=str(self.flags.value))
            #print('MULTIPLEXOR KERBEROS SSPI, APREQ: %s ERROR: %s' % (apreq, res))
            if res is not None:
                return None, None, res

            # here it seems like we get the full token not just the apreq data...
            # so we need to discard the layers

            self.session_key, err = await self.ksspi.get_session_key()
            if err is not None:
                return None, None, err

            unwrap = KRB5_MECH_INDEP_TOKEN.from_bytes(apreq)
            aprep = AP_REQ.load(unwrap.data[2:]).native
            subkey = Key(aprep['ticket']['enc-part']['etype'],
                         self.session_key)
            self.gssapi = get_gssapi(subkey)

            if aprep['ticket']['enc-part']['etype'] != 23:
                raw_seq_data, err = await self.ksspi.get_seq_number()
                if err is not None:
                    return None, None, err
                self.seq_number = GSSWrapToken.from_bytes(
                    raw_seq_data[16:]).SND_SEQ

            return unwrap.data[2:], False, res
        except Exception as e:
            return None, None, e
Beispiel #3
0
    async def authenticate(self,
                           authData,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        """
		This function is called (multiple times depending on the flags) to perform authentication. 
		"""
        try:
            if self.kc is None:
                _, err = await self.setup_kc()
                if err is not None:
                    return None, None, err

            if self.iterations == 0:
                self.seq_number = 0  #int.from_bytes(os.urandom(4), byteorder='big', signed=False)
                self.iterations += 1

                #tgt = await self.kc.get_TGT()
                tgt = await self.kc.get_TGT(
                    override_etype=self.preferred_etypes)
                tgs, encpart, self.session_key = await self.kc.get_TGS(
                    self.spn)  #, override_etype = self.preferred_etypes)

                #self.expected_server_seq_number = encpart.get('nonce', seq_number)

                ap_opts = []
                if ChecksumFlags.GSS_C_MUTUAL_FLAG in self.flags or ChecksumFlags.GSS_C_DCE_STYLE in self.flags:
                    if ChecksumFlags.GSS_C_MUTUAL_FLAG in self.flags:
                        ap_opts.append('mutual-required')
                    apreq = self.kc.construct_apreq(tgs,
                                                    encpart,
                                                    self.session_key,
                                                    flags=self.flags,
                                                    seq_number=self.seq_number,
                                                    ap_opts=ap_opts,
                                                    cb_data=cb_data)
                    return apreq, True, None

                else:
                    #no mutual or dce auth will take one step only
                    apreq = self.kc.construct_apreq(tgs,
                                                    encpart,
                                                    self.session_key,
                                                    flags=self.flags,
                                                    seq_number=self.seq_number,
                                                    ap_opts=[],
                                                    cb_data=cb_data)
                    self.gssapi = get_gssapi(self.session_key)
                    return apreq, False, None

            else:
                self.iterations += 1
                #raise Exception('Not implemented!')
                if ChecksumFlags.GSS_C_DCE_STYLE in self.flags:
                    # adata = authData[16:]
                    # if ChecksumFlags.GSS_C_DCE_STYLE in self.flags:
                    #	adata = authData
                    raise Exception('DCE auth Not implemented!')

                # at this point we are dealing with mutual authentication
                # This means that the server sent back an AP-rep wrapped in a token
                # The APREP contains a new session key we'd need to update and a seq-number
                # that is expected the server will use for future communication.
                # For mutual auth we dont need to reply anything after this step,
                # but for DCE auth a reply is expected. TODO

                # converting the token to aprep
                token = KRB5_MECH_INDEP_TOKEN.from_bytes(authData)
                if token.data[:2] != b'\x02\x00':
                    raise Exception('Unexpected token type! %s' %
                                    token.data[:2].hex())
                aprep = AP_REP.load(token.data[2:]).native

                # decrypting aprep
                cipher = _enctype_table[int(aprep['enc-part']['etype'])]()
                cipher_text = aprep['enc-part']['cipher']
                temp = cipher.decrypt(self.session_key, 12, cipher_text)
                enc_part = EncAPRepPart.load(temp).native

                #updating session key, gssapi
                self.session_key = Key(int(enc_part['subkey']['keytype']),
                                       enc_part['subkey']['keyvalue'])
                #self.seq_number = enc_part.get('seq-number', 0)
                self.gssapi = get_gssapi(self.session_key)

                return b'', False, None

        except Exception as e:
            return None, None, e
Beispiel #4
0
    async def authenticate(self,
                           authData=None,
                           flags=None,
                           seq_number=0,
                           cb_data=None):
        """
		This function is called (multiple times depending on the flags) to perform authentication. 
		"""
        try:
            if self.iterations == 0:
                self.ksspi = KerberosMSLDAPSSPI(domain=self.domain,
                                                username=self.username,
                                                password=self.password)
                token, self.actual_ctx_flags = self.ksspi.get_ticket_for_spn(
                    self.spn, ctx_flags=self.flags)
                self.iterations += 1

                if ISC_REQ.MUTUAL_AUTH in self.actual_ctx_flags or ISC_REQ.USE_DCE_STYLE in self.actual_ctx_flags:
                    #in these cases continuation is needed
                    return token, True, None

                else:
                    #no mutual or dce auth will take one step only
                    _, err = self.get_session_key()
                    if err is not None:
                        return None, None, err
                    apreq = AP_REQ.load(token).native
                    subkey = Key(apreq['ticket']['enc-part']['etype'],
                                 self.session_key)
                    self.gssapi = get_gssapi(subkey)
                    self.get_seq_number()

                    return token, False, None

            else:
                adata = authData[16:]
                if ISC_REQ.USE_DCE_STYLE in self.actual_ctx_flags:
                    adata = authData
                token, self.actual_ctx_flags = self.ksspi.get_ticket_for_spn(
                    self.spn,
                    ctx_flags=self.actual_ctx_flags,
                    token_data=adata)

                if ISC_REQ.USE_DCE_STYLE in self.actual_ctx_flags:
                    #Using DCE style 3-legged auth
                    aprep = AP_REP.load(token).native
                else:
                    aprep = AP_REP.load(adata).native
                    subkey = Key(aprep['enc-part']['etype'],
                                 self.get_session_key())

                _, err = self.get_session_key()
                if err is not None:
                    return None, None, err

                _, err = self.get_seq_number()
                if err is not None:
                    return None, None, err

                subkey = Key(token['enc-part']['etype'], self.session_key)
                self.gssapi = get_gssapi(subkey)

                self.iterations += 1
                return token, False, None

        except Exception as e:
            return None, None, e