feat(c2): integrate Mythic command and control (sprint 8) #11

Merged
knacky merged 16 commits from sprint/8-c2 into main 2026-06-11 10:29:19 +00:00
3 changed files with 22 additions and 1 deletions
Showing only changes of commit 7d3d39639e - Show all commits

View File

@@ -360,6 +360,7 @@ def list_simulation_tasks(sid: int):
"status": t.status,
"completed": t.completed,
"output": t.output,
"source": t.source.value,
"mapping_applied": t.mapping_applied,
"created_at": t.created_at.isoformat() if t.created_at else None,
"completed_at": t.completed_at.isoformat() if t.completed_at else None,

View File

@@ -282,6 +282,25 @@ class TestImportHappyPath:
resp = _import(client, redteam_token, sim["id"], [100])
assert resp.status_code == 200
def test_source_field_is_import_in_tasks_listing(
self, monkeypatch, client: FlaskClient, admin_token: str
) -> None:
"""Imported tasks appear with source='import' in GET /c2/tasks response."""
_make_completed_get_task(monkeypatch)
eng = _make_engagement(client, admin_token)
_put_config(client, admin_token, eng["id"])
sim = _make_sim(client, admin_token, eng["id"])
_import(client, admin_token, sim["id"], [100])
resp = client.get(
f"/api/simulations/{sim['id']}/c2/tasks",
headers=_h(admin_token),
)
assert resp.status_code == 200
task = resp.get_json()["tasks"][0]
assert task["source"] == "import"
def test_no_transition_when_all_skipped(
self, app: Flask, monkeypatch, client: FlaskClient, admin_token: str
) -> None:

View File

@@ -117,8 +117,9 @@ class TestListTasksHappyPath:
task = resp.get_json()["tasks"][0]
for field in ("id", "mythic_task_display_id", "callback_display_id",
"command", "params", "status", "completed", "output",
"mapping_applied", "created_at", "completed_at"):
"source", "mapping_applied", "created_at", "completed_at"):
assert field in task, f"missing field: {field}"
assert task["source"] == "mimic"
def test_first_poll_returns_submitted(
self, client: FlaskClient, admin_token: str