/// <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(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> /// 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()); }
/// <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(); }
/// <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> /// 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 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(); }