mirror of
https://github.com/TalAloni/SMBLibrary.git
synced 2025-07-26 02:38:15 +02:00
Bugfix: Last SessionSetupResponse was not signed, final async response was not signed
This commit is contained in:
parent
9902b91eff
commit
9fe283762a
5 changed files with 35 additions and 15 deletions
|
@ -43,9 +43,9 @@ namespace SMBLibrary.Server
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SMB2Session CreateSession(ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken)
|
public SMB2Session CreateSession(ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken, bool signingRequired)
|
||||||
{
|
{
|
||||||
SMB2Session session = new SMB2Session(this, sessionID, userName, machineName, sessionKey, accessToken);
|
SMB2Session session = new SMB2Session(this, sessionID, userName, machineName, sessionKey, accessToken, signingRequired);
|
||||||
lock (m_sessions)
|
lock (m_sessions)
|
||||||
{
|
{
|
||||||
m_sessions.Add(sessionID, session);
|
m_sessions.Add(sessionID, session);
|
||||||
|
|
|
@ -19,6 +19,7 @@ namespace SMBLibrary.Server
|
||||||
private byte[] m_sessionKey;
|
private byte[] m_sessionKey;
|
||||||
private SecurityContext m_securityContext;
|
private SecurityContext m_securityContext;
|
||||||
private DateTime m_creationDT;
|
private DateTime m_creationDT;
|
||||||
|
private bool m_signingRequired;
|
||||||
|
|
||||||
// Key is TreeID
|
// Key is TreeID
|
||||||
private Dictionary<uint, ISMBShare> m_connectedTrees = new Dictionary<uint, ISMBShare>();
|
private Dictionary<uint, ISMBShare> m_connectedTrees = new Dictionary<uint, ISMBShare>();
|
||||||
|
@ -31,13 +32,14 @@ namespace SMBLibrary.Server
|
||||||
// Key is the volatile portion of the FileID
|
// Key is the volatile portion of the FileID
|
||||||
private Dictionary<ulong, OpenSearch> m_openSearches = new Dictionary<ulong, OpenSearch>();
|
private Dictionary<ulong, OpenSearch> m_openSearches = new Dictionary<ulong, OpenSearch>();
|
||||||
|
|
||||||
public SMB2Session(SMB2ConnectionState connection, ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken)
|
public SMB2Session(SMB2ConnectionState connection, ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken, bool signingRequired)
|
||||||
{
|
{
|
||||||
m_connection = connection;
|
m_connection = connection;
|
||||||
m_sessionID = sessionID;
|
m_sessionID = sessionID;
|
||||||
m_sessionKey = sessionKey;
|
m_sessionKey = sessionKey;
|
||||||
m_securityContext = new SecurityContext(userName, machineName, connection.ClientEndPoint, connection.AuthenticationContext, accessToken);
|
m_securityContext = new SecurityContext(userName, machineName, connection.ClientEndPoint, connection.AuthenticationContext, accessToken);
|
||||||
m_creationDT = DateTime.Now;
|
m_creationDT = DateTime.Now;
|
||||||
|
m_signingRequired = signingRequired;
|
||||||
}
|
}
|
||||||
|
|
||||||
private uint? AllocateTreeID()
|
private uint? AllocateTreeID()
|
||||||
|
@ -245,5 +247,13 @@ namespace SMBLibrary.Server
|
||||||
return m_creationDT;
|
return m_creationDT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool SigningRequired
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return m_signingRequired;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,6 +59,7 @@ namespace SMBLibrary.Server.SMB2
|
||||||
ChangeNotifyResponse response = new ChangeNotifyResponse();
|
ChangeNotifyResponse response = new ChangeNotifyResponse();
|
||||||
response.Header.Status = status;
|
response.Header.Status = status;
|
||||||
response.Header.IsAsync = true;
|
response.Header.IsAsync = true;
|
||||||
|
response.Header.IsSigned = session.SigningRequired;
|
||||||
response.Header.AsyncID = asyncContext.AsyncID;
|
response.Header.AsyncID = asyncContext.AsyncID;
|
||||||
response.Header.SessionID = asyncContext.SessionID;
|
response.Header.SessionID = asyncContext.SessionID;
|
||||||
response.OutputBuffer = buffer;
|
response.OutputBuffer = buffer;
|
||||||
|
|
|
@ -66,12 +66,13 @@ namespace SMBLibrary.Server.SMB2
|
||||||
if (!isGuest.HasValue || !isGuest.Value)
|
if (!isGuest.HasValue || !isGuest.Value)
|
||||||
{
|
{
|
||||||
state.LogToServer(Severity.Information, "Session Setup: User '{0}' authenticated successfully (Domain: '{1}', Workstation: '{2}', OS version: '{3}').", userName, domainName, machineName, osVersion);
|
state.LogToServer(Severity.Information, "Session Setup: User '{0}' authenticated successfully (Domain: '{1}', Workstation: '{2}', OS version: '{3}').", userName, domainName, machineName, osVersion);
|
||||||
state.CreateSession(request.Header.SessionID, userName, machineName, sessionKey, accessToken);
|
bool signingRequired = (request.SecurityMode == SecurityMode.SigningRequired);
|
||||||
|
state.CreateSession(request.Header.SessionID, userName, machineName, sessionKey, accessToken, signingRequired);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), logged in as guest.", userName, domainName, machineName, osVersion);
|
state.LogToServer(Severity.Information, "Session Setup: User '{0}' failed authentication (Domain: '{1}', Workstation: '{2}', OS version: '{3}'), logged in as guest.", userName, domainName, machineName, osVersion);
|
||||||
state.CreateSession(request.Header.SessionID, "Guest", machineName, sessionKey, accessToken);
|
state.CreateSession(request.Header.SessionID, "Guest", machineName, sessionKey, accessToken, false);
|
||||||
response.SessionFlags = SessionFlags.IsGuest;
|
response.SessionFlags = SessionFlags.IsGuest;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ namespace SMBLibrary.Server
|
||||||
SMB2Command response = ProcessSMB2Command(request, ref state);
|
SMB2Command response = ProcessSMB2Command(request, ref state);
|
||||||
if (response != null)
|
if (response != null)
|
||||||
{
|
{
|
||||||
UpdateSMB2Header(response, request);
|
UpdateSMB2Header(response, request, state);
|
||||||
responseChain.Add(response);
|
responseChain.Add(response);
|
||||||
if (!request.Header.IsRelatedOperations)
|
if (!request.Header.IsRelatedOperations)
|
||||||
{
|
{
|
||||||
|
@ -185,10 +185,9 @@ namespace SMBLibrary.Server
|
||||||
|
|
||||||
internal static void EnqueueResponse(ConnectionState state, SMB2Command response)
|
internal static void EnqueueResponse(ConnectionState state, SMB2Command response)
|
||||||
{
|
{
|
||||||
SessionMessagePacket packet = new SessionMessagePacket();
|
List<SMB2Command> responseChain = new List<SMB2Command>();
|
||||||
packet.Trailer = response.GetBytes();
|
responseChain.Add(response);
|
||||||
state.SendQueue.Enqueue(packet);
|
EnqueueResponseChain(state, responseChain);
|
||||||
state.LogToServer(Severity.Verbose, "SMB2 response queued: {0}, Packet length: {1}", response.CommandName.ToString(), packet.Length);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void EnqueueResponseChain(ConnectionState state, List<SMB2Command> responseChain)
|
private static void EnqueueResponseChain(ConnectionState state, List<SMB2Command> responseChain)
|
||||||
|
@ -216,16 +215,12 @@ namespace SMBLibrary.Server
|
||||||
state.LogToServer(Severity.Verbose, "SMB2 response chain queued: Response count: {0}, First response: {1}, Packet length: {2}", responseChain.Count, responseChain[0].CommandName.ToString(), packet.Length);
|
state.LogToServer(Severity.Verbose, "SMB2 response chain queued: Response count: {0}, First response: {1}, Packet length: {2}", responseChain.Count, responseChain[0].CommandName.ToString(), packet.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateSMB2Header(SMB2Command response, SMB2Command request)
|
private static void UpdateSMB2Header(SMB2Command response, SMB2Command request, ConnectionState state)
|
||||||
{
|
{
|
||||||
response.Header.MessageID = request.Header.MessageID;
|
response.Header.MessageID = request.Header.MessageID;
|
||||||
response.Header.CreditCharge = request.Header.CreditCharge;
|
response.Header.CreditCharge = request.Header.CreditCharge;
|
||||||
response.Header.Credits = Math.Max((ushort)1, request.Header.Credits);
|
response.Header.Credits = Math.Max((ushort)1, request.Header.Credits);
|
||||||
response.Header.IsRelatedOperations = request.Header.IsRelatedOperations;
|
response.Header.IsRelatedOperations = request.Header.IsRelatedOperations;
|
||||||
// [MS-SMB2] The server SHOULD sign the message [..] if the request was signed by the client,
|
|
||||||
// and the response is not an interim response to an asynchronously processed request.
|
|
||||||
bool isInterimResponse = (request.Header.IsAsync && request.Header.Status == NTStatus.STATUS_PENDING);
|
|
||||||
response.Header.IsSigned = request.Header.IsSigned && !isInterimResponse;
|
|
||||||
response.Header.Reserved = request.Header.Reserved;
|
response.Header.Reserved = request.Header.Reserved;
|
||||||
if (response.Header.SessionID == 0)
|
if (response.Header.SessionID == 0)
|
||||||
{
|
{
|
||||||
|
@ -235,6 +230,19 @@ namespace SMBLibrary.Server
|
||||||
{
|
{
|
||||||
response.Header.TreeID = request.Header.TreeID;
|
response.Header.TreeID = request.Header.TreeID;
|
||||||
}
|
}
|
||||||
|
bool signingRequired = false;
|
||||||
|
if (state is SMB2ConnectionState)
|
||||||
|
{
|
||||||
|
SMB2Session session = ((SMB2ConnectionState)state).GetSession(response.Header.SessionID);
|
||||||
|
if (session != null && session.SigningRequired)
|
||||||
|
{
|
||||||
|
signingRequired = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// [MS-SMB2] The server SHOULD sign the message [..] if the request was signed by the client,
|
||||||
|
// and the response is not an interim response to an asynchronously processed request.
|
||||||
|
bool isInterimResponse = (response.Header.IsAsync && response.Header.Status == NTStatus.STATUS_PENDING);
|
||||||
|
response.Header.IsSigned = (request.Header.IsSigned || signingRequired) && !isInterimResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetRequestFileID(SMB2Command command, FileID fileID)
|
private static void SetRequestFileID(SMB2Command command, FileID fileID)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue