From 7438ccdf4f0f0af9d9e25d20f8f178d7f3fa3b8e Mon Sep 17 00:00:00 2001 From: TalAloni Date: Sat, 28 Nov 2020 21:56:48 +0200 Subject: [PATCH] Server: Use SMB2Cryptography.GenerateSigningKey instead of using SessionKey --- .../Server/ConnectionState/SMB2ConnectionState.cs | 6 +++--- SMBLibrary/Server/ConnectionState/SMB2Session.cs | 14 ++++++++++++-- SMBLibrary/Server/SMB2/SessionSetupHelper.cs | 8 +++++--- SMBLibrary/Server/SMBServer.SMB2.cs | 10 +++++----- 4 files changed, 25 insertions(+), 13 deletions(-) diff --git a/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs b/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs index e9495c4..553a9ea 100644 --- a/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs +++ b/SMBLibrary/Server/ConnectionState/SMB2ConnectionState.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2019 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2020 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, @@ -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); diff --git a/SMBLibrary/Server/ConnectionState/SMB2Session.cs b/SMBLibrary/Server/ConnectionState/SMB2Session.cs index 915c28b..7ec740a 100644 --- a/SMBLibrary/Server/ConnectionState/SMB2Session.cs +++ b/SMBLibrary/Server/ConnectionState/SMB2Session.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2014-2017 Tal Aloni . All rights reserved. +/* Copyright (C) 2014-2020 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, @@ -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 m_connectedTrees = new Dictionary(); @@ -32,7 +33,7 @@ namespace SMBLibrary.Server // Key is the volatile portion of the FileID private Dictionary m_openSearches = new Dictionary(); - 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; + } + } } } diff --git a/SMBLibrary/Server/SMB2/SessionSetupHelper.cs b/SMBLibrary/Server/SMB2/SessionSetupHelper.cs index f0d93f2..aa28f67 100644 --- a/SMBLibrary/Server/SMB2/SessionSetupHelper.cs +++ b/SMBLibrary/Server/SMB2/SessionSetupHelper.cs @@ -1,4 +1,4 @@ -/* Copyright (C) 2017-2019 Tal Aloni . All rights reserved. +/* Copyright (C) 2017-2020 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, @@ -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; } } diff --git a/SMBLibrary/Server/SMBServer.SMB2.cs b/SMBLibrary/Server/SMBServer.SMB2.cs index 02e490b..65671ec 100644 --- a/SMBLibrary/Server/SMBServer.SMB2.cs +++ b/SMBLibrary/Server/SMBServer.SMB2.cs @@ -228,7 +228,7 @@ namespace SMBLibrary.Server private static void EnqueueResponseChain(ConnectionState state, List 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) {