diff --git a/decnet/ttp/stix_export.py b/decnet/ttp/stix_export.py index dd361b22..5d36b450 100644 --- a/decnet/ttp/stix_export.py +++ b/decnet/ttp/stix_export.py @@ -284,12 +284,22 @@ def build_attacker_bundle( seen_cmds.add(cmd_line) proc = stix2.Process(command_line=cmd_line, is_hidden=False) objs.append(proc) + proc_obs = stix2.ObservedData( + first_observed=fs or now, + last_observed=ls or now, + number_observed=1, + object_refs=[proc.id], + created_by_ref=org.id, + ) + objs.append(proc_obs) objs.append( - stix2.ObservedData( - first_observed=fs or now, - last_observed=ls or now, - number_observed=1, - object_refs=[proc.id], + stix2.Sighting( + sighting_of_ref=ta.id, + first_seen=fs or now, + last_seen=ls or now, + count=1, + where_sighted_refs=[org.id], + observed_data_refs=[proc_obs.id], created_by_ref=org.id, ) ) diff --git a/tests/web/test_api_export_attacker_stix.py b/tests/web/test_api_export_attacker_stix.py index 4e79c97a..7c8124ae 100644 --- a/tests/web/test_api_export_attacker_stix.py +++ b/tests/web/test_api_export_attacker_stix.py @@ -245,6 +245,11 @@ async def test_commands_emit_process_scos(): assert len(processes) == 2 cmd_lines = {p["command_line"] for p in processes} assert cmd_lines == {"whoami", "cat /etc/passwd"} + # Each unique command emits a Sighting back to the threat-actor (no TTP tags here) + sightings = [o for o in objs if o["type"] == "sighting"] + assert len(sightings) == 2 + ta_id = next(o["id"] for o in objs if o["type"] == "threat-actor") + assert all(s["sighting_of_ref"] == ta_id for s in sightings) @pytest.mark.asyncio