mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-04-29 18:27:48 +02:00
IsNTLMv1ExtendedSecurity and IsNTLMv2NTResponse methods added to AuthenticationMessageUtils
This commit is contained in:
parent
f6feaced77
commit
6772c0c33e
4 changed files with 65 additions and 25 deletions
|
@ -58,6 +58,36 @@ namespace SMBLibrary.Authentication
|
|||
return (signature == AuthenticateMessage.ValidSignature);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// If NTLM v1 Extended Security is used, LMResponse starts with 8-byte challenge, followed by 16 bytes of padding (set to zero).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// LMResponse is 24 bytes for NTLM v1, NTLM v1 Extended Security and NTLM v2.
|
||||
/// </remarks>
|
||||
public static bool IsNTLMv1ExtendedSecurity(byte[] lmResponse)
|
||||
{
|
||||
if (lmResponse.Length == 24)
|
||||
{
|
||||
if (ByteUtils.AreByteArraysEqual(ByteReader.ReadBytes(lmResponse, 0, 8), new byte[8]))
|
||||
{
|
||||
// Challenge not present, cannot be NTLM v1 Extended Security
|
||||
return false;
|
||||
}
|
||||
return ByteUtils.AreByteArraysEqual(ByteReader.ReadBytes(lmResponse, 8, 16), new byte[16]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <remarks>
|
||||
/// NTLM v1 / NTLM v1 Extended Security NTResponse is 24 bytes.
|
||||
/// </remarks>
|
||||
public static bool IsNTLMv2NTResponse(byte[] ntResponse)
|
||||
{
|
||||
return (ntResponse.Length >= 48 &&
|
||||
ntResponse[16] == NTLMv2ClientChallenge.StructureVersion &&
|
||||
ntResponse[17] == NTLMv2ClientChallenge.StructureVersion);
|
||||
}
|
||||
|
||||
public static MessageTypeName GetMessageType(byte[] messageBytes)
|
||||
{
|
||||
return (MessageTypeName)LittleEndianConverter.ToUInt32(messageBytes, 8);
|
||||
|
|
|
@ -96,7 +96,7 @@ namespace SMBLibrary.Server
|
|||
return this[index];
|
||||
}
|
||||
|
||||
if (ntResponse.Length >= 48)
|
||||
if (AuthenticationMessageUtils.IsNTLMv2NTResponse(ntResponse))
|
||||
{
|
||||
byte[] clientNTProof = ByteReader.ReadBytes(ntResponse, 0, 16);
|
||||
byte[] clientChallengeStructurePadded = ByteReader.ReadBytes(ntResponse, 16, ntResponse.Length - 16);
|
||||
|
@ -161,8 +161,12 @@ namespace SMBLibrary.Server
|
|||
User user;
|
||||
if ((message.NegotiateFlags & NegotiateFlags.ExtendedSecurity) > 0)
|
||||
{
|
||||
user = AuthenticateV1Extended(message.UserName, m_serverChallenge, message.LmChallengeResponse, message.NtChallengeResponse);
|
||||
if (user == null)
|
||||
if (AuthenticationMessageUtils.IsNTLMv1ExtendedSecurity(message.LmChallengeResponse))
|
||||
{
|
||||
// NTLM v1 Extended Security:
|
||||
user = AuthenticateV1Extended(message.UserName, m_serverChallenge, message.LmChallengeResponse, message.NtChallengeResponse);
|
||||
}
|
||||
else
|
||||
{
|
||||
// NTLM v2:
|
||||
user = AuthenticateV2(message.DomainName, message.UserName, m_serverChallenge, message.LmChallengeResponse, message.NtChallengeResponse);
|
||||
|
|
|
@ -183,7 +183,8 @@ namespace SMBLibrary.Server.SMB1
|
|||
NegotiateFlags.Version |
|
||||
NegotiateFlags.Use128BitEncryption |
|
||||
NegotiateFlags.Use56BitEncryption;
|
||||
if (ntChallengeResponse.Length >= 48)
|
||||
if (AuthenticationMessageUtils.IsNTLMv1ExtendedSecurity(lmChallengeResponse) ||
|
||||
AuthenticationMessageUtils.IsNTLMv2NTResponse(ntChallengeResponse))
|
||||
{
|
||||
authenticateMessage.NegotiateFlags |= NegotiateFlags.ExtendedSecurity;
|
||||
}
|
||||
|
|
|
@ -82,32 +82,37 @@ namespace SMBLibrary.Server.Win32
|
|||
|
||||
if ((message.NegotiateFlags & NegotiateFlags.ExtendedSecurity) > 0)
|
||||
{
|
||||
// NTLM v1 extended security:
|
||||
byte[] clientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 0, 8);
|
||||
byte[] emptyPasswordNTLMv1Response = NTAuthentication.ComputeNTLMv1ExtendedSecurityResponse(m_serverChallenge, clientChallenge, String.Empty);
|
||||
if (ByteUtils.AreByteArraysEqual(emptyPasswordNTLMv1Response, message.NtChallengeResponse))
|
||||
if (AuthenticationMessageUtils.IsNTLMv1ExtendedSecurity(message.LmChallengeResponse))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// NTLM v2:
|
||||
byte[] _LMv2ClientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 16, 8);
|
||||
byte[] emptyPasswordLMv2Response = NTAuthentication.ComputeLMv2Response(m_serverChallenge, _LMv2ClientChallenge, String.Empty, message.UserName, message.DomainName);
|
||||
if (ByteUtils.AreByteArraysEqual(emptyPasswordLMv2Response, message.LmChallengeResponse))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.NtChallengeResponse.Length >= 48)
|
||||
{
|
||||
byte[] clientNTProof = ByteReader.ReadBytes(message.NtChallengeResponse, 0, 16);
|
||||
byte[] clientChallengeStructurePadded = ByteReader.ReadBytes(message.NtChallengeResponse, 16, message.NtChallengeResponse.Length - 16);
|
||||
byte[] emptyPasswordNTProof = NTAuthentication.ComputeNTLMv2Proof(m_serverChallenge, clientChallengeStructurePadded, String.Empty, message.UserName, message.DomainName);
|
||||
if (ByteUtils.AreByteArraysEqual(clientNTProof, emptyPasswordNTProof))
|
||||
// NTLM v1 extended security:
|
||||
byte[] clientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 0, 8);
|
||||
byte[] emptyPasswordNTLMv1Response = NTAuthentication.ComputeNTLMv1ExtendedSecurityResponse(m_serverChallenge, clientChallenge, String.Empty);
|
||||
if (ByteUtils.AreByteArraysEqual(emptyPasswordNTLMv1Response, message.NtChallengeResponse))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// NTLM v2:
|
||||
byte[] _LMv2ClientChallenge = ByteReader.ReadBytes(message.LmChallengeResponse, 16, 8);
|
||||
byte[] emptyPasswordLMv2Response = NTAuthentication.ComputeLMv2Response(m_serverChallenge, _LMv2ClientChallenge, String.Empty, message.UserName, message.DomainName);
|
||||
if (ByteUtils.AreByteArraysEqual(emptyPasswordLMv2Response, message.LmChallengeResponse))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (AuthenticationMessageUtils.IsNTLMv2NTResponse(message.NtChallengeResponse))
|
||||
{
|
||||
byte[] clientNTProof = ByteReader.ReadBytes(message.NtChallengeResponse, 0, 16);
|
||||
byte[] clientChallengeStructurePadded = ByteReader.ReadBytes(message.NtChallengeResponse, 16, message.NtChallengeResponse.Length - 16);
|
||||
byte[] emptyPasswordNTProof = NTAuthentication.ComputeNTLMv2Proof(m_serverChallenge, clientChallengeStructurePadded, String.Empty, message.UserName, message.DomainName);
|
||||
if (ByteUtils.AreByteArraysEqual(clientNTProof, emptyPasswordNTProof))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue