Skip to content

Commit

Permalink
[Recorded Future] handle exception raised when no attachment and no o…
Browse files Browse the repository at this point in the history
…bject_refs to report (#2938)
  • Loading branch information
helene-nguyen authored Dec 7, 2024
1 parent 56359e9 commit 9e007e5
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 5 deletions.
10 changes: 7 additions & 3 deletions external-import/recorded-future/src/rflib/rf_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,8 +77,12 @@ def get_notes(
if pull_signatures and "attachment" in attributes:
try:
result = self.get_attachment(note["id"])
attributes["attachment_content"] = result["rules"][0]["content"]
attributes["attachment_type"] = result["type"]
if result:
attributes["attachment_content"] = result["rules"][0]["content"]
attributes["attachment_type"] = result["type"]
else:
msg = "[ANALYST NOTES] No attachment found"
self.helper.log_error(msg)
except requests.exceptions.HTTPError as err:
if "403" in str(err):
msg = "[ANALYST NOTES] Your API token does not have permission to pull Detection Rules"
Expand Down Expand Up @@ -123,7 +127,7 @@ def get_attachment(self, doc_id: str) -> str:

res = self.session.post(DETECTION_SEARCH, json=query)
res.raise_for_status()
return res.json()["result"][0]
return res.json()["result"][0] if len(res.json()["result"]) > 0 else None

def get_fusion_file(self, path: str) -> str:
"""Gets a fusion file provided a path
Expand Down
21 changes: 19 additions & 2 deletions external-import/recorded-future/src/rflib/rf_to_stix2.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@

import ipaddress
import json
from collections import OrderedDict
from datetime import datetime

import pycti # type: ignore
import stix2
from stix2 import Report
from stix2.properties import ListProperty, ReferenceProperty

TLP_MAP = {
"white": stix2.TLP_WHITE,
Expand Down Expand Up @@ -898,6 +901,16 @@ def create_stix_objects(self):
]


class RFReport(Report):
"""Subclass of Report with 'object_refs' property set to required=False."""

_properties = OrderedDict(Report._properties) # Copy the parent class properties
_properties["object_refs"] = ListProperty(
ReferenceProperty(valid_types=["SCO", "SDO", "SRO"], spec_version="2.1"),
required=False,
)


class StixNote:
"""Represents Analyst Note"""

Expand Down Expand Up @@ -1105,15 +1118,19 @@ def _create_report_types(self, topics):

def to_stix_objects(self):
"""Returns a list of STIX objects"""
report = stix2.Report(
report_object_refs = [obj.id for obj in self.objects]

# Report in STIX lib must have at least one object_refs even if there is no object_refs
# Use a subclass of Report to make the object_refs optional
report = RFReport(
id=pycti.Report.generate_id(self.name, self.published),
name=self.name,
description=self.text,
published=self.published,
created_by_ref=self.author.id,
labels=self.labels,
report_types=self.report_types,
object_refs=[obj.id for obj in self.objects],
object_refs=report_object_refs,
external_references=self.external_references,
object_marking_refs=self.tlp,
)
Expand Down

0 comments on commit 9e007e5

Please sign in to comment.