예제 #1
0
        /// <summary>
        /// initialize the exportedSessionKey and internal keys
        /// </summary>
        /// <param name="flags">the flags of challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="responseKeyLM">the response key lm</param>
        /// <param name="lmChallengeResponse">the challenge response lm</param>
        /// <param name="encryptedRandomSessionKey">the encrypted random session key</param>
        /// <param name="exportedSessionKey">the exported session key</param>
        private void InitializeKeys(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            byte[] responseKeyLM,
            byte[] lmChallengeResponse,
            out byte[] encryptedRandomSessionKey,
            out byte[] exportedSessionKey
            )
        {
            // keyExchangeKey
            byte[] keyExchangeKey = null;

            // get random session key
            NlmpUtility.GetEncryptedRandomSessionKey(
                this.client.Config.Version, flags, this.client.Context.SessionBaseKey, lmChallengeResponse,
                responseKeyLM, challenge.Payload.ServerChallenge, out encryptedRandomSessionKey, out keyExchangeKey,
                out exportedSessionKey);

            this.client.Context.ClientSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Server");
            this.client.Context.ClientSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Server");

            NlmpUtility.RC4Init(this.client.Context.ClientHandle, this.client.Context.ClientSealingKey);
            NlmpUtility.RC4Init(this.client.Context.ServerHandle, this.client.Context.ServerSealingKey);
        }
