NTLM: AuthenticateMessage: Read/Write MIC field if present

This commit is contained in:
TalAloni 2021-01-23 14:41:38 +02:00
parent 2b5be7b291
commit 717f835490

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2017 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
/* Copyright (C) 2014-2020 Tal Aloni <tal.aloni.il@gmail.com>. 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);