Server: Use SMB2Cryptography.GenerateSigningKey instead of using SessionKey

This commit is contained in:
TalAloni 2020-11-28 21:56:48 +02:00
parent d50ce6f710
commit 7438ccdf4f
4 changed files with 25 additions and 13 deletions

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2014-2019 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 * 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, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -43,9 +43,9 @@ namespace SMBLibrary.Server
return null; return null;
} }
public SMB2Session CreateSession(ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken, bool signingRequired) public SMB2Session CreateSession(ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken, bool signingRequired, byte[] signingKey)
{ {
SMB2Session session = new SMB2Session(this, sessionID, userName, machineName, sessionKey, accessToken, signingRequired); SMB2Session session = new SMB2Session(this, sessionID, userName, machineName, sessionKey, accessToken, signingRequired, signingKey);
lock (m_sessions) lock (m_sessions)
{ {
m_sessions.Add(sessionID, session); m_sessions.Add(sessionID, session);

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 * 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, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -20,6 +20,7 @@ namespace SMBLibrary.Server
private SecurityContext m_securityContext; private SecurityContext m_securityContext;
private DateTime m_creationDT; private DateTime m_creationDT;
private bool m_signingRequired; private bool m_signingRequired;
private byte[] m_signingKey;
// 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>();
@ -32,7 +33,7 @@ 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, bool signingRequired) public SMB2Session(SMB2ConnectionState connection, ulong sessionID, string userName, string machineName, byte[] sessionKey, object accessToken, bool signingRequired, byte[] signingKey)
{ {
m_connection = connection; m_connection = connection;
m_sessionID = sessionID; m_sessionID = sessionID;
@ -40,6 +41,7 @@ namespace SMBLibrary.Server
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.UtcNow; m_creationDT = DateTime.UtcNow;
m_signingRequired = signingRequired; m_signingRequired = signingRequired;
m_signingKey = signingKey;
} }
private uint? AllocateTreeID() private uint? AllocateTreeID()
@ -256,5 +258,13 @@ namespace SMBLibrary.Server
return m_signingRequired; return m_signingRequired;
} }
} }
public byte[] SigningKey
{
get
{
return m_signingKey;
}
}
} }
} }

View file

@ -1,4 +1,4 @@
/* Copyright (C) 2017-2019 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved. /* Copyright (C) 2017-2020 Tal Aloni <tal.aloni.il@gmail.com>. All rights reserved.
* *
* You can redistribute this program and/or modify it under the terms of * 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, * the GNU Lesser Public License as published by the Free Software Foundation,
@ -67,12 +67,14 @@ namespace SMBLibrary.Server.SMB2
{ {
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);
bool signingRequired = (request.SecurityMode & SecurityMode.SigningRequired) > 0; bool signingRequired = (request.SecurityMode & SecurityMode.SigningRequired) > 0;
state.CreateSession(request.Header.SessionID, userName, machineName, sessionKey, accessToken, signingRequired); SMB2Dialect smb2Dialect = SMBServer.ToSMB2Dialect(state.Dialect);
byte[] signingKey = SMB2Cryptography.GenerateSigningKey(sessionKey, smb2Dialect, null);
state.CreateSession(request.Header.SessionID, userName, machineName, sessionKey, accessToken, signingRequired, signingKey);
} }
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, false); state.CreateSession(request.Header.SessionID, "Guest", machineName, sessionKey, accessToken, false, null);
response.SessionFlags = SessionFlags.IsGuest; response.SessionFlags = SessionFlags.IsGuest;
} }
} }

View file

@ -228,7 +228,7 @@ namespace SMBLibrary.Server
private static void EnqueueResponseChain(ConnectionState state, List<SMB2Command> responseChain) private static void EnqueueResponseChain(ConnectionState state, List<SMB2Command> responseChain)
{ {
byte[] sessionKey = null; byte[] signingKey = null;
if (state is SMB2ConnectionState) if (state is SMB2ConnectionState)
{ {
// Note: multiple sessions MAY be multiplexed on the same connection, so theoretically // Note: multiple sessions MAY be multiplexed on the same connection, so theoretically
@ -240,19 +240,19 @@ namespace SMBLibrary.Server
SMB2Session session = ((SMB2ConnectionState)state).GetSession(sessionID); SMB2Session session = ((SMB2ConnectionState)state).GetSession(sessionID);
if (session != null) if (session != null)
{ {
sessionKey = session.SessionKey; signingKey = session.SigningKey;
} }
} }
} }
SessionMessagePacket packet = new SessionMessagePacket(); SessionMessagePacket packet = new SessionMessagePacket();
SMB2Dialect smb2Dialect = (sessionKey != null) ? ToSMB2Dialect(state.Dialect) : SMB2Dialect.SMB2xx; SMB2Dialect smb2Dialect = (signingKey != null) ? ToSMB2Dialect(state.Dialect) : SMB2Dialect.SMB2xx;
packet.Trailer = SMB2Command.GetCommandChainBytes(responseChain, sessionKey, smb2Dialect); packet.Trailer = SMB2Command.GetCommandChainBytes(responseChain, signingKey, smb2Dialect);
state.SendQueue.Enqueue(packet); state.SendQueue.Enqueue(packet);
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 SMB2Dialect ToSMB2Dialect(SMBDialect smbDialect) internal static SMB2Dialect ToSMB2Dialect(SMBDialect smbDialect)
{ {
switch (smbDialect) switch (smbDialect)
{ {