예제 #2
0
        /// <summary>
        /// initialize the response of challenge
        /// </summary>
        /// <param name="flags">the flag for challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="targetInfo">the target info of avpairs</param>
        /// <param name="responseKeyLM">the response lm key</param>
        /// <param name="lmChallengeResponse">the challenge lm response</param>
        /// <param name="ntChallengeResponse">the nt challenge response</param>
        private void InitializeChallengeResponse(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            ICollection <AV_PAIR> targetInfo,
            out byte[] responseKeyLM,
            out byte[] lmChallengeResponse,
            out byte[] ntChallengeResponse
            )
        {
            // responseKeyNT
            byte[] responseKeyNT = NlmpUtility.GetResponseKeyNt(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // responseKeyLM
            responseKeyLM = NlmpUtility.GetResponseKeyLm(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // lmChallengeResponse
            lmChallengeResponse = null;

            // ntChallengeResponse
            ntChallengeResponse = null;

            ComputeResponse(
                flags, challenge.Payload.ServerChallenge, targetInfo, responseKeyNT, responseKeyLM,
                out lmChallengeResponse, out ntChallengeResponse);

            UpdateLmChallengeResponse(targetInfo, ref lmChallengeResponse);
        }
        /// <summary>
        /// create a challenge packet. This packet contains CHALLENGE_MESSAGE. The CHALLENGE_MESSAGE defines an NTLM
        /// challenge message that is sent from the server to the client. The CHALLENGE_MESSAGE is used by the server
        /// to challenge the client to prove its identity.
        /// </summary>
        /// <param name="negotiateFlags">The client sets flags to indicate options it supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="serverChallenge">contains the NTLM challenge. The challenge is a 64-bit nonce.</param>
        /// <param name="targetName">
        /// TargetName contains the name of the server authentication realm, and MUST be expressed in the negotiated
        /// character set. A server that is a member of a domain returns the domain of which it is a member, and a
        /// server that is not a member of a domain returns the server name. This param can be null.
        /// </param>
        /// <param name="targetInfo">
        /// TargetInfo contains a sequence of AV_PAIR structures.This param can be null.
        /// </param>
        /// <returns>the NlmpChallengePacket</returns>
        /// <noException></noException>
        public NlmpChallengePacket CreateChallengePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            ulong serverChallenge,
            string targetName,
            ICollection <AV_PAIR> targetInfo
            )
        {
            NlmpChallengePacket packet = new NlmpChallengePacket();

            packet.SetNegotiateFlags(negotiateFlags);

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            packet.SetServerChallenge(serverChallenge);

            if (NlmpUtility.IsDomainType(negotiateFlags) || NlmpUtility.IsServerType(negotiateFlags))
            {
                packet.SetTargetName(targetName);
            }

            // generate bytes of targetinfo
            byte[] targetInfoBytes = NlmpUtility.AvPairCollectionGetBytes(targetInfo);

            // initialize targetinfofield
            packet.SetTargetInfo(targetInfoBytes);

            return(packet);
        }
        /// <summary>
        /// copy constructor.
        /// </summary>
        public NlmpChallengePacket(
            NlmpChallengePacket stackPacket
            )
            : base(stackPacket)
        {
            this.payload = stackPacket.payload;

            if (stackPacket.payload.TargetName != null)
            {
                this.payload.TargetName =
                    new byte[stackPacket.payload.TargetName.Length];
                Array.Copy(
                    stackPacket.payload.TargetName,
                    this.payload.TargetName,
                    stackPacket.payload.TargetName.Length);
            }

            if (stackPacket.payload.TargetInfo != null)
            {
                this.payload.TargetInfo =
                    new byte[stackPacket.payload.TargetInfo.Length];
                Array.Copy(
                    stackPacket.payload.TargetInfo,
                    this.payload.TargetInfo,
                    stackPacket.payload.TargetInfo.Length);
            }
        }
        /// <summary>
        /// copy constructor.
        /// </summary>
        public NlmpChallengePacket(
            NlmpChallengePacket stackPacket
            )
            : base(stackPacket)
        {
            this.payload = stackPacket.payload;

            if (stackPacket.payload.TargetName != null)
            {
                this.payload.TargetName =
                    new byte[stackPacket.payload.TargetName.Length];
                Array.Copy(
                    stackPacket.payload.TargetName,
                    this.payload.TargetName,
                    stackPacket.payload.TargetName.Length);
            }

            if (stackPacket.payload.TargetInfo != null)
            {
                this.payload.TargetInfo =
                    new byte[stackPacket.payload.TargetInfo.Length];
                Array.Copy(
                    stackPacket.payload.TargetInfo,
                    this.payload.TargetInfo,
                    stackPacket.payload.TargetInfo.Length);
            }
        }
예제 #6
0
        /// <summary>
        /// get the security token,using the token from server
        /// </summary>
        /// <param name="serverToken">the token from server challenge</param>
        /// <returns>the security token</returns>
        private byte[] GetSecurityToken(
            byte[] serverToken
            )
        {
            if (this.client == null)
            {
                throw new InvalidOperationException("The client is null! You must initialize this field first!");
            }

            // the challenge packet from server
            NlmpChallengePacket challenge = new NlmpChallengePacket(serverToken);

            NegotiateTypes flags = InitializeNegotiateFlags(challenge.Payload.NegotiateFlags);

            // the target info
            ICollection <AV_PAIR> targetInfo = InitializeTargetInfo(challenge.Payload.TargetInfo);

            // responseKeyLM
            byte[] responseKeyLM;

            // lmChallengeResponse
            byte[] lmChallengeResponse;

            // ntChallengeResponse
            byte[] ntChallengeResponse;

            // initialize the challenge response
            InitializeChallengeResponse(
                flags, challenge, targetInfo, out responseKeyLM, out lmChallengeResponse, out ntChallengeResponse);

            // encryptedRandomSessionKey
            byte[] encryptedRandomSessionKey = null;

            // exportedSessionKey
            byte[] exportedSessionKey = null;

            // initialize keys
            InitializeKeys(
                flags, challenge, responseKeyLM, lmChallengeResponse, out encryptedRandomSessionKey,
                out exportedSessionKey);

            // save the exported sessionkey
            this.client.Context.ExportedSessionKey = exportedSessionKey;

            // create challenge packet
            NlmpAuthenticatePacket packet = this.client.CreateAuthenticatePacket(
                flags, NlmpUtility.GetVersion(), lmChallengeResponse, ntChallengeResponse,
                this.currentActiveCredential.DomainName, this.currentActiveCredential.AccountName,
                Environment.MachineName, encryptedRandomSessionKey);

            // initialize the mic of challenge packet
            InitializeChallengeMIC(exportedSessionKey, targetInfo, packet, challenge);

            return(packet.ToBytes());
        }
예제 #7
0
        /// <summary>
        /// Update ServerChallenge to this context
        /// </summary>
        /// <param name="serverChallenge">the serverChallenge to update</param>
        public void UpdateServerChallenge(ulong serverChallenge)
        {
            #region Prepare the Nlmp Negotiate Flags

            // the flags for negotiage
            NegotiateTypes nlmpFlags = NegotiateTypes.NTLMSSP_NEGOTIATE_NTLM | NegotiateTypes.NTLM_NEGOTIATE_OEM;

            #endregion

            #region Prepare the ServerName

            List <AV_PAIR> pairs = new List <AV_PAIR>();

            NlmpUtility.AddAVPair(pairs, AV_PAIR_IDs.MsvAvEOL, 0x00, null);

            #endregion

            this.challenge = this.nlmpServer.CreateChallengePacket(nlmpFlags, NlmpUtility.GetVersion(), serverChallenge,
                                                                   GenerateTargetName(), pairs);
            this.token = this.challenge.ToBytes();
        }
예제 #8
0
        /// <summary>
        /// initialize the mic of challenge packet
        /// </summary>
        /// <param name="exportedSessionKey">the exported session key</param>
        /// <param name="targetInfo">the target info contains av pairs.</param>
        /// <param name="authenticatePacket">the authenticate packet</param>
        /// <param name="challengePacket">the challenge packet</param>
        private void InitializeChallengeMIC(
            byte[] exportedSessionKey,
            ICollection <AV_PAIR> targetInfo,
            NlmpAuthenticatePacket authenticatePacket,
            NlmpChallengePacket challengePacket
            )
        {
            if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvTimestamp))
            {
                // update mic with security algorithm
                byte[] mic = null;
                // if connectionless, this.negotiate is null.
                mic = NlmpUtility.GetMic(exportedSessionKey, this.negotiate, challengePacket, authenticatePacket);

                // get payload of packet
                AUTHENTICATE_MESSAGE payload = authenticatePacket.Payload;

                // update mic to payload
                payload.MIC = mic;

                // update the meaningful payload to packet
                authenticatePacket.Payload = payload;
            }
        }
