public async Task Handle(NewTransport newTransport, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Got Transport Message.");
            Transport transport = new Transport();

            transport.Name     = newTransport.Name;
            transport.ApiKeyId = newTransport.ApiKeyId;
            _taskRepository.Add(transport);
            TransportCreated transportCreated = new TransportCreated();

            transportCreated.Success   = true;
            transportCreated.Transport = transport;
            _eventBus.Publish(transportCreated, replyTo, correlationId);
        }
        public async Task Handle(NewErrorMessage newErrorMessage, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Got ErrorMessage Message.");
            ErrorMessage errorMessage = new ErrorMessage();

            errorMessage.Source  = newErrorMessage.Source;
            errorMessage.Message = newErrorMessage.Message;
            errorMessage.Details = newErrorMessage.Details;
            _taskRepository.Add(errorMessage);

            ErrorMessageAnnouncement errorMessageAnnouncement = new ErrorMessageAnnouncement();

            errorMessageAnnouncement.Id        = errorMessage.Id;
            errorMessageAnnouncement.Source    = errorMessage.Source;
            errorMessageAnnouncement.Message   = errorMessage.Message;
            errorMessageAnnouncement.Details   = errorMessage.Details;
            errorMessageAnnouncement.Timestamp = errorMessage.Timestamp;
            _eventBus.Publish(errorMessageAnnouncement, replyTo, correlationId);
        }
Example #3
0
        public static void LoadSelf(FactionRepository dbRepository)
        {
            bool import;

            try
            {
                Language language = dbRepository.GetLanguage(Settings.LanguageName);
                Settings.LanguageId = language.Id;
                import = false;
            }
            catch
            {
                import = true;
            }

            if (import)
            {
                Language language = new Language();
                language.Name = Settings.LanguageName;
                dbRepository.Add(language);
                Settings.LanguageId = language.Id;
            }
        }
        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);
                    }
                }
            }
        }
Example #5
0
        public static void LoadModules(FactionRepository dbRepository)
        {
            string[] files = Directory.GetFiles(Settings.ModulesPath, Settings.ModuleConfigName, SearchOption.AllDirectories);
            foreach (string file in files)
            {
                bool   import;
                string contents = File.ReadAllText(file);
                JsonSerializerSettings settings = new JsonSerializerSettings
                {
                    NullValueHandling     = NullValueHandling.Include,
                    MissingMemberHandling = MissingMemberHandling.Ignore
                };
                ModuleConfig moduleConfig = JsonConvert.DeserializeObject <ModuleConfig>(contents);
                try
                {
                    Module module = dbRepository.GetModule(moduleConfig.Name, Settings.LanguageName);
                    import = false;
                }
                catch
                {
                    import = true;
                }
                if (import)
                {
                    Module module = new Module();
                    module.Name          = moduleConfig.Name;
                    module.Description   = moduleConfig.Description;
                    module.Authors       = String.Join(", ", moduleConfig.Authors.ToArray());
                    module.BuildLocation = moduleConfig.BuildLocation;
                    module.BuildCommand  = moduleConfig.BuildCommand;
                    module.LanguageId    = Settings.LanguageId;
                    dbRepository.Add(module);

                    foreach (CommandConfig commandConfig in moduleConfig.Commands)
                    {
                        Command command = new Command();
                        command.Name           = commandConfig.Name;
                        command.Description    = commandConfig.Description;
                        command.Help           = commandConfig.Help;
                        command.MitreReference = commandConfig.MitreReference;
                        command.OpsecSafe      = commandConfig.OpsecSafe;
                        command.ModuleId       = module.Id;
                        if (commandConfig.Artifacts.Count > 0)
                        {
                            command.Artifacts = String.Join(",", commandConfig.Artifacts.ToArray());
                        }
                        dbRepository.Add(command);
                        foreach (CommandParameterConfig paramConfig in commandConfig.Parameters)
                        {
                            CommandParameter param = new CommandParameter();
                            param.Name      = paramConfig.Name;
                            param.CommandId = command.Id;
                            param.Help      = paramConfig.Help;
                            param.Required  = paramConfig.Required;
                            param.Position  = paramConfig.Position;
                            param.Values    = String.Join(",", paramConfig.Values.ToArray());
                            dbRepository.Add(param);
                        }
                    }
                }
            }
        }
