/// <summary> /// initialize the restriction of target info /// </summary> /// <param name="targetInfo">the target info collection</param> private void InitializeRestriction( ICollection <AV_PAIR> targetInfo ) { // update the MsAvRestrictions of targetInfo // MachineID (32 bytes): A 256-bit random number created at computer // startup to identify the calling machine. Restriction_Encoding restriction = new Restriction_Encoding(); // defines the length, in bytes, of AV_PAIR Value. restriction.Size = 0x30; restriction.MachineID = new byte[NlmpUtility.MACHINE_ID_SIZE]; byte[] restrictionBytes = NlmpUtility.StructGetBytes(restriction); if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsAvRestrictions)) { NlmpUtility.UpdateAvPair( targetInfo, AV_PAIR_IDs.MsAvRestrictions, (ushort)restrictionBytes.Length, restrictionBytes); } else { NlmpUtility.AddAVPair( targetInfo, AV_PAIR_IDs.MsAvRestrictions, (ushort)restrictionBytes.Length, restrictionBytes); } }
//If the ClientChannelBindingsUnhashed (section 3.1.1.2) is not NULL private void InitializeMsAvChannelBindings( ICollection <AV_PAIR> targetInfo ) { // update the MsAvChannelBinding of targetInfo // add an AV_PAIR structure (section 2.2.2.1) and set the AvId field to MsvAvChannelBindings and the Value field to Z(16). var value = NlmpUtility.Z(16); if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvChannelBindings)) { NlmpUtility.UpdateAvPair( targetInfo, AV_PAIR_IDs.MsvChannelBindings, (ushort)value.Length, value); } else { NlmpUtility.AddAVPair( targetInfo, AV_PAIR_IDs.MsvChannelBindings, (ushort)value.Length, value); } }
// If ClientSuppliedTargetName (section 3.1.1.2) is not NULL private void InitializeMsvAvTargetName( ICollection <AV_PAIR> targetInfo ) { // update the MsvAvTargetName of targetInfo // Add an AV_PAIR structure (section 2.2.2.1) and set the AvId field to MsvAvTargetName and the Value field to ClientSuppliedTargetName without terminating NULL. byte[] targetName = NlmpUtility.Unicode(this.credential.TargetName); if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvTargetName)) { NlmpUtility.UpdateAvPair( targetInfo, AV_PAIR_IDs.MsvAvTargetName, (ushort)targetName.Length, targetName); } else { NlmpUtility.AddAVPair( targetInfo, AV_PAIR_IDs.MsvAvTargetName, (ushort)targetName.Length, targetName); } }
/// <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> /// initialize the MsAvFlags of target info /// </summary> /// <param name="targetInfo">the target info collection</param> private void InitializeMsAvFlags( ICollection <AV_PAIR> targetInfo ) { // update the MsvAvFlags of targetInfo if (NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvFlags)) { uint value = NlmpUtility.BytesToSecurityUInt32( NlmpUtility.AvPairGetValue(targetInfo, AV_PAIR_IDs.MsvAvFlags) ); // if AvId field set to MsvAvFlags, set the 0x02 bit to 1. value |= 0x02; byte[] newValue = NlmpUtility.SecurityUInt32GetBytes(value); NlmpUtility.UpdateAvPair(targetInfo, AV_PAIR_IDs.MsvAvFlags, (ushort)newValue.Length, newValue); } else { // if AvId field set to MsvAvFlags, set the 0x02 bit to 1. uint value = 0x02; byte[] newValue = NlmpUtility.SecurityUInt32GetBytes(value); NlmpUtility.AddAVPair(targetInfo, AV_PAIR_IDs.MsvAvFlags, (ushort)newValue.Length, newValue); } }
/// <summary> /// update the lm challenge response /// </summary> /// <param name="targetInfo">the challenge packet</param> /// <param name="lmChallengeResponse">the lm challenge response</param> /// <summary> private void UpdateLmChallengeResponse( ICollection <AV_PAIR> targetInfo, ref byte[] lmChallengeResponse ) { // If NTLM v2 authentication is used and the CHALLENGE_MESSAGE TargetInfo field (section 2.2.1.2) has an MsvAvTimestamp present, // the client SHOULD NOT send the LmChallengeResponse and SHOULD send Z(24) instead if (NlmpUtility.IsNtlmV2(this.client.Config.Version) && targetInfo != null && NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvTimestamp)) { lmChallengeResponse = NlmpUtility.Z(24); } }
/// <summary> /// retrieve the domain name from client. client encode the domain name in the authenticate packet. /// </summary> /// <param name="authenticatePacket">the authenticate packet contains the domain name</param> /// <returns>the authentication information of client</returns> private ClientAuthenticateInfomation RetrieveClientAuthenticateInformation( NlmpAuthenticatePacket authenticatePacket) { ClientAuthenticateInfomation authenticateInformation = new ClientAuthenticateInfomation(); // retrieve the version of client if (authenticatePacket.Payload.NtChallengeResponseFields.Len == NTLM_V1_NT_CHALLENGE_RESPONSE_LENGTH) { authenticateInformation.Version = NlmpVersion.v1; } else { authenticateInformation.Version = NlmpVersion.v2; } // retrieve the client challenge if (authenticateInformation.Version == NlmpVersion.v1) { authenticateInformation.ClientChallenge = BitConverter.ToUInt64(ArrayUtility.SubArray <byte>( authenticatePacket.Payload.LmChallengeResponse, 0, TIME_CLIENT_CHALLENGE_LENGTH), 0); } else { authenticateInformation.ClientChallenge = BitConverter.ToUInt64( ArrayUtility.SubArray <byte>(authenticatePacket.Payload.NtChallengeResponse, NTLM_V2_CLIENT_CHALLENGE_OFFSET_IN_NT_CHALLENGE_RESPONSE, TIME_CLIENT_CHALLENGE_LENGTH), 0); } // retrieve the domain name of client if (NlmpUtility.IsUnicode(authenticatePacket.Payload.NegotiateFlags)) { authenticateInformation.DomainName = Encoding.Unicode.GetString(authenticatePacket.Payload.DomainName); } else { authenticateInformation.DomainName = Encoding.ASCII.GetString(authenticatePacket.Payload.DomainName); } // retrieve the user name of client if (NlmpUtility.IsUnicode(authenticatePacket.Payload.NegotiateFlags)) { authenticateInformation.UserName = Encoding.Unicode.GetString(authenticatePacket.Payload.UserName); } else { authenticateInformation.UserName = Encoding.ASCII.GetString(authenticatePacket.Payload.UserName); } // retrieve the server name of client if (authenticateInformation.Version == NlmpVersion.v2) { authenticateInformation.ServerName = ArrayUtility.SubArray <byte>(authenticatePacket.Payload.NtChallengeResponse, NTLM_V2_SERVER_NAME_OFFSET_IN_NT_CHALLENGE_RESPONSE, authenticatePacket.Payload.NtChallengeResponseFields.Len - NTLM_V2_SERVER_NAME_OFFSET_IN_NT_CHALLENGE_RESPONSE - NTLM_V2_SERVER_NAME_RESERVED_LENGTH_IN_NT_CHALLENGE_RESPONSE); } // retrieve the time of client ICollection <AV_PAIR> targetInfo = NlmpUtility.BytesGetAvPairCollection(this.challenge.Payload.TargetInfo); // retrieve the time authenticateInformation.ClientTime = NlmpUtility.GetTime(targetInfo); // if server did not response the timestamp, use the client time stamp if (!NlmpUtility.AvPairContains(targetInfo, AV_PAIR_IDs.MsvAvTimestamp) && authenticateInformation.Version == NlmpVersion.v2) { authenticateInformation.ClientTime = BitConverter.ToUInt64( ArrayUtility.SubArray <byte>(authenticatePacket.Payload.NtChallengeResponse, NTLM_V2_TIME_STAMP_OFFSET_IN_NT_CHALLENGE_RESPONSE, TIME_STAMP_LENGTH), 0); } return(authenticateInformation); }