예제 #1
0
    def setup(self):
        self.mode = self.settings.mode
        if self.mode.upper() == 'MANUAL':
            #for passign the messages automatically with the sessionbasekey, the using this class for sign and seal
            return

        if 'challenge' not in self.settings.template:
            self.challenge = os.urandom(8)
        else:
            self.challenge = self.settings.template['challenge']
        self.flags = self.settings.template['flags']
        if 'session_key' in self.settings.template:
            self.RandomSessionKey = self.settings.template['session_key']

        self.timestamp = self.settings.template.get(
            'timestamp')  #used in unittest only!

        if self.mode.upper() == 'SERVER':
            version = self.settings.template['version']
            targetName = self.settings.template['targetname']
            targetInfo = self.settings.template['targetinfo']

            self.ntlmChallenge = NTLMChallenge.construct(
                challenge=self.challenge,
                targetName=targetName,
                targetInfo=targetInfo,
                version=version,
                flags=self.flags)
예제 #2
0
    def setup(self):
        if 'challenge' not in self.settings.template:
            self.challenge = os.urandom(8)
        else:
            self.challenge = self.settings.template['challenge']
        self.flags = self.settings.template['flags']
        if 'session_key' in self.settings.template:
            self.RandomSessionKey = self.settings.template['session_key']
        self.mode = self.settings.mode
        self.timestamp = self.settings.template.get(
            'timestamp')  #used in unittest only!

        if self.mode.upper() == 'SERVER':
            version = self.settings.template['version']
            targetName = self.settings.template['targetname']
            targetInfo = self.settings.template['targetinfo']

            self.ntlmChallenge = NTLMChallenge.construct(
                challenge=self.challenge_server,
                targetName=targetName,
                targetInfo=targetInfo,
                version=version,
                flags=self.flags)
예제 #3
0
def test_msdn():
    credential = Credential()
    credential.username = '******'
    credential.domain = 'Domain'
    credential.password = '******'

    template = {
        'flags':
        NegotiateFlags.NEGOTIATE_56 | NegotiateFlags.REQUEST_NON_NT_SESSION_KEY
        | NegotiateFlags.NEGOTIATE_KEY_EXCH | NegotiateFlags.NEGOTIATE_128
        | NegotiateFlags.NEGOTIATE_VERSION | NegotiateFlags.TARGET_TYPE_SERVER
        | NegotiateFlags.NEGOTIATE_ALWAYS_SIGN | NegotiateFlags.NEGOTIATE_NTLM
        | NegotiateFlags.NEGOTIATE_SIGN | NegotiateFlags.NEGOTIATE_SEAL
        | NegotiateFlags.NTLM_NEGOTIATE_OEM | NegotiateFlags.NEGOTIATE_UNICODE,
        'version':
        Version.construct(WindowsMajorVersion.WINDOWS_MAJOR_VERSION_10,
                          minor=WindowsMinorVersion.WINDOWS_MINOR_VERSION_0,
                          build=15063),
        'domain_name':
        'Domain',
        'workstation_name':
        'COMPUTER',
        'ntlm_downgrade':
        True,
        'extended_security':
        False
    }
    settings = NTLMHandlerSettings(credential,
                                   mode='CLIENT',
                                   template_name=None,
                                   ntlm_downgrade=True,
                                   extended_security=False,
                                   custom_template=template)
    handler = NTLMAUTHHandler(settings)
    #assert handler.flags == int.from_bytes(b'\x33\x82\x02\xe2', "little", signed = False)
    data, is_res = handler.authenticate(None)
    print(data)
    print(is_res)

    details = AVPairs({
        AVPAIRType.MsvAvNbDomainName: 'TEST',
        AVPAIRType.MsvAvNbComputerName: 'WIN2019AD',
        AVPAIRType.MsvAvDnsDomainName: 'test.corp',
        AVPAIRType.MsvAvDnsComputerName: 'WIN2019AD.test.corp',
        AVPAIRType.MsvAvTimestamp: b'\xae\xc6\x00\xbf\xc5\xfd\xd4\x01',
        AVPAIRType.MsvAvFlags: b'\x02\x00\x00\x00',
        AVPAIRType.MsvAvSingleHost:
        b"0\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 \x00\x00R}'\xf24\xdet7`\x96c\x84\xd3oa\xae*\xa4\xfc*8\x06\x99\xf8\xca\xa6\x00\x01\x1bHm\x89",
        AVPAIRType.MsvChannelBindings:
        b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00',
        AVPAIRType.MsvAvTargetName: 'cifs/10.10.10.2'
    })

    challenge = NTLMChallenge.construct(
        challenge=b'\x01\x23\x45\x67\x89\xab\xcd\xef',
        targetName='Domain',
        targetInfo=details,
        version=handler.ntlmNegotiate.Version,
        flags=handler.flags)
    data, is_res = handler.authenticate(challenge.to_bytes())
    print(data)
    print(is_res)

    print(handler.ntlmAuthenticate.LMChallenge.to_bytes().hex())
    print(handler.ntlmAuthenticate.NTChallenge.to_bytes().hex())
