예제 #1
0
        public async Task Handle(UpdateTransport updateTransport, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Updating Transport..");
            Transport transport = _taskRepository.GetTransport(updateTransport.Id);

            transport.Name          = updateTransport.Name;
            transport.TransportType = updateTransport.TransportType;
            transport.Visible       = updateTransport.Visible;
            transport.Enabled       = updateTransport.Enabled;
            transport.Configuration = updateTransport.Configuration;
            transport.Guid          = updateTransport.Guid;
            if (!transport.Visible)
            {
                transport.Enabled = false;
            }

            ApiKey apiKey = _taskRepository.GetApiKey(transport.ApiKeyId.Value);

            if (!transport.Enabled)
            {
                apiKey.Enabled = false;
                _taskRepository.Update(apiKey.Id, apiKey);
            }
            else if (!apiKey.Enabled)
            {
                apiKey.Enabled = true;
                _taskRepository.Update(apiKey.Id, apiKey);
            }

            transport = _taskRepository.Update(transport.Id, transport);

            TransportUpdated transportUpdated = new TransportUpdated();

            transportUpdated.Success   = true;
            transportUpdated.Transport = transport;
            _eventBus.Publish(transportUpdated, replyTo, correlationId);
        }
        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 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.");
                }
            }
        }
예제 #4
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);
            }
        }