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() { }