예제 #4
0
    async def authenticate(self,
                           authData,
                           flags=None,
                           seq_number=0,
                           is_rpc=False):
        if self.mode.upper() == 'SERVER':
            if self.ntlmNegotiate is None:
                ###parse client NTLMNegotiate message
                self.ntlmNegotiate = NTLMNegotiate.from_bytes(authData)
                return self.ntlmChallenge.to_bytes(), True

            elif self.ntlmAuthenticate is None:
                self.ntlmAuthenticate = NTLMAuthenticate.from_bytes(
                    authData, self.use_NTLMv2)
                creds = NTLMcredential.construct(self.ntlmNegotiate,
                                                 self.ntlmChallenge,
                                                 self.ntlmAuthenticate)
                print(creds)

                # TODO: check when is sessionkey needed and check when is singing needed, and calculate the keys!
                # self.calc_SessionBaseKey()
                # self.calc_KeyExchangeKey()
                auth_credential = creds[0]
                #self.SessionBaseKey = auth_credential.calc_session_base_key()
                #self.calc_key_exchange_key()

                if auth_credential.verify(self.credential):
                    return AuthResult.FAIL, auth_credential
                else:
                    return AuthResult.FAIL, auth_credential

            else:
                raise Exception('Too many calls to do_AUTH function!')

        elif self.mode.upper() == 'CLIENT':
            if self.iteration_cnt == 0:
                if authData is not None:
                    raise Exception(
                        'First call as client MUST be with empty data!')

                if is_rpc == True:
                    #rpc (unknow reason) reqauires seal to be set, otherwise it will fail to authenticate
                    self.set_seal()

                self.iteration_cnt += 1
                #negotiate message was already calulcated in setup
                self.ntlmNegotiate = NTLMNegotiate.construct(
                    self.flags,
                    domainname=self.settings.template['domain_name'],
                    workstationname=self.settings.template['workstation_name'],
                    version=self.settings.template.get('version'))
                self.ntlmNegotiate_raw = self.ntlmNegotiate.to_bytes()
                return self.ntlmNegotiate_raw, True

            else:
                #server challenge incoming
                self.ntlmChallenge_raw = authData
                self.ntlmChallenge = NTLMChallenge.from_bytes(authData)

                if is_rpc == True:
                    #rpc (unknow reason) reqauires seal to be set, otherwise it will fail to authenticate
                    self.set_seal()

                ##################self.flags = self.ntlmChallenge.NegotiateFlags

                #we need to calculate the response based on the credential and the settings flags
                if self.settings.ntlm_downgrade == True:
                    #NTLMv1 authentication
                    # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/464551a8-9fc4-428e-b3d3-bc5bfb2e73a5

                    #check if we authenticate as guest
                    if self.settings.credential.is_guest == True:
                        lmresp = LMResponse()
                        lmresp.Response = b'\x00'
                        self.ntlmAuthenticate = NTLMAuthenticate.construct(
                            self.flags, lm_response=lmresp)
                        return self.ntlmAuthenticate.to_bytes(), False

                    if self.flags & NegotiateFlags.NEGOTIATE_EXTENDED_SESSIONSECURITY:
                        #Extended auth!
                        self.ntlm_credentials = netntlm_ess.construct(
                            self.ntlmChallenge.ServerChallenge, self.challenge,
                            self.settings.credential)

                        self.KeyExchangeKey = self.ntlm_credentials.calc_key_exchange_key(
                        )
                        self.setup_crypto()

                        self.ntlmAuthenticate = NTLMAuthenticate.construct(
                            self.flags,
                            lm_response=self.ntlm_credentials.LMResponse,
                            nt_response=self.ntlm_credentials.NTResponse,
                            version=self.ntlmNegotiate.Version,
                            encrypted_session=self.EncryptedRandomSessionKey)
                    else:
                        self.ntlm_credentials = netntlm.construct(
                            self.ntlmChallenge.ServerChallenge,
                            self.settings.credential)

                        self.KeyExchangeKey = self.ntlm_credentials.calc_key_exchange_key(
                            with_lm=self.flags
                            & NegotiateFlags.NEGOTIATE_LM_KEY,
                            non_nt_session_key=self.flags
                            & NegotiateFlags.REQUEST_NON_NT_SESSION_KEY)
                        self.setup_crypto()
                        self.ntlmAuthenticate = NTLMAuthenticate.construct(
                            self.flags,
                            lm_response=self.ntlm_credentials.LMResponse,
                            nt_response=self.ntlm_credentials.NTResponse,
                            version=self.ntlmNegotiate.Version,
                            encrypted_session=self.EncryptedRandomSessionKey)

                else:
                    #NTLMv2
                    # https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-nlmp/5e550938-91d4-459f-b67d-75d70009e3f3
                    if self.settings.credential.is_guest == True:
                        lmresp = LMResponse()
                        lmresp.Response = b'\x00'
                        self.ntlmAuthenticate = NTLMAuthenticate.construct(
                            self.flags, lm_response=lmresp)
                        return self.ntlmAuthenticate.to_bytes(), False

                    else:
                        #comment this out for testing!
                        ti = self.ntlmChallenge.TargetInfo
                        ti[AVPAIRType.MsvAvTargetName] = 'cifs/%s' % ti[
                            AVPAIRType.MsvAvNbComputerName]
                        ###

                        self.ntlm_credentials = netntlmv2.construct(
                            self.ntlmChallenge.ServerChallenge,
                            self.challenge,
                            ti,
                            self.settings.credential,
                            timestamp=self.timestamp)
                        self.KeyExchangeKey = self.ntlm_credentials.calc_key_exchange_key(
                        )
                        self.setup_crypto()

                        #TODO: if "ti" / targetinfo in the challenge message has "MsvAvFlags" type and the bit for MIC is set (0x00000002) we need to send a MIC. probably...
                        mic = None

                        self.ntlmAuthenticate = NTLMAuthenticate.construct(
                            self.flags,
                            domainname=self.settings.credential.domain,
                            workstationname=self.settings.credential.
                            workstation,
                            username=self.settings.credential.username,
                            lm_response=self.ntlm_credentials.LMResponse,
                            nt_response=self.ntlm_credentials.NTResponse,
                            version=self.ntlmNegotiate.Version,
                            encrypted_session=self.EncryptedRandomSessionKey,
                            mic=mic)

                self.ntlmAuthenticate_raw = self.ntlmAuthenticate.to_bytes()
                return self.ntlmAuthenticate_raw, False

        elif self.mode.upper() == 'RELAY':
            if self.iteration_cnt == 0:
                self.ntlmNegotiate_raw = authData
                self.ntlmNegotiate = NTLMNegotiate.from_bytes(authData)
                self.iteration_cnt += 1

            elif self.iteration_cnt == 1:
                self.ntlmChallenge_raw = authData
                self.ntlmChallenge = NTLMChallenge.from_bytes(authData)
                self.iteration_cnt += 1

            elif self.iteration_cnt == 2:
                self.ntlmChallenge_raw = authData
                self.ntlmChallenge = NTLMChallenge.from_bytes(authData)
                self.iteration_cnt += 1

            else:
                raise Exception('Too many iterations for relay mode!')
예제 #5
0
 def load_challenge(self, data):
     self.ntlmChallenge = NTLMChallenge.from_bytes(data)