From dd026cf704b46e978206cc72aca37d81c06e8fdf Mon Sep 17 00:00:00 2001 From: Tal Aloni Date: Thu, 27 Jul 2023 23:14:11 +0300 Subject: [PATCH] Client: Support anonymous login --- .../Helpers/NTLMAuthenticationHelper.cs | 43 ++++++++++++++----- SMBLibrary/Client/SMB1Client.cs | 2 +- SMBLibrary/Client/SMB2Client.cs | 2 +- 3 files changed, 35 insertions(+), 12 deletions(-) diff --git a/SMBLibrary/Client/Helpers/NTLMAuthenticationHelper.cs b/SMBLibrary/Client/Helpers/NTLMAuthenticationHelper.cs index 1a0c670..184194b 100644 --- a/SMBLibrary/Client/Helpers/NTLMAuthenticationHelper.cs +++ b/SMBLibrary/Client/Helpers/NTLMAuthenticationHelper.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2018 Tal Aloni . All rights reserved. +/* Copyright (C) 2017-2023 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, @@ -15,7 +15,7 @@ namespace SMBLibrary.Client { public class NTLMAuthenticationHelper { - public static byte[] GetNegotiateMessage(byte[] securityBlob, string domainName, AuthenticationMethod authenticationMethod) + public static byte[] GetNegotiateMessage(byte[] securityBlob, string domainName, string userName, string password, AuthenticationMethod authenticationMethod) { bool useGSSAPI = false; if (securityBlob.Length > 0) @@ -46,9 +46,13 @@ namespace SMBLibrary.Client NegotiateFlags.AlwaysSign | NegotiateFlags.Version | NegotiateFlags.Use128BitEncryption | - NegotiateFlags.KeyExchange | NegotiateFlags.Use56BitEncryption; + if (!(userName == String.Empty && password == String.Empty)) + { + negotiateMessage.NegotiateFlags |= NegotiateFlags.KeyExchange; + } + if (authenticationMethod == AuthenticationMethod.NTLMv1) { negotiateMessage.NegotiateFlags |= NegotiateFlags.LanManagerSessionKey; @@ -139,6 +143,11 @@ namespace SMBLibrary.Client authenticateMessage.NegotiateFlags |= NegotiateFlags.ExtendedSessionSecurity; } + if (userName == String.Empty && password == String.Empty) + { + authenticateMessage.NegotiateFlags |= NegotiateFlags.Anonymous; + } + authenticateMessage.UserName = userName; authenticateMessage.DomainName = domainName; authenticateMessage.WorkStation = Environment.MachineName; @@ -146,7 +155,13 @@ namespace SMBLibrary.Client byte[] keyExchangeKey; if (authenticationMethod == AuthenticationMethod.NTLMv1 || authenticationMethod == AuthenticationMethod.NTLMv1ExtendedSessionSecurity) { - if (authenticationMethod == AuthenticationMethod.NTLMv1) + // https://msdn.microsoft.com/en-us/library/cc236699.aspx + if (userName == String.Empty && password == String.Empty) + { + authenticateMessage.LmChallengeResponse = new byte[1]; + authenticateMessage.NtChallengeResponse = new byte[0]; + } + else if (authenticationMethod == AuthenticationMethod.NTLMv1) { authenticateMessage.LmChallengeResponse = NTLMCryptography.ComputeLMv1Response(challengeMessage.ServerChallenge, password); authenticateMessage.NtChallengeResponse = NTLMCryptography.ComputeNTLMv1Response(challengeMessage.ServerChallenge, password); @@ -156,25 +171,33 @@ namespace SMBLibrary.Client authenticateMessage.LmChallengeResponse = ByteUtils.Concatenate(clientChallenge, new byte[16]); authenticateMessage.NtChallengeResponse = NTLMCryptography.ComputeNTLMv1ExtendedSessionSecurityResponse(challengeMessage.ServerChallenge, clientChallenge, password); } - // https://msdn.microsoft.com/en-us/library/cc236699.aspx + sessionBaseKey = new MD4().GetByteHashFromBytes(NTLMCryptography.NTOWFv1(password)); byte[] lmowf = NTLMCryptography.LMOWFv1(password); keyExchangeKey = NTLMCryptography.KXKey(sessionBaseKey, authenticateMessage.NegotiateFlags, authenticateMessage.LmChallengeResponse, challengeMessage.ServerChallenge, lmowf); } else // NTLMv2 { + // https://msdn.microsoft.com/en-us/library/cc236700.aspx NTLMv2ClientChallenge clientChallengeStructure = new NTLMv2ClientChallenge(time, clientChallenge, challengeMessage.TargetInfo, spn); byte[] clientChallengeStructurePadded = clientChallengeStructure.GetBytesPadded(); byte[] ntProofStr = NTLMCryptography.ComputeNTLMv2Proof(challengeMessage.ServerChallenge, clientChallengeStructurePadded, password, userName, domainName); - - authenticateMessage.LmChallengeResponse = NTLMCryptography.ComputeLMv2Response(challengeMessage.ServerChallenge, clientChallenge, password, userName, challengeMessage.TargetName); - authenticateMessage.NtChallengeResponse = ByteUtils.Concatenate(ntProofStr, clientChallengeStructurePadded); - - // https://msdn.microsoft.com/en-us/library/cc236700.aspx + if (userName == String.Empty && password == String.Empty) + { + authenticateMessage.LmChallengeResponse = new byte[1]; + authenticateMessage.NtChallengeResponse = new byte[0]; + } + else + { + authenticateMessage.LmChallengeResponse = NTLMCryptography.ComputeLMv2Response(challengeMessage.ServerChallenge, clientChallenge, password, userName, challengeMessage.TargetName); + authenticateMessage.NtChallengeResponse = ByteUtils.Concatenate(ntProofStr, clientChallengeStructurePadded); + } + byte[] responseKeyNT = NTLMCryptography.NTOWFv2(password, userName, domainName); sessionBaseKey = new HMACMD5(responseKeyNT).ComputeHash(ntProofStr); keyExchangeKey = sessionBaseKey; } + authenticateMessage.Version = NTLMVersion.Server2003; // https://msdn.microsoft.com/en-us/library/cc236676.aspx diff --git a/SMBLibrary/Client/SMB1Client.cs b/SMBLibrary/Client/SMB1Client.cs index 13e2e1c..175f68d 100644 --- a/SMBLibrary/Client/SMB1Client.cs +++ b/SMBLibrary/Client/SMB1Client.cs @@ -289,7 +289,7 @@ namespace SMBLibrary.Client } else // m_securityBlob != null { - byte[] negotiateMessage = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, authenticationMethod); + byte[] negotiateMessage = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, userName, password, authenticationMethod); if (negotiateMessage == null) { return NTStatus.SEC_E_INVALID_TOKEN; diff --git a/SMBLibrary/Client/SMB2Client.cs b/SMBLibrary/Client/SMB2Client.cs index ea26421..2e3eeb7 100644 --- a/SMBLibrary/Client/SMB2Client.cs +++ b/SMBLibrary/Client/SMB2Client.cs @@ -214,7 +214,7 @@ namespace SMBLibrary.Client throw new InvalidOperationException("A connection must be successfully established before attempting login"); } - byte[] negotiateMessage = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, authenticationMethod); + byte[] negotiateMessage = NTLMAuthenticationHelper.GetNegotiateMessage(m_securityBlob, domainName, userName, password, authenticationMethod); if (negotiateMessage == null) { return NTStatus.SEC_E_INVALID_TOKEN;