Skip to content

Commit

Permalink
Use ASP.NET
Browse files Browse the repository at this point in the history
  • Loading branch information
riskydissonance committed Mar 4, 2022
1 parent 4c4282a commit ca675b8
Show file tree
Hide file tree
Showing 12 changed files with 118 additions and 140 deletions.
2 changes: 1 addition & 1 deletion SharpSocksImplant/Comms/WebClientEx.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using System;
using System.Net;

namespace SharpSocksImplant.Utils
namespace SharpSocksImplant.Comms
{
public class WebClientEx : WebClient
{
Expand Down
24 changes: 24 additions & 0 deletions SharpSocksServer/HttpServer/HttpRequestHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using SharpSocksServer.Logging;

namespace SharpSocksServer.HttpServer
{
public class HttpRequestHandler
{
private readonly ILogOutput _logOutput;
private readonly IProcessRequest _processRequest;

public HttpRequestHandler(IProcessRequest processRequest, ILogOutput logOutput)
{
_processRequest = processRequest;
_logOutput = logOutput;
}

public Task HandleRequest(HttpContext context)
{
_logOutput.LogMessage($"Handling request from {context.Request.Host}");
return Task.Run(() => _processRequest.ProcessRequest(context));
}
}
}
26 changes: 12 additions & 14 deletions SharpSocksServer/HttpServer/HttpServerController.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
using System.Collections.Generic;
using System.Security.Cryptography.X509Certificates;
using Microsoft.AspNetCore.Builder;
using SharpSocksServer.Config;
using SharpSocksServer.ImplantComms;
using SharpSocksServer.Logging;

namespace SharpSocksServer.HttpServer
{
public class HttpServerController
{
public HttpServerController(ILogOutput logger, EncryptedC2RequestProcessor requestProcessor, SharpSocksConfig config)
private readonly HttpRequestHandler _requestHandler;

public HttpServerController(ILogOutput logger, SharpSocksConfig config, HttpRequestHandler requestHandler)
{
_requestHandler = requestHandler;
Logger = logger;
RequestProcessor = requestProcessor;
Config = config;
}

private ILogOutput Logger { get; }
private EncryptedC2RequestProcessor RequestProcessor { get; }
private SharpSocksConfig Config { get; }

public void StartHttp()
{
var httpAsyncListener = new HttpAsyncListener(RequestProcessor, Logger);
httpAsyncListener.CreateListener(new Dictionary<string, X509Certificate2>
{
{
Config.HttpServerURI,
null
}
});
var builder = WebApplication.CreateBuilder();
var app = builder.Build();

app.MapGet("{uri:regex(/*)}", _requestHandler.HandleRequest);
app.MapPost("{uri:regex(/*)}", _requestHandler.HandleRequest);

app.Run(Config.HttpServerURI);
Logger.LogMessage($"C2 HTTP processor listening on {Config.HttpServerURI}");
}
}
Expand Down
9 changes: 9 additions & 0 deletions SharpSocksServer/HttpServer/IProcessRequest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using Microsoft.AspNetCore.Http;

namespace SharpSocksServer.HttpServer
{
public interface IProcessRequest
{
void ProcessRequest(HttpContext httpContext);
}
}
53 changes: 0 additions & 53 deletions SharpSocksServer/ImplantComms/HTTPAsyncListener.cs

This file was deleted.

9 changes: 0 additions & 9 deletions SharpSocksServer/ImplantComms/IProcessRequest.cs

This file was deleted.

55 changes: 28 additions & 27 deletions SharpSocksServer/ImplantComms/ProcessEncryptedC2Request.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Xml.Linq;
using System.Xml.XPath;
using Microsoft.AspNetCore.Http;
using SharpSocksCommon;
using SharpSocksCommon.Encryption;
using SharpSocksServer.Config;
using SharpSocksServer.HttpServer;
using SharpSocksServer.Logging;
using SharpSocksServer.SocksServer;

Expand Down Expand Up @@ -50,7 +51,7 @@ public EncryptedC2RequestProcessor(ILogOutput logger, IEncryptionHelper encrypti

private IEncryptionHelper Encryption { get; }

public ManualResetEvent CmdChannelRunningEvent { get; }
private ManualResetEvent CmdChannelRunningEvent { get; }

private string PayloadCookieName { get; }

Expand All @@ -67,16 +68,15 @@ private bool IsCommandChannelConnected
}
}

public void ProcessRequest(HttpListenerContext httpListenerContext)
public void ProcessRequest(HttpContext httpContext)
{
Cookie sessionIdCookie;
string sessionIdCookie;
try
{
sessionIdCookie = httpListenerContext.Request.Cookies[_sessionIdName];
if (string.IsNullOrEmpty(sessionIdCookie?.Value))
sessionIdCookie = httpContext.Request.Cookies[_sessionIdName];
if (string.IsNullOrEmpty(sessionIdCookie))
{
httpListenerContext.Response.StatusCode = 401;
httpListenerContext.Response.Close();
httpContext.Response.StatusCode = 401;
return;
}
}
Expand All @@ -91,7 +91,7 @@ public void ProcessRequest(HttpListenerContext httpListenerContext)
try
{
var decryptedSessionCookie = Encoding.UTF8
.GetString((Encryption.Decrypt(sessionIdCookie.Value) ?? throw new Exception($"Can't decrypt session cookie{sessionIdCookie.Value}")).ToArray())
.GetString((Encryption.Decrypt(sessionIdCookie) ?? throw new Exception($"Can't decrypt session cookie{sessionIdCookie}")).ToArray())
.Split(':');
targetId = decryptedSessionCookie[0];
if (!Enum.TryParse(decryptedSessionCookie[1], out statusFromCookie))
Expand All @@ -105,8 +105,7 @@ public void ProcessRequest(HttpListenerContext httpListenerContext)
catch (Exception e)
{
Logger.LogError($"Error occured communicating with implant: {e}");
httpListenerContext.Response.StatusCode = 500;
httpListenerContext.Response.Close();
httpContext.Response.StatusCode = 500;
return;
}

Expand All @@ -116,16 +115,16 @@ public void ProcessRequest(HttpListenerContext httpListenerContext)
string requestData = null;
try
{
switch (httpListenerContext.Request.HttpMethod)
switch (httpContext.Request.Method)
{
case "POST":
requestData = new StreamReader(httpListenerContext.Request.InputStream).ReadToEnd();
requestData = new StreamReader(httpContext.Request.Body).ReadToEndAsync().Result;
break;
case "GET":
{
var commandChannelCookie = httpListenerContext.Request.Cookies[PayloadCookieName];
if (!string.IsNullOrWhiteSpace(commandChannelCookie?.Value))
requestData = commandChannelCookie.Value;
var commandChannelCookie = httpContext.Request.Cookies[PayloadCookieName];
if (!string.IsNullOrWhiteSpace(commandChannelCookie))
requestData = commandChannelCookie;
break;
}
}
Expand All @@ -145,7 +144,7 @@ public void ProcessRequest(HttpListenerContext httpListenerContext)
}
else
{
responseBytes = HandleNetworkChannelRequest(httpListenerContext, statusFromCookie, targetId, decryptedData);
responseBytes = HandleNetworkChannelRequest(httpContext, statusFromCookie, targetId, decryptedData);
if (responseBytes == null)
{
CloseTargetConnection(targetId);
Expand All @@ -155,11 +154,11 @@ public void ProcessRequest(HttpListenerContext httpListenerContext)

try
{
httpListenerContext.Response.StatusCode = 200;
httpContext.Response.StatusCode = 200;
var source = EncryptPayload(responseBytes);
if (source is { Count: > 0 })
httpListenerContext.Response.OutputStream.Write(source.ToArray(), 0, source.Count);
httpListenerContext.Response.OutputStream.Close();
httpContext.Response.Body.WriteAsync(source.ToArray(), 0, source.Count);
httpContext.Response.Body.Close();
}
catch (Exception e)
{
Expand Down Expand Up @@ -200,7 +199,12 @@ public void SendDataToTarget(string listenerGuid, List<byte> payload)
dataTask.Wait.Set();
}

private List<byte> HandleNetworkChannelRequest(HttpListenerContext httpListenerContext, CommandChannelStatus statusFromCookie, string targetId, List<byte> requestData)
public ManualResetEvent GetCommandChannelRunningEvent()
{
return CmdChannelRunningEvent;
}

private List<byte> HandleNetworkChannelRequest(HttpContext httpContext, CommandChannelStatus statusFromCookie, string targetId, List<byte> requestData)
{
var responseBytes = new List<byte>();
try
Expand All @@ -217,8 +221,7 @@ private List<byte> HandleNetworkChannelRequest(HttpListenerContext httpListenerC

_listeners.Remove(targetId);
SocksProxy.CloseConnection(targetId);
httpListenerContext.Response.StatusCode = 200;
httpListenerContext.Response.OutputStream.Close();
httpContext.Response.StatusCode = 200;
return null;
}

Expand All @@ -240,8 +243,7 @@ private List<byte> HandleNetworkChannelRequest(HttpListenerContext httpListenerC
var dataTask = _dataTasks[targetId];
if (!SocksProxy.IsValidSession(targetId))
{
httpListenerContext.Response.StatusCode = 200;
httpListenerContext.Response.OutputStream.Close();
httpContext.Response.StatusCode = 200;
return null;
}

Expand All @@ -260,8 +262,7 @@ private List<byte> HandleNetworkChannelRequest(HttpListenerContext httpListenerC
Logger.LogMessage($"[{targetId}][Implant -> SOCKS Server] Session ID {targetId} is not valid");
try
{
httpListenerContext.Response.StatusCode = 404;
httpListenerContext.Response.OutputStream.Close();
httpContext.Response.StatusCode = 404;
return null;
}
catch (Exception e)
Expand Down
40 changes: 21 additions & 19 deletions SharpSocksServer/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,17 @@ private static void Main(string[] args)
try
{
Console.WriteLine("[*] Initialising...");
var config = ParseArgs(args);

var services = new ServiceCollection()
.AddSingleton(config)
.AddSingleton<IEncryptionHelper>(new RijndaelCBCCryptor(config.EncryptionKey))
.AddSingleton(ParseArgs(args))
.AddSingleton<IEncryptionHelper>(x =>
new RijndaelCBCCryptor(x.GetRequiredService<SharpSocksConfig>().EncryptionKey))
.AddSingleton<EncryptedC2RequestProcessor>()
.AddSingleton<IProcessRequest>(x => x.GetRequiredService<EncryptedC2RequestProcessor>())
.AddSingleton<ISocksImplantComms>(x => x.GetRequiredService<EncryptedC2RequestProcessor>())
.AddSingleton<HttpServerController>()
.AddSingleton<ServerController>()
.AddSingleton<SocksServerController>()
.AddSingleton<HttpRequestHandler>()
.AddSingleton<ILogOutput, ConsoleOutput>();

var serviceProvider = services.BuildServiceProvider();
Expand All @@ -34,11 +37,10 @@ private static void Main(string[] args)
SocksProxy.Logger = logger;

var httpServerController = serviceProvider.GetRequiredService<HttpServerController>();
var serverController = serviceProvider.GetRequiredService<ServerController>();
var serverController = serviceProvider.GetRequiredService<SocksServerController>();
Console.WriteLine("[*] Initialised");

httpServerController.StartHttp();
serverController.StartSocks();
httpServerController.StartHttp();

logger.LogImportantMessage("Press x to quit");

Expand All @@ -54,24 +56,24 @@ private static void Main(string[] args)

private static SharpSocksConfig ParseArgs(string[] args)
{
var _app = new CommandLineApplication();
_app.HelpOption();
var optSocksServerUri = _app.Option("-s|--socksserveruri", "IP:Port for SOCKS to listen on, default is *:43334", CommandOptionType.SingleValue);
var optCmdChannelId = _app.Option("-c|--cmdid", "Command Channel Identifier, needs to be shared with the server", CommandOptionType.SingleValue);
var optHttpServer = _app.Option("-l|--httpserveruri", "Uri to listen on, default is http://127.0.0.1:8081", CommandOptionType.SingleValue);
var optEncKey = _app.Option("-k|--encryptionkey", "The encryption key used to secure comms", CommandOptionType.SingleValue);
var optSessionCookie = _app.Option("-sc|--sessioncookie", "The name of the cookie to pass the session identifier", CommandOptionType.SingleValue);
var optPayloadCookie = _app.Option("-pc|--payloadcookie", "The name of the cookie to pass smaller requests through", CommandOptionType.SingleValue);
var optSocketTimeout = _app.Option("-st|--socketTimeout", "How long should SOCKS sockets be held open for, default is 30s", CommandOptionType.SingleValue);
var optVerbose = _app.Option("-v|--verbose", "Verbose error logging", CommandOptionType.NoValue);
var app = new CommandLineApplication();
app.HelpOption();
var optSocksServerUri = app.Option("-s|--socksserveruri", "IP:Port for SOCKS to listen on, default is *:43334", CommandOptionType.SingleValue);
var optCmdChannelId = app.Option("-c|--cmdid", "Command Channel Identifier, needs to be shared with the server", CommandOptionType.SingleValue);
var optHttpServer = app.Option("-l|--httpserveruri", "Uri to listen on, default is http://127.0.0.1:8081", CommandOptionType.SingleValue);
var optEncKey = app.Option("-k|--encryptionkey", "The encryption key used to secure comms", CommandOptionType.SingleValue);
var optSessionCookie = app.Option("-sc|--sessioncookie", "The name of the cookie to pass the session identifier", CommandOptionType.SingleValue);
var optPayloadCookie = app.Option("-pc|--payloadcookie", "The name of the cookie to pass smaller requests through", CommandOptionType.SingleValue);
var optSocketTimeout = app.Option("-st|--socketTimeout", "How long should SOCKS sockets be held open for, default is 30s", CommandOptionType.SingleValue);
var optVerbose = app.Option("-v|--verbose", "Verbose error logging", CommandOptionType.NoValue);

SharpSocksConfig config = null;
_app.OnExecute(() =>
app.OnExecute(() =>
{
config = SharpSocksConfig.LoadConfig(optSocksServerUri, optSocketTimeout, optCmdChannelId, optEncKey, optSessionCookie, optPayloadCookie,
optVerbose, optHttpServer);
});
_app.Execute(args);
app.Execute(args);
return config;
}
}
Expand Down
Loading

0 comments on commit ca675b8

Please sign in to comment.