Example #1
0
 public ActionResult CreateDownloadEvent([FromBody] DownloadEvent downloadEvent)
 {
     downloadEvent.Time = DateTime.UtcNow;
     downloadEvent.WriteToDisk();
     _context.Events.Add(downloadEvent);
     _context.SaveChanges();
     return(CreatedAtRoute(nameof(GetEvent), new { id = downloadEvent.Id }, downloadEvent));
 }
        public ActionResult <GruntTasking> EditGruntTasking(int id, int tid, [FromBody] GruntTasking gruntTasking)
        {
            Grunt grunt = _context.Grunts.FirstOrDefault(G => G.Id == id);

            if (grunt == null)
            {
                return(NotFound($"NotFound - Grunt with id: {id}"));
            }
            GruntTasking updatingGruntTasking = _context.GruntTaskings.FirstOrDefault(GT => grunt.Id == GT.GruntId && tid == GT.Id);

            if (updatingGruntTasking == null)
            {
                return(NotFound($"NotFound - GruntTasking with id: {tid}"));
            }
            GruntTask gruntTask = _context.GruntTasks.FirstOrDefault(G => G.Id == gruntTasking.TaskId);

            if (gruntTask == null)
            {
                return(NotFound($"NotFound - GruntTask with id: {gruntTasking.TaskId}"));
            }
            GruntTask DownloadTask = _context.GruntTasks.FirstOrDefault(GT => GT.Name == "Download");

            if (DownloadTask == null)
            {
                return(NotFound($"NotFound - GruntTask DownloadTask"));
            }

            List <CapturedCredential> capturedCredentials = CapturedCredential.ParseCredentials(gruntTasking.GruntTaskOutput);

            foreach (CapturedCredential cred in capturedCredentials)
            {
                if (!ContextContainsCredentials(cred))
                {
                    _context.Credentials.Add(cred);
                    _context.SaveChanges();
                }
            }

            GruntTaskingStatus newStatus      = gruntTasking.Status;
            GruntTaskingStatus originalStatus = updatingGruntTasking.Status;

            if ((originalStatus == GruntTaskingStatus.Tasked || originalStatus == GruntTaskingStatus.Progressed) &&
                newStatus == GruntTaskingStatus.Completed)
            {
                if (gruntTasking.Type == GruntTaskingType.Kill)
                {
                    grunt.Status = Grunt.GruntStatus.Killed;
                }
                else if (gruntTasking.Type == GruntTaskingType.SetDelay || gruntTasking.Type == GruntTaskingType.SetJitter || gruntTasking.Type == GruntTaskingType.SetConnectAttempts)
                {
                    bool parsed = int.TryParse(gruntTasking.TaskingMessage, out int n);
                    if (parsed)
                    {
                        if (gruntTasking.Type == GruntTaskingType.SetDelay)
                        {
                            grunt.Delay = n;
                        }
                        else if (gruntTasking.Type == GruntTaskingType.SetJitter)
                        {
                            grunt.JitterPercent = n;
                        }
                        else if (gruntTasking.Type == GruntTaskingType.SetConnectAttempts)
                        {
                            grunt.ConnectAttempts = n;
                        }
                    }
                }
                else if (gruntTasking.Type == GruntTaskingType.Connect)
                {
                    if (originalStatus == GruntTaskingStatus.Tasked)
                    {
                        // Check if this Grunt was already connected
                        string hostname = gruntTasking.GruntTaskingMessage.Message.Split(",")[0];
                        string pipename = gruntTasking.GruntTaskingMessage.Message.Split(",")[1];
                        Grunt  previouslyConnectedGrunt = _context.Grunts.FirstOrDefault(G =>
                                                                                         G.CommType == Grunt.CommunicationType.SMB &&
                                                                                         (G.IPAddress == hostname || G.Hostname == hostname) &&
                                                                                         G.SMBPipeName == pipename &&
                                                                                         (G.Status == Grunt.GruntStatus.Disconnected || G.Status == Grunt.GruntStatus.Lost || G.Status == Grunt.GruntStatus.Active)
                                                                                         );
                        if (previouslyConnectedGrunt != null)
                        {
                            if (previouslyConnectedGrunt.Status != Grunt.GruntStatus.Disconnected)
                            {
                                // If already connected, disconnect to avoid cycles
                                Grunt previouslyConnectedGruntPrevParent = null;
                                foreach (Grunt g in _context.Grunts)
                                {
                                    if (g.Children.Contains(previouslyConnectedGrunt.GUID))
                                    {
                                        previouslyConnectedGruntPrevParent = g;
                                    }
                                }
                                if (previouslyConnectedGruntPrevParent != null)
                                {
                                    previouslyConnectedGruntPrevParent.RemoveChild(previouslyConnectedGrunt);
                                    _context.Grunts.Update(previouslyConnectedGruntPrevParent);
                                }
                            }

                            // Connect to tasked Grunt, no need to "Progress", as Grunt is already staged
                            grunt.AddChild(previouslyConnectedGrunt);
                            previouslyConnectedGrunt.Status = Grunt.GruntStatus.Active;
                            _context.Grunts.Update(previouslyConnectedGrunt);
                        }
                        else
                        {
                            // If not already connected, the Grunt is going to stage, set status to Progressed
                            newStatus = GruntTaskingStatus.Progressed;
                        }
                    }
                    else if (originalStatus == GruntTaskingStatus.Progressed)
                    {
                        // Connecting Grunt has staged, add as Child
                        string hostname     = gruntTasking.GruntTaskingMessage.Message.Split(",")[0];
                        string pipename     = gruntTasking.GruntTaskingMessage.Message.Split(",")[1];
                        Grunt  stagingGrunt = _context.Grunts.FirstOrDefault(G =>
                                                                             G.CommType == Grunt.CommunicationType.SMB &&
                                                                             ((G.IPAddress == hostname || G.Hostname == hostname) || (G.IPAddress == "" && G.Hostname == "")) &&
                                                                             G.SMBPipeName == pipename &&
                                                                             G.Status == Grunt.GruntStatus.Stage0
                                                                             );
                        if (stagingGrunt == null)
                        {
                            return(NotFound($"NotFound - Grunt staging from {hostname}:{pipename}"));
                        }
                        grunt.AddChild(stagingGrunt);
                    }
                }
                else if (gruntTasking.Type == GruntTaskingType.Disconnect)
                {
                    Grunt disconnectFromGrunt = _context.Grunts.FirstOrDefault(G => G.GUID == gruntTasking.GruntTaskingMessage.Message);
                    if (disconnectFromGrunt == null)
                    {
                        return(NotFound($"NotFound - Grunt with GUID: {gruntTasking.GruntTaskingMessage.Message}"));
                    }

                    disconnectFromGrunt.Status = Grunt.GruntStatus.Disconnected;
                    _context.Grunts.Update(disconnectFromGrunt);
                    grunt.RemoveChild(disconnectFromGrunt);
                }
            }

            if ((newStatus == GruntTaskingStatus.Completed || newStatus == GruntTaskingStatus.Progressed) && originalStatus != newStatus)
            {
                if (newStatus == GruntTaskingStatus.Completed)
                {
                    updatingGruntTasking.CompletionTime = DateTime.UtcNow;
                }
                string verb = newStatus == GruntTaskingStatus.Completed ? "completed" : "progressed";
                if (gruntTasking.TaskId == DownloadTask.Id)
                {
                    _context.Events.Add(new Event
                    {
                        Time          = updatingGruntTasking.CompletionTime,
                        MessageHeader = "[" + updatingGruntTasking.CompletionTime + " UTC] Grunt: " + grunt.Name + " has " + verb + " GruntTasking: " + gruntTasking.Name,
                        Level         = Event.EventLevel.Highlight,
                        Context       = grunt.Name
                    });
                    string        FileName      = Common.CovenantEncoding.GetString(Convert.FromBase64String(gruntTasking.TaskingMessage.Split(",")[1]));
                    DownloadEvent downloadEvent = new DownloadEvent
                    {
                        Time          = updatingGruntTasking.CompletionTime,
                        MessageHeader = "Downloaded: " + FileName + "\r\n" + "Syncing to Elite...",
                        Level         = Event.EventLevel.Highlight,
                        Context       = grunt.Name,
                        FileName      = FileName,
                        FileContents  = gruntTasking.GruntTaskOutput,
                        Progress      = DownloadEvent.DownloadProgress.Complete
                    };
                    downloadEvent.WriteToDisk();
                    _context.Events.Add(downloadEvent);
                }
                else
                {
                    _context.Events.Add(new Event
                    {
                        Time          = updatingGruntTasking.CompletionTime,
                        MessageHeader = "[" + updatingGruntTasking.CompletionTime + " UTC] Grunt: " + grunt.Name + " has " + verb + " GruntTasking: " + gruntTasking.Name,
                        MessageBody   = "(" + gruntTasking.TaskingUser + ") > " + gruntTasking.TaskingCommand + Environment.NewLine + gruntTasking.GruntTaskOutput,
                        Level         = Event.EventLevel.Highlight,
                        Context       = grunt.Name
                    });
                }
            }

            updatingGruntTasking.Status          = newStatus;
            updatingGruntTasking.GruntTaskOutput = gruntTasking.GruntTaskOutput;
            _context.GruntTaskings.Update(updatingGruntTasking);
            _context.Grunts.Update(grunt);
            _context.SaveChanges();

            return(updatingGruntTasking);
        }