Beispiel #1
0
        public async Task Handle(UpdateAgent updateAgent, string replyTo, string correlationId)
        {
            Console.WriteLine($"[i] Got Update Agent Message.");
            Agent agent = _taskRepository.GetAgent(updateAgent.Id);

            agent.Name    = updateAgent.Name;
            agent.Visible = updateAgent.Visible;
            _taskRepository.Update(agent.Id, agent);

            AgentUpdated agentUpdated = new AgentUpdated {
                Success = true, Agent = agent
            };

            _eventBus.Publish(agentUpdated, replyTo, correlationId);
        }
        public async Task <AgentEntity> Handle(UpsertActorCommand request, CancellationToken cancellationToken)
        {
            // Try find in cache
            AgentEntity actor = await _mediator.Send(GetAgentQuery.Create(request.Actor), cancellationToken);

            if (actor == null)
            {
                actor = (request.Actor.ObjectType == ObjectType.Agent
                    ? _mapper.Map <AgentEntity>(request.Actor)
                    : _mapper.Map <GroupEntity>(request.Actor));
                actor.AgentId = Guid.NewGuid();
                _context.Agents.Add(actor);
            }

            if (request.Actor is Group group && actor is GroupEntity groupEntity)
            {
                if (_context.Entry(actor).State != EntityState.Added)
                {
                    _context.Entry(actor).State = EntityState.Modified;
                }

                // Perform group update logic, add group member etc.
                foreach (var member in group.Member)
                {
                    var savedGrpActor = await _mediator.Send(UpsertActorCommand.Create(member), cancellationToken);

                    if (groupEntity.Members.Any(x => x.AgentId == savedGrpActor.AgentId))
                    {
                        continue;
                    }

                    groupEntity.Members.Add(new GroupMemberEntity()
                    {
                        GroupMemberId = Guid.NewGuid(),
                        AgentId       = savedGrpActor.AgentId,
                        GroupId       = groupEntity.AgentId,
                    });
                }

                await _mediator.Publish(AgentUpdated.Create(actor)).ConfigureAwait(false);
            }

            return(actor);
        }
        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);
                    }
                }
            }
        }
Beispiel #4
0
        public async Task <AgentEntity> Handle(UpsertActorCommand request, CancellationToken cancellationToken)
        {
            AgentEntity persona = await _mediator.Send(GetAgentQuery.Create(request.Actor), cancellationToken);

            bool isNew = false;

            if (persona == null)
            {
                persona = (request.Actor.ObjectType == ObjectType.Agent
                    ? _mapper.Map <AgentEntity>(request.Actor)
                    : _mapper.Map <GroupEntity>(request.Actor));
                persona.AgentId = Guid.NewGuid();

                if (persona.ObjectType == EntityObjectType.Agent &&
                    !string.IsNullOrEmpty(request.Actor.Name))
                {
                    persona.Person = new PersonEntity()
                    {
                        PersonId = Guid.NewGuid(),
                        Name     = request.Actor.Name
                    };
                }

                _context.Agents.Add(persona);
                await _context.SaveChangesAsync(cancellationToken);

                isNew = true;
            }

            if (!isNew)
            {
                if (request.Actor is Group group &&
                    !group.IsAnonymous() &&
                    persona is GroupEntity groupEntity)
                {
                    var upserts = group.Member.Select(member => _mediator.Send(UpsertActorCommand.Create(member), cancellationToken));
                    var members = await Task.WhenAll(upserts);

                    // Remove any members that does not exist in the request group
                    foreach (var member in groupEntity.Members)
                    {
                        if (!members.Any(x => x.AgentId == member.AgentId))
                        {
                            groupEntity.Members.Remove(member);
                        }
                    }

                    // Add any member that does not exist in the stored group from the request group
                    foreach (var member in members)
                    {
                        if (!groupEntity.Members.Any(x => x.AgentId == member.AgentId))
                        {
                            groupEntity.Members.Add(new GroupMemberEntity()
                            {
                                GroupId = groupEntity.AgentId,
                                AgentId = member.AgentId
                            });
                        }
                    }

                    await _mediator.Publish(AgentUpdated.Create(persona));
                }
            }

            await _context.SaveChangesAsync(cancellationToken);

            return(persona);
        }
        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);
                }
            }
        }