public static ConsoleMessage ProcessShowMessage(ConsoleMessage consoleMessage)
        {
            ConsoleMessage consoleResponse = new ConsoleMessage();

            consoleResponse.AgentId  = consoleMessage.AgentId;
            consoleResponse.UserId   = 1;
            consoleResponse.Type     = "ShowMessage";
            consoleResponse.Received = DateTime.UtcNow;

            List <string> availableShowCommands = new List <string>();

            availableShowCommands.Add("MODULES");
            availableShowCommands.Add("COMMANDS");

            string showCommand = "";

            string[] commandParts = consoleMessage.Content.Split(' ');
            if (commandParts.Length > 1)
            {
                if (availableShowCommands.Contains(commandParts[1].ToUpper()))
                {
                    showCommand = commandParts[1].ToUpper();
                }
                else
                {
                    consoleResponse.Display = $"Unknown SHOW option {commandParts[1]}. Valid options are: {availableShowCommands.ToString()}";
                }
            }
            else
            {
                consoleResponse.Display = $"Available SHOW commands are:";
                foreach (string availableShowCommand in availableShowCommands)
                {
                    consoleResponse.Display += $"\n * show {availableShowCommand.ToLower()}";
                }
            }

            if (String.IsNullOrEmpty(showCommand))
            {
                return(consoleResponse);
            }

            if (showCommand == "MODULES")
            {
                List <ShowModule> showModules = new List <ShowModule>();
                foreach (Module module in AgentDetails.AvailableModules)
                {
                    showModules.Add(new ShowModule(module, AgentDetails.IsModuleLoaded(module)));
                }
                consoleResponse.Display = JsonConvert.SerializeObject(showModules);
            }
            else if (showCommand == "COMMANDS")
            {
                List <ShowCommand> showCommands      = new List <ShowCommand>();
                List <Command>     agentTypeCommands = _taskRepository.GetAgentTypeCommands(AgentDetails.AgentType.Id);
                foreach (Command command in agentTypeCommands)
                {
                    showCommands.Add(new ShowCommand(command, AgentDetails.IsCommandAvailable(command)));
                }
                foreach (Module module in AgentDetails.AvailableModules)
                {
                    List <Command> commands = _taskRepository.GetCommands(module.Id);
                    foreach (Command command in commands)
                    {
                        showCommands.Add(new ShowCommand(command, AgentDetails.IsCommandAvailable(command)));
                    }
                }
                consoleResponse.Display = JsonConvert.SerializeObject(showCommands);
            }
            return(consoleResponse);
        }
        public async Task Handle(NewConsoleMessage newConsoleMessage, string replyTo, string correlationId)
        {
            // Reset Error stuff
            error        = false;
            errorMessage = "";

            // figure out what agent we're dealing with
            Agent agent = _taskRepository.GetAgent(newConsoleMessage.AgentId);

            agent.AgentType = _taskRepository.GetAgentType(agent.AgentTypeId);

            // flesh out and save the ConsoleMessage object
            ConsoleMessage consoleMessage = new ConsoleMessage();

            consoleMessage.AgentId  = newConsoleMessage.AgentId;
            consoleMessage.UserId   = newConsoleMessage.UserId;
            consoleMessage.Agent    = agent;
            consoleMessage.User     = _taskRepository.GetUser(consoleMessage.UserId.Value);
            consoleMessage.Content  = newConsoleMessage.Content;
            consoleMessage.Display  = newConsoleMessage.Display;
            consoleMessage.Received = DateTime.UtcNow;
            consoleMessage.Type     = "AgentTask";
            _taskRepository.Add(consoleMessage);

            // Announce our new message to Rabbit
            ConsoleMessageAnnouncement messageAnnouncement = new ConsoleMessageAnnouncement();

            messageAnnouncement.Success        = true;
            messageAnnouncement.Username       = consoleMessage.User.Username;
            messageAnnouncement.ConsoleMessage = consoleMessage;
            _eventBus.Publish(messageAnnouncement);

            // These are the commands we allow. If one of these isn't the first part of a command
            List <string> allowedActions = new List <string>();

            allowedActions.Add("HELP");
            allowedActions.Add("SHOW");
            allowedActions.Add("LOAD");
            allowedActions.Add("SET");
            allowedActions.Add("USE");
            allowedActions.Add("RUN");
            allowedActions.Add("EXIT");

            // we assume that the command is a RUN command
            string action = "RUN";

            string[] consoleMessageComponents = consoleMessage.Content.Split(' ');
            if (consoleMessageComponents.Length > 0)
            {
                if (allowedActions.Contains(consoleMessageComponents[0].ToUpper()))
                {
                    action = consoleMessageComponents[0].ToUpper();
                }
            }

            // if this is a SHOW or HELP commmand, we won't be sending anything to the agent
            // so lets take care of that here:
            AgentDetails.Language         = _taskRepository.GetLanguage(consoleMessage.Agent.AgentType.LanguageId);
            AgentDetails.AvailableModules = _taskRepository.GetModules(AgentDetails.Language.Id);
            AgentDetails.LoadedModules    = _taskRepository.GetAgentModules(consoleMessage.AgentId);
            AgentDetails.AgentType        = consoleMessage.Agent.AgentType;

            if (action == "HELP")
            {
                ConsoleMessage message = ProcessHelpMessage(consoleMessage);
                _taskRepository.Add(message);

                ConsoleMessageAnnouncement response = new ConsoleMessageAnnouncement();
                response.Success        = true;
                response.Username       = "******";
                response.ConsoleMessage = message;
                _eventBus.Publish(response);
            }

            else if (action == "SHOW")
            {
                ConsoleMessage message = ProcessShowMessage(consoleMessage);
                _taskRepository.Add(message);

                ConsoleMessageAnnouncement response = new ConsoleMessageAnnouncement();
                response.Success        = true;
                response.Username       = "******";
                response.ConsoleMessage = message;
                _eventBus.Publish(response);
            }

            else
            {
                // We'll be tasking the agent to do something so lets create an agentTask
                AgentTask agentTask = new AgentTask();
                agentTask.Action           = action;
                agentTask.AgentId          = consoleMessage.AgentId;
                agentTask.ConsoleMessageId = consoleMessage.Id;
                agentTask.ConsoleMessage   = consoleMessage;
                agentTask.Agent            = consoleMessage.Agent;

                // Package the AgentTask into a envelope for seralization & encryption.
                // Then process the ACTION and populate CONTENTS appropriately
                Dictionary <String, String> outboundMessage = new Dictionary <String, String>();
                outboundMessage.Add("AgentName", agentTask.Agent.Name);
                outboundMessage.Add("Name", agentTask.Name);
                outboundMessage.Add("Action", agentTask.Action);

                // Message formats
                // * load stdlib
                // * load dotnet/stdlib
                // * load transport/dns
                if (agentTask.Action == "LOAD")
                {
                    LoadModule msg = new LoadModule();
                    if (consoleMessageComponents[1].Contains("/"))
                    {
                        msg.Language = consoleMessageComponents[1].Split("/")[0];
                        msg.Name     = consoleMessageComponents[1].Split("/")[0];
                    }
                    else
                    {
                        msg.Language = (_taskRepository.GetLanguage(consoleMessage.Agent.AgentType.LanguageId)).Name;
                        msg.Name     = consoleMessageComponents[1];
                    }

                    bool LoadSuccess = false;
                    foreach (Module module in AgentDetails.AvailableModules)
                    {
                        if (String.Equals(module.Name, msg.Name, StringComparison.CurrentCultureIgnoreCase))
                        {
                            _eventBus.Publish(msg, null, null, true);
                            string         message        = _eventBus.ResponseQueue.Take();
                            ModuleResponse moduleResponse = JsonConvert.DeserializeObject <ModuleResponse>(message);
                            outboundMessage.Add("Command", moduleResponse.Contents);
                            LoadSuccess = true;

                            AgentUpdated agentUpdated = new AgentUpdated {
                                Success = true, Agent = agentTask.Agent
                            };
                            _eventBus.Publish(agentUpdated);

                            break;
                        }
                    }

                    if (!LoadSuccess)
                    {
                        error        = true;
                        errorMessage = $"Module {msg.Name} is not a valid module. Use the 'show modules' command to view available modules";
                    }
                }

                // Message formats
                // * set beacon:5
                else if (agentTask.Action == "SET")
                {
                    outboundMessage.Add("Command", consoleMessageComponents[1]);
                }

                else if (agentTask.Action == "EXIT")
                {
                    outboundMessage.Add("Command", "exit");
                }
                // Example commands:
                // * ls
                // * ls "C:\Program Files"
                // * ls /path:"C:\Program Files"
                if (agentTask.Action == "RUN")
                {
                    string   submittedCommand = consoleMessage.Content;
                    string[] processedArgs    = null;

                    // check to see if we have parameters (for example: ls /path:foo)
                    int index = submittedCommand.IndexOf(' ');
                    if (index > 0)
                    {
                        // change submittedCommand to just the first part of the command (ex: ls)
                        submittedCommand = submittedCommand.Substring(0, index);
                        string submittedArgs = consoleMessage.Content.Substring(index + 1);
                        if (submittedArgs.Length > 0)
                        {
                            processedArgs = SplitArguments(submittedArgs);
                        }
                    }

                    // Check if command is available
                    try
                    {
                        Command commandObject = _taskRepository.GetCommand(submittedCommand);
                        if (!AgentDetails.IsModuleLoaded(commandObject.Module))
                        {
                            error        = true;
                            errorMessage = $"The module for this command isn't loaded. You can load it by running: 'load {commandObject.Module.Name}'";
                        }
                    }
                    catch
                    {
                        error        = true;
                        errorMessage = $"{submittedCommand} is not a valid command for this agent. To view available commands, run: 'show commands'";
                    }

                    if (!error)
                    {
                        FactionCommand factionCommand = ProcessCommand(submittedCommand, processedArgs);
                        string         command        = factionCommand.Command;
                        if (factionCommand.Arguments.Count > 0)
                        {
                            command = $"{factionCommand.Command} {JsonConvert.SerializeObject(factionCommand.Arguments)}";
                        }
                        outboundMessage.Add("Command", command);
                    }
                }

                // If there's an error, send it back
                if (error)
                {
                    ConsoleMessage message = new ConsoleMessage();
                    message.AgentId     = consoleMessage.AgentId;
                    message.AgentTaskId = agentTask.Id;
                    message.UserId      = 1;
                    message.Type        = "AgentTaskError";
                    message.Display     = errorMessage;
                    _taskRepository.Add(message);

                    ConsoleMessageAnnouncement response = new ConsoleMessageAnnouncement();
                    response.Success        = true;
                    response.Username       = "******";
                    response.ConsoleMessage = message;
                    _eventBus.Publish(response);
                }
                // Else, create a new task for the agent
                else
                {
                    // update agentTask with final command format and save it
                    agentTask.Command = outboundMessage["Command"];
                    _taskRepository.Add(agentTask);

                    // update the incoming consoleMessage with this task Id
                    consoleMessage.AgentTaskId = agentTask.Id;
                    _taskRepository.Update(consoleMessage.Id, consoleMessage);

                    string jsonOutboundMessage             = JsonConvert.SerializeObject(outboundMessage);
                    Dictionary <string, string> encCommand = Crypto.Encrypt(jsonOutboundMessage, agentTask.Id, agentTask.Agent.AesPassword);

                    // Create a AgentTaskMessage object with the seralized/encrypted message contents
                    AgentTaskMessage agentTaskMessage = new AgentTaskMessage();
                    agentTaskMessage.Agent       = agentTask.Agent;
                    agentTaskMessage.Message     = encCommand["encryptedMsg"];
                    agentTaskMessage.AgentId     = consoleMessage.Agent.Id;
                    agentTaskMessage.AgentTaskId = agentTask.Id;
                    agentTaskMessage.AgentTask   = agentTask;
                    agentTaskMessage.Hmac        = encCommand["hmac"];
                    agentTaskMessage.Iv          = encCommand["iv"];
                    agentTaskMessage.Sent        = false;
                    _taskRepository.Add(agentTaskMessage);
                }
            }
        }
        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);
        }