예제 #9
0
        /// <summary>
        /// accept the negotiate packet, generated the challenge packet.
        /// </summary>
        /// <param name="negotiatePacket">the negotiate packet</param>
        private void AcceptNegotiatePacket(NlmpNegotiatePacket negotiatePacket)
        {
            // save the negotiate, to valid the mic when authenticate.
            this.negotiate = negotiatePacket;

            // generated negotiate flags for challenge packet
            NegotiateTypes negotiateFlags = GeneratedNegotiateFlags(negotiatePacket);

            // initialize target name
            string targetName = GenerateTargetName();

            // initialize av pairs.
            ICollection <AV_PAIR> targetInfo = GenerateTargetInfo();

            VERSION sspiVersion = NlmpUtility.GetVersion();
            // the serverChallenge is 8 bytes.
            ulong serverChallenge = BitConverter.ToUInt64(NlmpUtility.Nonce(8), 0);

            NlmpChallengePacket challengePacket = this.nlmpServer.CreateChallengePacket(
                negotiateFlags, sspiVersion, serverChallenge, targetName, targetInfo);

            this.challenge = challengePacket;
            this.token     = challengePacket.ToBytes();
        }
        /// <summary>
        /// initialize the exportedSessionKey and internal keys
        /// </summary>
        /// <param name="flags">the flags of challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="responseKeyLM">the response key lm</param>
        /// <param name="lmChallengeResponse">the challenge response lm</param>
        /// <param name="encryptedRandomSessionKey">the encrypted random session key</param>
        /// <param name="exportedSessionKey">the exported session key</param>
        private void InitializeKeys(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            byte[] responseKeyLM,
            byte[] lmChallengeResponse,
            out byte[] encryptedRandomSessionKey,
            out byte[] exportedSessionKey
            )
        {
            // keyExchangeKey
            byte[] keyExchangeKey = null;

            // get random session key
            NlmpUtility.GetEncryptedRandomSessionKey(
                this.client.Config.Version, flags, this.client.Context.SessionBaseKey, lmChallengeResponse,
                responseKeyLM, challenge.Payload.ServerChallenge, out encryptedRandomSessionKey, out keyExchangeKey,
                out exportedSessionKey);

            this.client.Context.ClientSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSigningKey = NlmpUtility.SignKey(flags, exportedSessionKey, "Server");
            this.client.Context.ClientSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Client");
            this.client.Context.ServerSealingKey = NlmpUtility.SealKey(flags, exportedSessionKey, "Server");

            NlmpUtility.RC4Init(this.client.Context.ClientHandle, this.client.Context.ClientSealingKey);
            NlmpUtility.RC4Init(this.client.Context.ServerHandle, this.client.Context.ServerSealingKey);
        }
        /// <summary>
        /// initialize the response of challenge
        /// </summary>
        /// <param name="flags">the flag for challenge</param>
        /// <param name="challenge">the challenge packet</param>
        /// <param name="targetInfo">the target info of avpairs</param>
        /// <param name="responseKeyLM">the response lm key</param>
        /// <param name="lmChallengeResponse">the challenge lm response</param>
        /// <param name="ntChallengeResponse">the nt challenge response</param>
        private void InitializeChallengeResponse(
            NegotiateTypes flags,
            NlmpChallengePacket challenge,
            ICollection<AV_PAIR> targetInfo,
            out byte[] responseKeyLM,
            out byte[] lmChallengeResponse,
            out byte[] ntChallengeResponse
            )
        {
            // responseKeyNT
            byte[] responseKeyNT = NlmpUtility.GetResponseKeyNt(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // responseKeyLM
            responseKeyLM = NlmpUtility.GetResponseKeyLm(
                this.client.Config.Version, this.currentActiveCredential.DomainName,
                this.currentActiveCredential.AccountName, this.currentActiveCredential.Password);

            // lmChallengeResponse
            lmChallengeResponse = null;

            // ntChallengeResponse
            ntChallengeResponse = null;

            ComputeResponse(
                flags, challenge.Payload.ServerChallenge, targetInfo, responseKeyNT, responseKeyLM,
                out lmChallengeResponse, out ntChallengeResponse);

            UpdateLmChallengeResponse(challenge.Payload.TargetInfo, ref lmChallengeResponse);
        }
        /// <summary>
        /// initialize the mic of challenge packet
        /// </summary>
        /// <param name="exportedSessionKey">the exported session key</param>
        /// <param name="targetInfo">the target info contains av pairs.</param>
        /// <param name="authenticatePacket">the authenticate packet</param>
        /// <param name="challengePacket">the challenge packet</param>
        private void InitializeChallengeMIC(
            byte[] exportedSessionKey,
            ICollection<AV_PAIR> targetInfo,
            NlmpAuthenticatePacket authenticatePacket,
            NlmpChallengePacket challengePacket
            )
        {
            if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvTimestamp))
            {
                // update mic with security algorithm
                byte[] mic = null;
                // if connectionless, this.negotiate is null.
                mic = NlmpUtility.GetMic(exportedSessionKey, this.negotiate, challengePacket, authenticatePacket);

                // get payload of packet
                AUTHENTICATE_MESSAGE payload = authenticatePacket.Payload;

                // update mic to payload
                payload.MIC = mic;

                // update the meaningful payload to packet
                authenticatePacket.Payload = payload;
            }
        }
        /// <summary>
        /// get the security token,using the token from server
        /// </summary>
        /// <param name="serverToken">the token from server challenge</param>
        /// <returns>the security token</returns>
        private byte[] GetSecurityToken(
            byte[] serverToken
            )
        {
            if (this.client == null)
            {
                throw new InvalidOperationException("The client is null! You must initialize this field first!");
            }

            NegotiateTypes flags = InitializeNegotiateFlags();

            // the challenge packet from server
            NlmpChallengePacket challenge = new NlmpChallengePacket(serverToken);

            // the target info
            ICollection<AV_PAIR> targetInfo = InitializeTargetInfo(challenge.Payload.TargetInfo);

            // responseKeyLM
            byte[] responseKeyLM;

            // lmChallengeResponse
            byte[] lmChallengeResponse;

            // ntChallengeResponse
            byte[] ntChallengeResponse;

            // initiliaze the challenge response
            InitializeChallengeResponse(
                flags, challenge, targetInfo, out responseKeyLM, out lmChallengeResponse, out ntChallengeResponse);

            // encryptedRandomSessionKey
            byte[] encryptedRandomSessionKey = null;

            // exportedSessionKey
            byte[] exportedSessionKey = null;

            // initialize keys
            InitializeKeys(
                flags, challenge, responseKeyLM, lmChallengeResponse, out encryptedRandomSessionKey,
                out exportedSessionKey);

            // save the exported sessionkey
            this.client.Context.ExportedSessionKey = exportedSessionKey;

            // create challenge packet
            NlmpAuthenticatePacket packet = this.client.CreateAuthenticatePacket(
                    flags, NlmpUtility.GetVersion(), lmChallengeResponse, ntChallengeResponse,
                    this.currentActiveCredential.DomainName, this.currentActiveCredential.AccountName,
                    Environment.MachineName, encryptedRandomSessionKey);

            // initialize the mic of challenge packet
            InitializeChallengeMIC(exportedSessionKey, targetInfo, packet, challenge);

            return packet.ToBytes();
        }
        /// <summary>
        /// create a challenge packet. This packet contains CHALLENGE_MESSAGE. The CHALLENGE_MESSAGE defines an NTLM 
        /// challenge message that is sent from the server to the client. The CHALLENGE_MESSAGE is used by the server  
        /// to challenge the client to prove its identity.
        /// </summary>
        /// <param name="negotiateFlags">The client sets flags to indicate options it supports.</param>
        /// <param name="version">
        /// This structure is used for debugging purposes only. In normal (non-debugging) protocol messages, it is
        /// ignored and does not affect the NTLM message processing.
        /// </param>
        /// <param name="serverChallenge">contains the NTLM challenge. The challenge is a 64-bit nonce.</param>
        /// <param name="targetName">
        /// TargetName contains the name of the server authentication realm, and MUST be expressed in the negotiated 
        /// character set. A server that is a member of a domain returns the domain of which it is a member, and a 
        /// server that is not a member of a domain returns the server name. This param can be null.
        /// </param>
        /// <param name="targetInfo">
        /// TargetInfo contains a sequence of AV_PAIR structures.This param can be null.
        /// </param>
        /// <returns>the NlmpChallengePacket</returns>
        /// <noException></noException>
        public NlmpChallengePacket CreateChallengePacket(
            NegotiateTypes negotiateFlags,
            VERSION version,
            ulong serverChallenge,
            string targetName,
            ICollection<AV_PAIR> targetInfo
            )
        {
            NlmpChallengePacket packet = new NlmpChallengePacket();

            packet.SetNegotiateFlags(negotiateFlags);

            if (NlmpUtility.IsVersionRequired(negotiateFlags))
            {
                packet.SetVersion(version);
            }

            packet.SetServerChallenge(serverChallenge);

            if (NlmpUtility.IsDomainType(negotiateFlags) || NlmpUtility.IsServerType(negotiateFlags))
            {
                packet.SetTargetName(targetName);
            }

            // generate bytes of targetinfo
            byte[] targetInfoBytes = NlmpUtility.AvPairCollectionGetBytes(targetInfo);

            // initialize targetinfofield
            packet.SetTargetInfo(targetInfoBytes);

            return packet;
        }
        /// <summary>
        /// accept the negotiate packet, generated the challenge packet.
        /// </summary>
        /// <param name="negotiatePacket">the negotiate packet</param>
        private void AcceptNegotiatePacket(NlmpNegotiatePacket negotiatePacket)
        {
            // save the negotiate, to valid the mic when authenticate.
            this.negotiate = negotiatePacket;

            // generated negotiate flags for challenge packet
            NegotiateTypes negotiateFlags = GeneratedNegotiateFlags(negotiatePacket);

            // initialize target name
            string targetName = GenerateTargetName();

            // initialize av pairs.
            ICollection<AV_PAIR> targetInfo = GenerateTargetInfo();

            VERSION sspiVersion = NlmpUtility.GetVersion();
            // the serverChallenge is 8 bytes.
            ulong serverChallenge = BitConverter.ToUInt64(NlmpUtility.Nonce(8), 0);

            NlmpChallengePacket challengePacket = this.nlmpServer.CreateChallengePacket(
                negotiateFlags, sspiVersion, serverChallenge, targetName, targetInfo);

            this.challenge = challengePacket;
            this.token = challengePacket.ToBytes();
        }
        /// <summary>
        /// Update ServerChallenge to this context
        /// </summary>
        /// <param name="serverChallenge">the serverChallenge to update</param>
        public void UpdateServerChallenge(ulong serverChallenge)
        {
            #region Prepare the Nlmp Negotiate Flags

            // the flags for negotiage
            NegotiateTypes nlmpFlags = NegotiateTypes.NTLMSSP_NEGOTIATE_NTLM | NegotiateTypes.NTLM_NEGOTIATE_OEM;

            #endregion

            #region Prepare the ServerName

            List<AV_PAIR> pairs = new List<AV_PAIR>();

            NlmpUtility.AddAVPair(pairs, AV_PAIR_IDs.MsvAvEOL, 0x00, null);

            #endregion

            this.challenge = this.nlmpServer.CreateChallengePacket(nlmpFlags, NlmpUtility.GetVersion(), serverChallenge,
                GenerateTargetName(), pairs);
            this.token = this.challenge.ToBytes();
        }