Example #6
0
        public static void LoadAgents(FactionRepository dbRepository)
        {
            string[] files = Directory.GetFiles(Settings.AgentsPath, Settings.AgentConfigName, SearchOption.AllDirectories);
            foreach (string file in files)
            {
                string          contents        = File.ReadAllText(file);
                AgentTypeConfig agentTypeConfig = JsonConvert.DeserializeObject <AgentTypeConfig>(contents);
                AgentType       type            = dbRepository.GetAgentType(agentTypeConfig.Name);

                if (type == null)
                {
                    AgentType agentType = new AgentType();
                    agentType.Name          = agentTypeConfig.Name;
                    agentType.Guid          = agentTypeConfig.Guid;
                    agentType.Authors       = String.Join(", ", agentTypeConfig.Authors.ToArray());
                    agentType.LanguageId    = Settings.LanguageId;
                    agentType.BuildCommand  = agentTypeConfig.BuildCommand;
                    agentType.BuildLocation = agentTypeConfig.BuildLocation;
                    dbRepository.Add(agentType);

                    foreach (string value in agentTypeConfig.Architectures)
                    {
                        AgentTypeArchitecture agentTypeArchitecture = new AgentTypeArchitecture();
                        agentTypeArchitecture.Name        = value;
                        agentTypeArchitecture.AgentTypeId = agentType.Id;
                        dbRepository.Add(agentTypeArchitecture);
                    }

                    foreach (string value in agentTypeConfig.OperatingSystems)
                    {
                        AgentTypeOperatingSystem agentTypeOperatingSystem = new AgentTypeOperatingSystem();
                        agentTypeOperatingSystem.Name        = value;
                        agentTypeOperatingSystem.AgentTypeId = agentType.Id;
                        dbRepository.Add(agentTypeOperatingSystem);
                    }

                    foreach (string value in agentTypeConfig.Formats)
                    {
                        AgentTypeFormat agentTypeFormat = new AgentTypeFormat();
                        agentTypeFormat.Name        = value;
                        agentTypeFormat.AgentTypeId = agentType.Id;
                        dbRepository.Add(agentTypeFormat);
                    }

                    foreach (string value in agentTypeConfig.Versions)
                    {
                        AgentTypeVersion agentTypeVersion = new AgentTypeVersion();
                        agentTypeVersion.Name        = value;
                        agentTypeVersion.AgentTypeId = agentType.Id;
                        dbRepository.Add(agentTypeVersion);
                    }

                    foreach (string value in agentTypeConfig.Configurations)
                    {
                        AgentTypeConfiguration agentTypeConfiguration = new AgentTypeConfiguration();
                        agentTypeConfiguration.Name        = value;
                        agentTypeConfiguration.AgentTypeId = agentType.Id;
                        dbRepository.Add(agentTypeConfiguration);
                    }


                    foreach (AgentTransportConfig agentTransportConfig in agentTypeConfig.AgentTransportTypes)
                    {
                        AgentTransportType agentTransportType = new AgentTransportType();
                        agentTransportType.Name = agentTransportConfig.Name;
                        agentTransportType.TransportTypeGuid = agentTransportConfig.TransportTypeGuid;
                        agentTransportType.BuildCommand      = agentTransportConfig.BuildCommand;
                        agentTransportType.BuildLocation     = agentTransportConfig.BuildLocation;
                        agentTransportType.AgentTypeId       = agentType.Id;
                        dbRepository.Add(agentTransportType);
                    }

                    foreach (CommandConfig commandConfig in agentTypeConfig.Commands)
                    {
                        Command command = new Command();
                        command.Name           = commandConfig.Name;
                        command.Description    = commandConfig.Description;
                        command.Help           = commandConfig.Help;
                        command.MitreReference = commandConfig.MitreReference;
                        command.OpsecSafe      = commandConfig.OpsecSafe;
                        command.AgentTypeId    = agentType.Id;
                        if (commandConfig.Artifacts.Count > 0)
                        {
                            command.Artifacts = String.Join(",", commandConfig.Artifacts.ToArray());
                        }
                        dbRepository.Add(command);
                        foreach (CommandParameterConfig paramConfig in commandConfig.Parameters)
                        {
                            CommandParameter param = new CommandParameter();
                            param.Name      = paramConfig.Name;
                            param.CommandId = command.Id;
                            param.Help      = paramConfig.Help;
                            param.Required  = paramConfig.Required;
                            param.Position  = paramConfig.Position;
                            param.Values    = String.Join(",", paramConfig.Values.ToArray());
                            dbRepository.Add(param);
                        }
                    }
                }
            }
        }
        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 async Task Handle(NewStagingMessage newStagingMessage, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Got StagingMessage Message.");
            Payload payload = _taskRepository.GetPayload(newStagingMessage.PayloadName);

            if (payload.Enabled)
            {
                StagingMessage stagingMessage = new StagingMessage();
                // Decode and Decrypt AgentTaskResponse
                stagingMessage.HMAC        = newStagingMessage.HMAC;
                stagingMessage.IV          = newStagingMessage.IV;
                stagingMessage.Message     = newStagingMessage.Message;
                stagingMessage.PayloadName = newStagingMessage.PayloadName;
                stagingMessage.TransportId = newStagingMessage.TransportId;
                stagingMessage.SourceIp    = newStagingMessage.SourceIp;
                stagingMessage.Payload     = payload;
                stagingMessage.PayloadId   = stagingMessage.Payload.Id;
                _taskRepository.Add(stagingMessage);

                // Decrypt Message from Agent
                string decryptedMessage = Crypto.Decrypt(stagingMessage);
                Console.WriteLine($"Got response {decryptedMessage}");

                // Process taskResults
                // TODO: Probably a better way to check if the message is blank.
                if ((decryptedMessage != "[]") || (!String.IsNullOrEmpty(decryptedMessage)))
                {
                    Agent agent = JsonConvert.DeserializeObject <Agent>(decryptedMessage);
                    agent.Name               = Utility.GenerateSecureString(12);
                    agent.AesPassword        = Utility.GenerateSecureString(32);
                    agent.InitialCheckin     = DateTime.UtcNow;
                    agent.LastCheckin        = DateTime.UtcNow;
                    agent.BeaconInterval     = stagingMessage.Payload.BeaconInterval;
                    agent.ExternalIp         = stagingMessage.SourceIp;
                    agent.TransportId        = stagingMessage.TransportId;
                    agent.Jitter             = stagingMessage.Payload.Jitter;
                    agent.AgentType          = _taskRepository.GetAgentType(stagingMessage.Payload.AgentTypeId);
                    agent.AgentType.Language = _taskRepository.GetLanguage(agent.AgentType.LanguageId);
                    agent.AgentTypeId        = stagingMessage.Payload.AgentType.Id;
                    agent.Transport          = _taskRepository.GetTransport(stagingMessage.TransportId);
                    agent.Payload            = stagingMessage.Payload;

                    _taskRepository.Add(agent);

                    NewAgent newAgent = new NewAgent(agent);
                    _eventBus.Publish(newAgent);

                    // Create Agent tasks to setup agent
                    List <OutboundTask> stagingTasks = new List <OutboundTask>();

                    AgentTask agentNameTask = new AgentTask();
                    agentNameTask.AgentId = agent.Id;
                    agentNameTask.Action  = "SET";
                    agentNameTask.Command = $"Name:{agent.Name}";
                    _taskRepository.Add(agentNameTask);
                    stagingTasks.Add(new OutboundTask(agent.Name, agentNameTask));

                    AgentTask passwordTask = new AgentTask();
                    passwordTask.AgentId = agent.Id;
                    passwordTask.Action  = "SET";
                    passwordTask.Command = $"Password:{agent.AesPassword}";
                    _taskRepository.Add(passwordTask);
                    stagingTasks.Add(new OutboundTask(agent.Name, passwordTask));

                    AgentTask beaconTask = new AgentTask();
                    beaconTask.AgentId = agent.Id;
                    beaconTask.Action  = "SET";
                    beaconTask.Command = $"BeaconInterval:{agent.BeaconInterval.ToString()}";
                    _taskRepository.Add(beaconTask);
                    stagingTasks.Add(new OutboundTask(agent.Name, beaconTask));

                    AgentTask jitterTask = new AgentTask();
                    jitterTask.AgentId = agent.Id;
                    jitterTask.Action  = "SET";
                    jitterTask.Command = $"Jitter:{agent.Jitter.ToString()}";
                    _taskRepository.Add(jitterTask);
                    stagingTasks.Add(new OutboundTask(agent.Name, jitterTask));

                    AgentTask payloadNameTask = new AgentTask();
                    payloadNameTask.AgentId = agent.Id;
                    payloadNameTask.Action  = "SET";
                    payloadNameTask.Command = $"PayloadName:null";
                    _taskRepository.Add(payloadNameTask);
                    stagingTasks.Add(new OutboundTask(agent.Name, payloadNameTask));

                    AgentTask stagerIdTask = new AgentTask();
                    stagerIdTask.AgentId = agent.Id;
                    stagerIdTask.Action  = "SET";
                    stagerIdTask.Command = $"StagingId:null";
                    _taskRepository.Add(stagerIdTask);
                    stagingTasks.Add(new OutboundTask(agent.Name, stagerIdTask));

                    // Convert outbound message to json and encrypt with the staging message password
                    string jsonOutboundMessage             = JsonConvert.SerializeObject(stagingTasks);
                    Dictionary <string, string> encCommand = Crypto.Encrypt(jsonOutboundMessage, agent.Id, stagingMessage.Payload.Key);

                    // Create a StagingResponse object with the seralized/encrypted message contents
                    StagingResponse stagingResponse = new StagingResponse();
                    stagingResponse.Agent   = agent;
                    stagingResponse.Message = encCommand["encryptedMsg"];
                    stagingResponse.AgentId = agent.Id;
                    stagingResponse.HMAC    = encCommand["hmac"];
                    stagingResponse.IV      = encCommand["iv"];
                    stagingResponse.Sent    = false;

                    _taskRepository.Add(stagingResponse);

                    // Package for delivery
                    string stagingJson    = JsonConvert.SerializeObject(new OutboundStagingResponse(stagingResponse));
                    string encodedMessage = Convert.ToBase64String(Encoding.UTF8.GetBytes(stagingJson));
                    Dictionary <string, string> outboundMessage = new Dictionary <string, string>();
                    outboundMessage["AgentName"] = agent.StagingId;
                    outboundMessage["Message"]   = encodedMessage;
                    _eventBus.Publish(outboundMessage, replyTo, correlationId);
                }
                else
                {
                    Console.WriteLine($"[i] Payload is disabled. Staging message ignored.");
                }
            }
        }
