Skip to content

Commit

Permalink
Merge branch 'master' of github.com-ddupdyke-sei:cmu-sei/GHOSTS
Browse files Browse the repository at this point in the history
  • Loading branch information
sei-dupdyke committed Oct 9, 2020
2 parents 7c14467 + 5a65191 commit 99d8dfd
Show file tree
Hide file tree
Showing 49 changed files with 702 additions and 414 deletions.
7 changes: 6 additions & 1 deletion src/Ghosts.Api/Controllers/ClientIdController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@

namespace Ghosts.Api.Controllers
{
/// <summary>
/// GHOSTS CLIENT CONTROLLER
/// These endpoints are typically only used by GHOSTS Clients installed and configured to use the GHOSTS C2
/// </summary>
[Produces("application/json")]
[Route("api/[controller]")]
public class ClientIdController : Controller
Expand All @@ -25,8 +29,9 @@ public ClientIdController(IMachineService service)
}

/// <summary>
/// Clients post to this endpoint to get their unique GHOSTS system ID
/// Clients use this endpoint to get their unique GHOSTS system ID
/// </summary>
/// <param name="ct">Cancellation Token</param>
/// <returns>A client's particular unique GHOSTS system ID (GUID)</returns>
[HttpGet]
public async Task<IActionResult> Index(CancellationToken ct)
Expand Down
12 changes: 7 additions & 5 deletions src/Ghosts.Api/Controllers/ClientResultsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@

namespace Ghosts.Api.Controllers
{
/// <summary>
/// GHOSTS CLIENT CONTROLLER
/// These endpoints are typically only used by GHOSTS Clients installed and configured to use the GHOSTS C2
/// </summary>
[Produces("application/json")]
[Route("api/[controller]")]
public class ClientResultsController : Controller
Expand All @@ -28,7 +32,7 @@ public ClientResultsController(IBackgroundQueue service)
}

