diff --git a/SMBLibrary/Authentication/NTLM/Structures/AuthenticateMessage.cs b/SMBLibrary/Authentication/NTLM/Structures/AuthenticateMessage.cs index b09ffed..060308a 100644 --- a/SMBLibrary/Authentication/NTLM/Structures/AuthenticateMessage.cs +++ b/SMBLibrary/Authentication/NTLM/Structures/AuthenticateMessage.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2017 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2020 Tal Aloni . All rights reserved. * * You can redistribute this program and/or modify it under the terms of * the GNU Lesser Public License as published by the Free Software Foundation, @@ -28,7 +28,7 @@ namespace SMBLibrary.Authentication.NTLM public byte[] EncryptedRandomSessionKey; public NegotiateFlags NegotiateFlags; public NTLMVersion Version; - // 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003 + public byte[] MIC; // 16-byte MIC field is omitted for Windows NT / 2000 / XP / Server 2003 public AuthenticateMessage() { @@ -51,10 +51,47 @@ namespace SMBLibrary.Authentication.NTLM WorkStation = AuthenticationMessageUtils.ReadUnicodeStringBufferPointer(buffer, 44); EncryptedRandomSessionKey = AuthenticationMessageUtils.ReadBufferPointer(buffer, 52); NegotiateFlags = (NegotiateFlags)LittleEndianConverter.ToUInt32(buffer, 60); + int offset = 64; if ((NegotiateFlags & NegotiateFlags.Version) > 0) { - Version = new NTLMVersion(buffer, 64); + Version = new NTLMVersion(buffer, offset); + offset += NTLMVersion.Length; } + if (HasMicField()) + { + MIC = ByteReader.ReadBytes(buffer, offset, 16); + } + } + + public bool HasMicField() + { + if (!AuthenticationMessageUtils.IsNTLMv2NTResponse(NtChallengeResponse)) + { + return false; + } + + NTLMv2ClientChallenge challenge; + try + { + challenge = new NTLMv2ClientChallenge(NtChallengeResponse, 16); + } + catch + { + return false; + } + + int index = challenge.AVPairs.IndexOfKey(AVPairKey.Flags); + if (index >= 0) + { + byte[] value = challenge.AVPairs[index].Value; + if (value.Length == 4) + { + int flags = LittleEndianConverter.ToInt32(value, 0); + return (flags & 0x02) > 0; + } + } + + return false; } public byte[] GetBytes() @@ -69,17 +106,27 @@ namespace SMBLibrary.Authentication.NTLM { fixedLength += NTLMVersion.Length; } + if (MIC != null) + { + fixedLength += MIC.Length; + } int payloadLength = LmChallengeResponse.Length + NtChallengeResponse.Length + DomainName.Length * 2 + UserName.Length * 2 + WorkStation.Length * 2 + EncryptedRandomSessionKey.Length; byte[] buffer = new byte[fixedLength + payloadLength]; ByteWriter.WriteAnsiString(buffer, 0, ValidSignature, 8); LittleEndianWriter.WriteUInt32(buffer, 8, (uint)MessageType); LittleEndianWriter.WriteUInt32(buffer, 60, (uint)NegotiateFlags); + int offset = 64; if ((NegotiateFlags & NegotiateFlags.Version) > 0) { - Version.WriteBytes(buffer, 64); + Version.WriteBytes(buffer, offset); + offset += NTLMVersion.Length; + } + if (MIC != null) + { + ByteWriter.WriteBytes(buffer, offset, MIC); + offset += MIC.Length; } - int offset = fixedLength; AuthenticationMessageUtils.WriteBufferPointer(buffer, 12, (ushort)LmChallengeResponse.Length, (uint)offset); ByteWriter.WriteBytes(buffer, ref offset, LmChallengeResponse); AuthenticationMessageUtils.WriteBufferPointer(buffer, 20, (ushort)NtChallengeResponse.Length, (uint)offset);