From b3f7812dd222871f9b0027b5b1fd49d9a997ab0d Mon Sep 17 00:00:00 2001 From: Jon Owens <15575425+DragoQCC@users.noreply.github.com> Date: Sat, 8 Apr 2023 21:20:59 -0400 Subject: [PATCH] added firstSeen and Implant_number to engineers to help with tracking, also added ability to show/hide fields in the implants table --- Engineer/Models/HttpCommModule.cs | 2 +- HardHatC2Client/Models/Engineer.cs | 6 +- HardHatC2Client/Pages/Engineers.razor | 201 +++++++++++++++----- TeamServer/Models/Dbstorage/Engineer_DAO.cs | 11 ++ TeamServer/Models/Engineers/Engineer.cs | 9 +- 5 files changed, 176 insertions(+), 53 deletions(-) diff --git a/Engineer/Models/HttpCommModule.cs b/Engineer/Models/HttpCommModule.cs index d072a56f..568e79c7 100644 --- a/Engineer/Models/HttpCommModule.cs +++ b/Engineer/Models/HttpCommModule.cs @@ -64,7 +64,7 @@ public override async Task CheckIn() { //pick one of the strings in the Urls list and use it for the request string url = Urls[new Random().Next(Urls.Count)]; - // Console.WriteLine("Checking in with " + _client.BaseAddress + url); + //Console.WriteLine("Checking in with " + _client.BaseAddress + url); var taskReturned = _client.GetAsync(url, HttpCompletionOption.ResponseContentRead); // gets anything waiting at the maanger for us to read, when this happens it triggers the HandleImplant in our TS if (await Task.WhenAny(taskReturned, Task.Delay(Sleep + 10000)) != taskReturned || taskReturned.Status == TaskStatus.Faulted) diff --git a/HardHatC2Client/Models/Engineer.cs b/HardHatC2Client/Models/Engineer.cs index 0e4bea04..7d5fe868 100644 --- a/HardHatC2Client/Models/Engineer.cs +++ b/HardHatC2Client/Models/Engineer.cs @@ -8,7 +8,9 @@ namespace HardHatC2Client.Models { public class Engineer { - public EngineerMetadata engineerMetadata { get; set;} + public EngineerMetadata engineerMetadata { get; set;} + + public int Number { get; set; } public string Id { get; set; } public string Address { get; set; } public string Hostname { get; set; } @@ -20,6 +22,8 @@ public class Engineer public DateTime LastSeen { get; set; } public string LastSeenTimer { get; set; } + public DateTime FirstSeen { get; set; } + public string ExternalAddress { get; set; } public string ConnectionType { get; set; } public string ManagerName { get; set; } diff --git a/HardHatC2Client/Pages/Engineers.razor b/HardHatC2Client/Pages/Engineers.razor index 8cad7115..4b42e8d9 100644 --- a/HardHatC2Client/Pages/Engineers.razor +++ b/HardHatC2Client/Pages/Engineers.razor @@ -49,6 +49,29 @@ { EngineerDisplayList = EngineerList.ToList(); } + Show/Hide fields + + + + + + + + + + + + + + + + + + + + Close + + Implants @@ -56,38 +79,41 @@ - - - Status - External Address - Manager - Connection Type - Address - hostname - username - process - pid - Integrity - arch - Sleep Time - lastseen - Options + # + + Status + External Address + Manager + Connection Type + Address + hostname + username + process + pid + Integrity + arch + Sleep Time + lastseen + firstseen + Options + @Rowcontext.Number @Rowcontext.Status - @Rowcontext.ExternalAddress - @Rowcontext.ManagerName - @Rowcontext.ConnectionType @FindManager(Rowcontext,Rowcontext.ManagerName) - @Rowcontext.Address - @Rowcontext.Hostname - @Rowcontext.Username - @Rowcontext.ProcessName - @Rowcontext.ProcessId - @Rowcontext.Integrity - @Rowcontext.Arch - @Rowcontext.Sleep sec - @LastSeenTimer(Rowcontext) + @Rowcontext.ExternalAddress + @Rowcontext.ManagerName + @Rowcontext.ConnectionType @FindManager(Rowcontext,Rowcontext.ManagerName) + @Rowcontext.Address + @Rowcontext.Hostname + @Rowcontext.Username + @Rowcontext.ProcessName + @Rowcontext.ProcessId + @Rowcontext.Integrity + @Rowcontext.Arch + @Rowcontext.Sleep sec + @LastSeenTimer(Rowcontext) + @Rowcontext.FirstSeen @@ -190,21 +216,21 @@ - - Status - External Address - Manager - Connection Type - Address - hostname - username - process - pid - Integrity - arch - Sleep Time - lastseen - Options + + Status + External Address + Manager + Connection Type + Address + hostname + username + process + pid + Integrity + arch + Sleep Time + lastseen + Options @@ -266,6 +292,8 @@ public ILocalStorageService localStorage { get; set; } protected internal static ObservableCollection EngineerList = new ObservableCollection(); + private static Dictionary EngineerNumbers = new(); + private static Dictionary EngineerFirstSeenDict = new(); protected internal static List EngineerDisplayList = new List(); private static SpawnEngineerRequest formData = new SpawnEngineerRequest(); private string EngineerTestID { get; set; } @@ -286,13 +314,41 @@ private static DateTime? LastRefresh { get; set; } = null; private string searchString1 = ""; + private bool OpenDialog { get; set; } = false; + private Dictionary ColumnVisibility = new Dictionary +{ + { "Number", true}, + {"ImplantId",true }, + { "Status", true }, + { "ExternalAddress", true }, + { "ManagerName", true }, + { "ConnectionType", true }, + { "Address", true }, + { "Hostname", true }, + { "Username", true }, + { "ProcessName", true }, + { "ProcessId", true }, + { "Integrity", true }, + { "Arch", true }, + { "Sleep", true }, + { "LastSeen", true }, + {"FirstSeen",true }, +}; + public static async Task SetPsCommand(string command) { PsCmd = command; } - private string setStyle(bool IsDark) + private string setStyle(bool IsDark,string fieldName) { + if (!String.IsNullOrEmpty(fieldName)) + { + if (!ColumnVisibility[fieldName]) + { + return "display:none;"; + } + } if(IsDark) { return "background:white; color:black;"; @@ -321,6 +377,26 @@ return Color.Primary; } + private void ToggleColumnVisibility(string columnName) + { + if (ColumnVisibility.ContainsKey(columnName)) + { + ColumnVisibility[columnName] = !ColumnVisibility[columnName]; + } + } + + private string GetCellStyle(string columnName) + { + if (ColumnVisibility.ContainsKey(columnName) && ColumnVisibility[columnName]) + { + return opacitySetting; + } + else + { + return "display:none;"; + } + } + public async Task validSubmit() { if (formData.managerName != null) @@ -362,14 +438,14 @@ return string.Empty; } } - + private bool FilterFunc1(Engineer search) => FilterFunc(search, searchString1); private bool FilterFunc(Engineer search, string searchString) { if (string.IsNullOrWhiteSpace(searchString)) return true; - //for each element in the array if it contains searchString then return true + //for each element in the array if it contains searchString then return true if (search.Id.ToLower().Contains(searchString.ToLower())) { return true; @@ -475,7 +551,7 @@ public static string FindManager(Engineer currenteng,string managerName) { - if(currenteng.ConnectionType.Equals("http",StringComparison.CurrentCultureIgnoreCase)) + if (currenteng.ConnectionType.Equals("http", StringComparison.CurrentCultureIgnoreCase) || currenteng.ConnectionType.Equals("https", StringComparison.CurrentCultureIgnoreCase)) { return ""; } @@ -514,8 +590,8 @@ ShowSuccessToast(requestResponse); } //reset the form data object - // formData = new SpawnEngineerRequest(); - // OnStateChange(); + // formData = new SpawnEngineerRequest(); + // OnStateChange(); } public static async Task GetAllEngineers() @@ -544,6 +620,21 @@ if (!EngineerList.Any(x => x.Id == engineerresponse.Id)) { EngineerList.Add(engineerresponse); + if (!EngineerNumbers.ContainsKey(engineerresponse.Id)) + { + //get the lastest item added to the EngineerNumbers dictionary + KeyValuePair? lastItem = EngineerNumbers.LastOrDefault(); + if (lastItem == null) + { + EngineerNumbers.Add(engineerresponse.Id, 0); + EngineerFirstSeenDict.Add(engineerresponse.Id, DateTime.UtcNow); + } + else + { + EngineerNumbers.Add(engineerresponse.Id, lastItem.Value.Value + 1); + EngineerFirstSeenDict.Add(engineerresponse.Id, DateTime.UtcNow); + } + } } if (EngineerList.Any(x => x.Id == engineerresponse.Id)) { @@ -575,6 +666,18 @@ if (!EngineerList.Any(x => x.Id == engineer.Id)) { EngineerList.Add(engineer); + //get the lastest item added to the EngineerNumbers dictionary + KeyValuePair? lastItem = EngineerNumbers.LastOrDefault(); + if (lastItem == null) + { + EngineerNumbers.Add(engineer.Id, 0); + EngineerFirstSeenDict.Add(engineer.Id, DateTime.UtcNow); + } + else + { + EngineerNumbers.Add(engineer.Id, lastItem.Value.Value + 1); + EngineerFirstSeenDict.Add(engineer.Id, DateTime.UtcNow); + } } if (EngineerList.Any(x => x.Id == engineer.Id)) { diff --git a/TeamServer/Models/Dbstorage/Engineer_DAO.cs b/TeamServer/Models/Dbstorage/Engineer_DAO.cs index ee15598d..f4956fad 100644 --- a/TeamServer/Models/Dbstorage/Engineer_DAO.cs +++ b/TeamServer/Models/Dbstorage/Engineer_DAO.cs @@ -10,6 +10,9 @@ public class Engineer_DAO [PrimaryKey] public string id { get; set; } + [Column("number")] + public int number { get; set; } + [Column("engineerMetadata")] public byte[] engineerMetadata { get; set; } @@ -25,6 +28,9 @@ public class Engineer_DAO [Column("LastSeen")] public DateTime LastSeen { get; set; } + [Column("FirstSeen")] + public DateTime FirstSeen { get; set; } + [Column("Status")] public string Status { get; set; } @@ -33,12 +39,15 @@ public static implicit operator Engineer_DAO(Engineer model) { return new Engineer_DAO { + id = model.engineerMetadata.Id, + number = model.Number, engineerMetadata = model.engineerMetadata.Serialize(), ConnectionType = model.ConnectionType, ManagerName = model.ManagerName, ExternalAddress = model.ExternalAddress, LastSeen = model.LastSeen, + FirstSeen = model.FirstSeen, Status = model.Status }; } @@ -49,10 +58,12 @@ public static implicit operator Engineer(Engineer_DAO dao) return new Engineer { engineerMetadata = dao.engineerMetadata.Deserialize(), + Number = dao.number, ConnectionType = dao.ConnectionType, ManagerName = dao.ManagerName, ExternalAddress = dao.ExternalAddress, LastSeen = dao.LastSeen, + FirstSeen = dao.FirstSeen, Status = dao.Status, }; } diff --git a/TeamServer/Models/Engineers/Engineer.cs b/TeamServer/Models/Engineers/Engineer.cs index 88f7f8bd..84370eed 100644 --- a/TeamServer/Models/Engineers/Engineer.cs +++ b/TeamServer/Models/Engineers/Engineer.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading; +using TeamServer.Services; // Model for Engineer defines class, constructors, and other needed functions namespace TeamServer.Models @@ -11,11 +12,12 @@ public class Engineer { //class memeber properties and varables public EngineerMetadata engineerMetadata { get; set; } //added metadata from class loads all properties from there , having no setter makes this read only so it can only be set in this line nad the constructor and not changed anywhere else. - + public int Number { get; set; } public string ConnectionType { get; set;} public string ManagerName { get; set;} public string ExternalAddress { get; set; } - public DateTime LastSeen { get; set; } //private set because we dont ant any other class to set it + public DateTime LastSeen { get; set; } + public DateTime FirstSeen { get; set; } public string Status { get; set; } public readonly ConcurrentQueue _pendingTasks = new(); @@ -26,6 +28,9 @@ public class Engineer public Engineer(EngineerMetadata metadata) // makes constructor and includes metadata on creation { engineerMetadata = metadata; + //get the last engineer and increment the number by 1 and set the FirstSeen to now in UTC + Number = EngineerService._engineers.Count > 0 ? EngineerService._engineers.Last().Number + 1 : 1; + FirstSeen = DateTime.UtcNow; } public Engineer() { }