/// <summary>
/// Clients post an encrypted timeline or health payload to this endpoint
/// Clients post an encrypted timeline or health payload to this endpoint
/// </summary>
/// <param name="transmission">The encrypted timeline or health log payload</param>
/// <param name="ct">Cancellation Token</param>
Expand All @@ -42,7 +46,7 @@ public IActionResult Secure([FromBody] EncryptedPayload transmission, Cancellati
{
var key = Request.Headers["ghosts-name"].ToString();
//decrypt
transmission.Payload = Crypto.Base64Decode(transmission.Payload);
transmission.Payload = Base64Encoder.Base64Decode(transmission.Payload);
raw = Crypto.DecryptStringAes(transmission.Payload, key);
}
catch (Exception exc)
Expand All @@ -58,7 +62,7 @@ public IActionResult Secure([FromBody] EncryptedPayload transmission, Cancellati
}

/// <summary>
/// Clients post a timeline or health payload to this endpoint
/// Clients post a timeline or health payload to this endpoint
/// </summary>
/// <param name="value">Timeline or health log payload</param>
/// <param name="ct">Cancellation Token</param>
Expand All @@ -74,8 +78,6 @@ private IActionResult Process(HttpContext context, HttpRequest request, Transfer
{
var id = request.Headers["ghosts-id"];

//log.Trace($"Request by {id}");

var m = WebRequestReader.GetMachine(HttpContext);

if (!string.IsNullOrEmpty(id))
Expand Down
14 changes: 10 additions & 4 deletions src/Ghosts.Api/Controllers/ClientSurveyController.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
using System;
// Copyright 2017 Carnegie Mellon University. All Rights Reserved. See LICENSE.md file for terms.

using System;
using System.Threading;
using Ghosts.Api.Infrastructure;
using Ghosts.Api.Models;
Expand All @@ -12,6 +14,10 @@

namespace ghosts.api.Controllers
{
/// <summary>
/// GHOSTS CLIENT CONTROLLER
/// These endpoints are typically only used by GHOSTS Clients installed and configured to use the GHOSTS C2
/// </summary>
[Produces("application/json")]
[Route("api/[controller]")]
public class ClientSurveyController : Controller
Expand All @@ -25,7 +31,7 @@ public ClientSurveyController(IBackgroundQueue service)
}

/// <summary>
/// Clients post an encrypted survey result to this endpoint
/// Clients post an encrypted survey results to this endpoint
/// </summary>
/// <param name="transmission">The encrypted survey result</param>
/// <param name="ct">Cancellation Token</param>
Expand All @@ -39,7 +45,7 @@ public IActionResult Secure([FromBody] EncryptedPayload transmission, Cancellati
{
var key = Request.Headers["ghosts-name"].ToString();
//decrypt - the headers must be the same as encrypted with the client
transmission.Payload = Crypto.Base64Decode(transmission.Payload);
transmission.Payload = Base64Encoder.Base64Decode(transmission.Payload);
raw = Crypto.DecryptStringAes(transmission.Payload, key);
}
catch (Exception exc)
Expand All @@ -55,7 +61,7 @@ public IActionResult Secure([FromBody] EncryptedPayload transmission, Cancellati
}

/// <summary>
/// Clients post survey result to this endpoint
/// Clients post survey results to this endpoint
/// </summary>
/// <param name="value">The client survey result</param>
/// <param name="ct">Cancellation Token</param>
Expand Down
77 changes: 77 additions & 0 deletions src/Ghosts.Api/Controllers/ClientTimeline.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// Copyright 2017 Carnegie Mellon University. All Rights Reserved. See LICENSE.md file for terms.

using System;
using System.Threading;
using System.Threading.Tasks;
using Ghosts.Api.Infrastructure;
using Ghosts.Api.Services;
using Ghosts.Domain;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using NLog;

namespace ghosts.api.Controllers
{
/// <summary>
/// GHOSTS CLIENT CONTROLLER
/// These endpoints are typically only used by GHOSTS Clients installed and configured to use the GHOSTS C2
/// </summary>
[Produces("application/json")]
[Route("api/[controller]")]
public class ClientTimelineController : Controller
{
private static readonly Logger _log = LogManager.GetCurrentClassLogger();
private readonly IMachineTimelineService _service;
private readonly IMachineService _machineService;

public ClientTimelineController(IMachineTimelineService service, IMachineService machineService)
{
_service = service;
_machineService = machineService;
}

/// <summary>
/// Clients pot their timelines here, so that the C2 knows what a particular agent is doing
/// </summary>
/// <param name="timeline">The client's current timeline</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>The saved timeline record</returns>
[HttpPost]
public async Task<IActionResult> Index([FromBody] string timeline, CancellationToken ct)
{
var id = Request.Headers["ghosts-id"];

_log.Trace($"Request by {id}");

var m = WebRequestReader.GetMachine(HttpContext);

if (!string.IsNullOrEmpty(id))
{
m.Id = new Guid(id);
await _machineService.CreateAsync(m, ct);
}
else
{
if (!m.IsValid())
{
return StatusCode(StatusCodes.Status401Unauthorized, "Invalid machine request");
}
}

Timeline tl;

try
{
tl = JsonConvert.DeserializeObject<Timeline>(timeline);
}
catch (Exception e)
{
Console.WriteLine(e);
return StatusCode(StatusCodes.Status400BadRequest, "Invalid timeline file");
}

return Ok(await _service.CreateAsync(m, tl, ct));
}
}
}
6 changes: 5 additions & 1 deletion src/Ghosts.Api/Controllers/ClientUpdatesController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@

namespace Ghosts.Api.Controllers
{
/// <summary>
/// GHOSTS CLIENT CONTROLLER
/// These endpoints are typically only used by GHOSTS Clients installed and configured to use the GHOSTS C2
/// </summary>
[Produces("application/json")]
[Route("api/[controller]")]
public class ClientUpdatesController : Controller
Expand All @@ -28,7 +32,7 @@ public ClientUpdatesController(IMachineUpdateService updateService, IBackgroundQ
}

/// <summary>
/// Clients check for updates to download here
/// Clients use this endpoint to check for updates for them to download
/// </summary>
/// <param name="ct">Cancellation Token</param>
/// <returns>404 if no update, or a json payload of a particular update</returns>
Expand Down
8 changes: 6 additions & 2 deletions src/Ghosts.Api/Controllers/GroupHealthController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,10 @@
using System.Threading.Tasks;
using Ghosts.Api.Models;
using Ghosts.Api.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;

namespace Ghosts.Api.Controllers
{
[Authorize(Policy = "ApiUser")]
[Produces("application/json")]
[Route("api/group-health")]
[ResponseCache(Duration = 5)]
Expand All @@ -26,6 +24,12 @@ public GroupHealthController(IMachineGroupService service, IMachineService servi
_serviceMachine = serviceMachine;
}

/// <summary>
/// Endpoint returns health records for all of the machines in a group
/// </summary>
/// <param name="id">Group Id</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>Health records for machines in the group</returns>
[HttpGet("{id}")]
public async Task<IActionResult> Index([FromRoute] int id, CancellationToken ct)
{
Expand Down
9 changes: 6 additions & 3 deletions src/Ghosts.Api/Controllers/HomeController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
namespace Ghosts.Api.Controllers
{
[Produces("application/json")]
[Route("api/Home")]
[Route("api/home")]
[ResponseCache(Duration = 60)]
public class HomeController : Controller
{
Expand All @@ -21,9 +21,12 @@ public HomeController(ApplicationDbContext context)
}

/// <summary>
/// API Home
/// API Home, often used to verify API is working correctly
/// </summary>
/// <returns>Basic check information including version number, and a simple database connection counting machines and groups</returns>
/// <returns>
/// Basic check information including version number,
/// and a simple database connection counting machines and groups
/// </returns>
[HttpGet]
public IActionResult Index()
{
Expand Down
54 changes: 44 additions & 10 deletions src/Ghosts.Api/Controllers/MachineGroupsController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,13 @@
using Ghosts.Api.Models;
using Ghosts.Api.Services;
using Ghosts.Domain;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using NLog;

namespace Ghosts.Api.Controllers
{
//[Authorize(Policy = "ApiUser")]
[Produces("application/json")]
[Route("api/MachineGroups")]
[Route("api/machinegroups")]
[ResponseCache(Duration = 5)]
public class MachineGroupsController : Controller
{
Expand All @@ -31,14 +29,24 @@ public MachineGroupsController(IMachineGroupService service, IMachineService mac
_serviceMachine = machineService;
}

// GET: api/MachineGroups
/// <summary>
/// Gets the group information and the machines contained therein based on the provided query
/// </summary>
/// <param name="q">Query</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>Group information</returns>
[HttpGet]
public async Task<IEnumerable<Group>> GetMachineGroup(string q, CancellationToken ct)
{
return await _service.GetAsync(q, ct);
}

// GET: api/MachineGroups/5
/// <summary>
/// Gets the group information and the machines contained therein based on a specific group Id
/// </summary>
/// <param name="id">Group Id</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>Group information</returns>
[HttpGet("{id}")]
public async Task<IActionResult> GetMachineGroup([FromRoute] int id, CancellationToken ct)
{
Expand All @@ -50,7 +58,12 @@ public async Task<IActionResult> GetMachineGroup([FromRoute] int id, Cancellatio
return Ok(machineGroup);
}

// PUT: api/MachineGroups/5
/// <summary>
/// Updates a group's information
/// </summary>
/// <param name="model">The group to update</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>The updated group</returns>
[HttpPut("{id}")]
public async Task<IActionResult> PutMachineGroup([FromBody] Group model, CancellationToken ct)
{
Expand All @@ -61,7 +74,12 @@ public async Task<IActionResult> PutMachineGroup([FromBody] Group model, Cancell
return Ok(model);
}

// POST: api/MachineGroups
/// <summary>
/// Create new group
/// </summary>
/// <param name="model">The new group to add</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>The saved group</returns>
[HttpPost]
public async Task<IActionResult> PostMachineGroup([FromBody] Group model, CancellationToken ct)
{
Expand All @@ -72,7 +90,12 @@ public async Task<IActionResult> PostMachineGroup([FromBody] Group model, Cancel
return CreatedAtAction("GetMachineGroup", new {id}, model);
}

// DELETE: api/MachineGroups/5
/// <summary>
/// Deletes a specific group
/// </summary>
/// <param name="id">The group to delete</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>204 No Content</returns>
[HttpDelete("{id}")]
[ResponseCache(Duration = 0)]
public async Task<IActionResult> DeleteMachineGroup([FromRoute] int id, CancellationToken ct)
Expand All @@ -84,7 +107,13 @@ public async Task<IActionResult> DeleteMachineGroup([FromRoute] int id, Cancella
return NoContent();
}

[AllowAnonymous]
/// <summary>
/// Send a specific command to a group of machines
/// </summary>
/// <param name="id">Group ID</param>
/// <param name="command">The command to execute</param>
/// <param name="ct">Cancellation Token</param>
/// <returns>The results of running the command on each machine</returns>
[HttpPost("{id}/command")]
public async Task<IActionResult> SendCommand([FromRoute] int id, string command, CancellationToken ct)
{
Expand Down Expand Up @@ -118,7 +147,12 @@ public async Task<IActionResult> SendCommand([FromRoute] int id, string command,
}
}

[AllowAnonymous]
/// <summary>
/// Gets teh activity for a group of machines
/// </summary>
/// <param name="id">Group ID</param>
/// <param name="ct">Cancellation token</param>
/// <returns>The activity for the group</returns>
[HttpGet("{id}/activity")]
public async Task<IActionResult> Activity([FromRoute] int id, CancellationToken ct)
{
Expand Down

0 comments on commit 99d8dfd

Please sign in to comment.