Example #9
0
        public async Task Handle(NewPayload newPayload, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Got New Payload Message.");
            Payload payload = new Payload();

            payload.AgentType                  = _taskRepository.GetAgentType(newPayload.AgentTypeId);
            payload.AgentTransportType         = _taskRepository.GetAgentTransportType(newPayload.AgentTransportTypeId);
            payload.Transport                  = _taskRepository.GetTransport(newPayload.TransportId);
            payload.AgentTypeArchitectureId    = newPayload.ArchitectureId;
            payload.AgentTypeFormatId          = newPayload.FormatId;
            payload.AgentTypeVersionId         = newPayload.VersionId;
            payload.AgentTypeConfigurationId   = newPayload.AgentTypeConfigurationId;
            payload.AgentTypeOperatingSystemId = newPayload.OperatingSystemId;
            payload.Debug = newPayload.Debug;

            payload.Name           = newPayload.Name;
            payload.Description    = newPayload.Description;
            payload.Jitter         = newPayload.Jitter;
            payload.BeaconInterval = newPayload.BeaconInterval;
            payload.ExpirationDate = newPayload.ExpirationDate;
            payload.BuildToken     = newPayload.BuildToken;

            payload.Created    = DateTime.UtcNow;
            payload.Enabled    = true;
            payload.Visible    = true;
            payload.Built      = false;
            payload.Key        = Utility.GenerateSecureString(32);
            payload.LanguageId = Settings.LanguageId;
            _taskRepository.Add(payload);
            _eventBus.Publish(payload, replyTo, correlationId);

            string workingDir = Path.Join(Settings.AgentsPath, payload.AgentType.Name);

            // Create build config file
            BuildConfig buildConfig = CreateBuildConfig(payload);

            string buildConfigFile = Path.GetTempFileName();

            File.AppendAllText(buildConfigFile, JsonConvert.SerializeObject(buildConfig, Formatting.Indented));

            // Build transport first
            File.Delete(Path.Join(workingDir, payload.AgentTransportType.BuildLocation));

            string transportBuildCommand = $"{payload.AgentTransportType.BuildCommand} {buildConfigFile}";

            Dictionary <string, string> cmdResult = RunCommand(workingDir, transportBuildCommand);
            string transportB64 = "";

            if (cmdResult["ExitCode"] == "0")
            {
                byte[] transportBytes = File.ReadAllBytes(Path.Join(workingDir, payload.AgentTransportType.BuildLocation));
                transportB64 = Convert.ToBase64String(transportBytes);
                File.Delete(buildConfigFile);
            }
            else
            {
                Console.WriteLine($"ERROR DURING TRANSPORT BUILD: \nStdout: {cmdResult["Output"]}\n Stderr: {cmdResult["Error"]}");
                NewErrorMessage response = new NewErrorMessage();
                response.Source  = ".NET Build Server";
                response.Message = $"Error building {payload.AgentType.Name}";
                response.Details = $"Stdout: {cmdResult["Output"]}\n Stderr: {cmdResult["Error"]}";
                _eventBus.Publish(response, replyTo = null, correlationId = null);
            }

            // Build the agent
            if (!String.IsNullOrEmpty(transportB64))
            {
                buildConfig.TransportModule = transportB64;
                File.AppendAllText(buildConfigFile, JsonConvert.SerializeObject(buildConfig, Formatting.Indented));

                File.Delete(Path.Join(workingDir, payload.AgentType.BuildLocation));
                string buildCommand = $"{payload.AgentType.BuildCommand} {buildConfigFile}";
                cmdResult = RunCommand(workingDir, buildCommand);

                if (cmdResult["ExitCode"] == "0")
                {
                    try {
                        Console.WriteLine($"[PayloadBuildService] Build Successful!");
                        string originalPath  = Path.Join(workingDir, payload.AgentType.BuildLocation);
                        string fileExtension = Path.GetExtension(originalPath);
                        string payloadPath   = Path.Join(Settings.AgentsPath, "/build/", $"{payload.AgentType.Name}_{payload.AgentTypeConfiguration.Name}_{payload.Name}_{DateTime.Now.ToString("yyyyMMddHHmmss")}{fileExtension}");
                        Console.WriteLine($"[PayloadBuildService] Moving from {originalPath} to {payloadPath}");
                        File.Move(originalPath, payloadPath);
                        string    uploadUlr = $"{apiUrl}/{payload.Id}/file/";
                        WebClient wc        = new WebClient();
                        wc.Headers.Add("build-token", payload.BuildToken);
                        Console.WriteLine($"[PayloadBuildService] Uploading to {uploadUlr} with token {payload.BuildToken}");
                        byte[] resp = wc.UploadFile(uploadUlr, payloadPath);
                        Console.WriteLine($"[PayloadBuildService] Response: {wc.Encoding.GetString(resp)}");
                        //File.Delete(buildConfigFile);
                    }
                    catch (Exception e) {
                        Console.WriteLine($"ERROR UPLOADING PAYLOAD TO API: \n{e.Message}");
                        NewErrorMessage response = new NewErrorMessage();
                        response.Source  = ".NET Build Server";
                        response.Message = $"Error uploading {payload.AgentType.Name} payload to API";
                        response.Details = $"{e.Message}";
                        _eventBus.Publish(response, replyTo = null, correlationId = null);
                    }
                }
                else
                {
                    Console.WriteLine($"ERROR DURING AGENT BUILD: \nStdout: {cmdResult["Output"]}\n Stderr: {cmdResult["Error"]}");
                    NewErrorMessage response = new NewErrorMessage();
                    response.Source  = ".NET Build Server";
                    response.Message = $"Error building {payload.AgentType.Name}";
                    response.Details = $"Stdout: {cmdResult["Output"]}\n Stderr: {cmdResult["Error"]}";
                    _eventBus.Publish(response, replyTo = null, correlationId = null);
                }
            }
            else
            {
                Console.WriteLine($"ERROR DURING AGENT BUILD: \nStdout: {cmdResult["Output"]}\n Stderr: {cmdResult["Error"]}");
                NewErrorMessage response = new NewErrorMessage();
                response.Source  = ".NET Build Server";
                response.Message = $"Error building {payload.AgentType.Name}";
                response.Details = $"Tried to build an agent without a Base64 encoded transport string. Transport build must have failed.";
                _eventBus.Publish(response, replyTo = null, correlationId = null);
            }
        }