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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -43,9 +43,9 @@ namespace SMBLibrary.Server
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)
{
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
* the GNU Lesser Public License as published by the Free Software Foundation,
@ -20,6 +20,7 @@ namespace SMBLibrary.Server
private SecurityContext m_securityContext;
private DateTime m_creationDT;
private bool m_signingRequired;
private byte[] m_signingKey;
// Key is TreeID
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
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_sessionID = sessionID;
@ -40,6 +41,7 @@ namespace SMBLibrary.Server
m_securityContext = new SecurityContext(userName, machineName, connection.ClientEndPoint, connection.AuthenticationContext, accessToken);
m_creationDT = DateTime.UtcNow;
m_signingRequired = signingRequired;
m_signingKey = signingKey;
}
private uint? AllocateTreeID()
@ -256,5 +258,13 @@ namespace SMBLibrary.Server
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
* 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);
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
{
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;
}
}

View file

@ -228,7 +228,7 @@ namespace SMBLibrary.Server
private static void EnqueueResponseChain(ConnectionState state, List<SMB2Command> responseChain)
{
byte[] sessionKey = null;
byte[] signingKey = null;
if (state is SMB2ConnectionState)
{
// 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);
if (session != null)
{
sessionKey = session.SessionKey;
signingKey = session.SigningKey;
}
}
}
SessionMessagePacket packet = new SessionMessagePacket();
SMB2Dialect smb2Dialect = (sessionKey != null) ? ToSMB2Dialect(state.Dialect) : SMB2Dialect.SMB2xx;
packet.Trailer = SMB2Command.GetCommandChainBytes(responseChain, sessionKey, smb2Dialect);
SMB2Dialect smb2Dialect = (signingKey != null) ? ToSMB2Dialect(state.Dialect) : SMB2Dialect.SMB2xx;
packet.Trailer = SMB2Command.GetCommandChainBytes(responseChain, signingKey, smb2Dialect);
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);
}
private static SMB2Dialect ToSMB2Dialect(SMBDialect smbDialect)
internal static SMB2Dialect ToSMB2Dialect(SMBDialect smbDialect)
{
switch (smbDialect)
{