public async Task Handle(NewAgentCheckin agentCheckinMsg, string replyTo, string correlationId) { Console.WriteLine($"[i] Got AgentCheckin Message."); Transport transport = _taskRepository.GetTransport(agentCheckinMsg.TransportId); // Check in agent Agent agent = _taskRepository.GetAgent(agentCheckinMsg.AgentName); agent.TransportId = agentCheckinMsg.TransportId; agent.ExternalIp = agentCheckinMsg.SourceIp; agent.LastCheckin = DateTime.UtcNow; if (!agent.Visible) { agent.Visible = true; AgentUpdated update = new AgentUpdated(); update.Success = true; update.Agent = agent; _eventBus.Publish(update); } _taskRepository.Update(agent.Id, agent); AgentCheckinAnnouncement agentCheckinAnnouncement = new AgentCheckinAnnouncement(); agentCheckinAnnouncement.Id = agent.Id; agentCheckinAnnouncement.SourceIp = agentCheckinMsg.SourceIp; agentCheckinAnnouncement.TransportId = agentCheckinMsg.TransportId; agentCheckinAnnouncement.TransportName = transport.Name; agentCheckinAnnouncement.Received = agent.LastCheckin.Value; _eventBus.Publish(agentCheckinAnnouncement); // Decode and Decrypt AgentTaskResponse if (!String.IsNullOrEmpty(agentCheckinMsg.Message)) { AgentCheckin agentCheckin = new AgentCheckin(); agentCheckin.SourceIp = agentCheckinMsg.SourceIp; agentCheckin.TransportId = agentCheckinMsg.TransportId; agentCheckin.HMAC = agentCheckinMsg.HMAC; agentCheckin.IV = agentCheckinMsg.IV; agentCheckin.Message = agentCheckinMsg.Message; agentCheckin.AgentId = agent.Id; agentCheckin.Agent = agent; _taskRepository.Add(agentCheckin); // Decrypt Message from Agent string decryptedMessage = Crypto.Decrypt(agentCheckin); Console.WriteLine($"Got response {decryptedMessage}"); if (!agent.Visible) { agent.Visible = true; _taskRepository.Update(agent.Id, agent); } // Process taskResults // TODO: Probably a better way to check if the message is blank. if ((decryptedMessage != "[]") || (!String.IsNullOrEmpty(decryptedMessage))) { List <AgentTaskUpdate> taskUpdates = JsonConvert.DeserializeObject <List <AgentTaskUpdate> >(decryptedMessage); foreach (AgentTaskUpdate taskUpdate in taskUpdates) { taskUpdate.AgentTask = _taskRepository.GetAgentTask(taskUpdate.TaskName); taskUpdate.AgentId = taskUpdate.AgentTask.AgentId; taskUpdate.Received = DateTime.UtcNow; foreach (IOC ioc in taskUpdate.IOCs) { ioc.UserId = taskUpdate.AgentTask.ConsoleMessage.UserId.Value; ioc.AgentTaskUpdateId = taskUpdate.Id; } _taskRepository.Add(taskUpdate); if (taskUpdate.AgentTask.Action == "LOAD" && taskUpdate.Success.Value) { AgentsModulesXref xref = new AgentsModulesXref(); xref.AgentId = taskUpdate.AgentId; string languageName = taskUpdate.Agent.AgentType.Language.Name; string moduleName = taskUpdate.AgentTask.Command.Split(" ")[1]; if (moduleName.Contains("/")) { languageName = moduleName.Split("/")[0]; moduleName = moduleName.Split("/")[1]; } Module loadedModule = _taskRepository.GetModule(moduleName, languageName); xref.ModuleId = loadedModule.Id; _taskRepository.Add(xref); List <Command> loadedCommands = _taskRepository.GetCommands(loadedModule.Id); foreach (Command loadedCommand in loadedCommands) { loadedCommand.Parameters = _taskRepository.GetCommandParameters(loadedCommand.Id); } AgentCommandsUpdated agentCommandsUpdated = new AgentCommandsUpdated(); agentCommandsUpdated.Success = true; agentCommandsUpdated.AgentId = xref.AgentId; agentCommandsUpdated.Commands = loadedCommands; _eventBus.Publish(agentCommandsUpdated); } if (taskUpdate.Type == "File" && !String.IsNullOrEmpty(taskUpdate.Content)) { WebClient wc = new WebClient(); FactionSettings factionSettings = Utility.GetConfiguration(); wc.Headers[HttpRequestHeader.ContentType] = "application/json"; string rsp = wc.UploadString($"{apiUrl}/login/", $"{{\"Username\":\"{factionSettings.SYSTEM_USERNAME}\", \"Password\":\"{factionSettings.SYSTEM_PASSWORD}\"}}"); Dictionary <string, string> responseDict = JsonConvert.DeserializeObject <Dictionary <string, string> >(rsp); wc.Dispose(); string apiKeyName = responseDict["AccessKeyId"]; string apiSecret = responseDict["AccessSecret"]; string uploadUrl = $"{apiUrl}/file/?token={apiKeyName}:{apiSecret}"; Dictionary <string, string> upload = new Dictionary <string, string>(); upload.Add("AgentName", taskUpdate.Agent.Name); upload.Add("FileName", taskUpdate.ContentId); upload.Add("FileContent", taskUpdate.Content); WebClient uploadClient = new WebClient(); uploadClient.Headers[HttpRequestHeader.ContentType] = "application/json"; string content = JsonConvert.SerializeObject(upload); Console.WriteLine(content); string uploadResponse = uploadClient.UploadString(uploadUrl, content); } ConsoleMessage consoleMessage = new ConsoleMessage(); consoleMessage.Agent = taskUpdate.Agent; consoleMessage.Type = "AgentTaskResult"; consoleMessage.AgentTask = taskUpdate.AgentTask; consoleMessage.AgentTaskId = taskUpdate.AgentTask.Id; consoleMessage.Display = taskUpdate.Message; _taskRepository.Add(consoleMessage); ConsoleMessageAnnouncement response = new ConsoleMessageAnnouncement(); response.Success = true; response.Username = consoleMessage.Agent.Name; response.ConsoleMessage = consoleMessage; _eventBus.Publish(response); } } } }
public static ConsoleMessage ProcessHelpMessage(ConsoleMessage consoleMessage) { ConsoleMessage consoleResponse = new ConsoleMessage(); consoleResponse.AgentId = consoleMessage.AgentId; consoleResponse.UserId = 1; consoleResponse.Received = DateTime.UtcNow; consoleResponse.Type = "HelpResponse"; // Remove the leading "HELP ", if we can't do this lets assume its just "help" string recievedCommand = ""; try { recievedCommand = consoleMessage.Content.Remove(0, 5); } catch { consoleResponse.Display = $"Faction Agent Help:\n\n* 'show commands' will return a list of available commands.\n* 'show modules' will show available modules\n* 'help <command>` will give you details about a command\n* 'help <command> /<paramater>' will give you details about a commands paramter"; return(consoleResponse); } FactionCommand factionCommand = ProcessCommand(recievedCommand); if (factionCommand.Arguments.Count > 0) { string ParameterName = factionCommand.Arguments.Keys.Last().ToString(); CommandParameter parameter; try { parameter = _taskRepository.GetCommandParameter(factionCommand.Command, ParameterName); if (String.IsNullOrEmpty(parameter.Help)) { consoleResponse.Display = $"No help available for parameter: {parameter.Name} under command {factionCommand.Command}"; } else { consoleResponse.Display = $"Name: {parameter.Name}\nRequired: {parameter.Required}\nAccepted Values: {parameter.Values}\n\n## Help\n{parameter.Help}"; } } catch { consoleResponse.Display = $"No parameter named {ParameterName} found for command {factionCommand.Command}"; } } else { try { Command command = _taskRepository.GetCommand(factionCommand.Command); if (String.IsNullOrEmpty(command.Help)) { consoleResponse.Display = $"No help available for command {command.Name}"; } else { consoleResponse.Display = $"Name: {command.Name}"; consoleResponse.Display += $"\nDescription: {command.Description}"; consoleResponse.Display += $"\nMitre ATT&CK Reference: {command.MitreReference}"; consoleResponse.Display += $"\nOpsecSafe: {command.OpsecSafe}"; consoleResponse.Display += $"\nLoaded: {AgentDetails.IsCommandAvailable(command)}"; consoleResponse.Display += $"\n\nHelp:\n{command.Help}\n"; List <CommandParameter> parameters = _taskRepository.GetCommandParameters(command.Id); if (parameters.Count() > 0) { string parameterText = "\nParameters:"; foreach (CommandParameter param in parameters) { parameterText += $"\nName: {param.Name}"; parameterText += $"\nRequired: {param.Required.ToString()}"; if (param.Position.HasValue) { parameterText += $"\nPosition: {param.Position.Value.ToString()}"; } else { parameterText += $"\nPosition: N/A"; } parameterText += $"\nHelp: {param.Help}\n"; } consoleResponse.Display += parameterText; } if (!String.IsNullOrEmpty(command.Artifacts)) { consoleResponse.Display += "\n\nArtifacts:"; string[] artifacts = command.Artifacts.Split(","); foreach (string artifact in artifacts) { consoleResponse.Display += $"\n* {artifact}"; } } consoleResponse.Display += "\n"; } } catch { consoleResponse.Display = $"No command found named {recievedCommand}"; } } return(consoleResponse); }