Skip to content

Commit a849e34

Browse files
committed
experimenting with updating
the drilldowns and generating defaults
1 parent 20e8840 commit a849e34

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

contentctl/objects/abstract_security_content_objects/detection_abstract.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -571,7 +571,7 @@ def model_post_init(self, __context: Any) -> None:
571571
for drilldown in self.drilldown_searches:
572572
drilldown.perform_search_substitutions(self)
573573
print("adding default drilldown?")
574-
self.drilldown_searches.append(Drilldown.constructDrilldownFromDetection(self))
574+
self.drilldown_searches.extend(Drilldown.constructDrilldownsFromDetection(self))
575575

576576
@field_validator('lookups', mode="before")
577577
@classmethod

contentctl/objects/drilldown.py

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,43 @@
55
from contentctl.objects.detection import Detection
66
from contentctl.objects.enums import AnalyticsType
77
SEARCH_PLACEHOLDER = "%original_detection_search%"
8+
EARLIEST_OFFSET = "$info_min_time$"
9+
LATEST_OFFSET = "$info_max_time$"
10+
RISK_SEARCH = "index = risk | stats count values(search_name) values(risk_message) values(analyticstories) values(annotations._all) values(annotations.mitre_attack.mitre_tactic) by risk_object"
811

912
class Drilldown(BaseModel):
1013
name: str = Field(..., description="The name of the drilldown search", min_length=5)
1114
search: str = Field(..., description="The text of a drilldown search. This must be valid SPL.", min_length=1)
1215
earliest_offset:str = Field(...,
1316
description="Earliest offset time for the drilldown search. "
14-
"The most common value for this field is '$info_min_time$', "
17+
f"The most common value for this field is '{EARLIEST_OFFSET}', "
1518
"but it is NOT the default value and must be supplied explicitly.",
1619
min_length= 1)
1720
latest_offset:str = Field(...,
1821
description="Latest offset time for the driolldown search. "
19-
"The most common value for this field is '$info_max_time$', "
22+
f"The most common value for this field is '{LATEST_OFFSET}', "
2023
"but it is NOT the default value and must be supplied explicitly.",
2124
min_length= 1)
2225

2326
@classmethod
24-
def constructDrilldownFromDetection(cls, detection: Detection) -> Drilldown:
27+
def constructDrilldownsFromDetection(cls, detection: Detection) -> list[Drilldown]:
2528
if len([f"${o.name}$" for o in detection.tags.observable if o.role[0] == "Victim"]) == 0 and detection.type != AnalyticsType.Hunting:
2629
print("no victim!")
2730
# print(detection.tags.observable)
2831
# print(detection.file_path)
29-
name_field = "View the detection results for " + ' and ' + ''.join([f"${o.name}$" for o in detection.tags.observable if o.type[0] == "Victim"])
30-
search_field = f"{detection.search} | search " + ' '.join([f"o.name = ${o.name}$" for o in detection.tags.observable])
31-
return cls(name=name_field, search=search_field)
32+
33+
variableNamesString = ' and'.join([f"${o.name}$" for o in detection.tags.observable if o.type[0] == "Victim"])
34+
nameField = "View the detection results for }" + variableNamesString
35+
appendedSearch = " | search " + ' '.join([f"o.name = ${o.name}$" for o in detection.tags.observable])
36+
search_field = f"{detection.search}{appendedSearch}"
37+
detection_results = cls(name=nameField, earliest_offset=EARLIEST_OFFSET, latest_offset=LATEST_OFFSET, search=search_field)
38+
39+
40+
nameField = f"View risk events for the last 7 days for {variableNamesString}"
41+
search_field = f"{RISK_SEARCH}{appendedSearch}"
42+
risk_events_last_7_days = cls(name=nameField, earliest_offset=EARLIEST_OFFSET, latest_offset=LATEST_OFFSET, search=search_field)
43+
44+
return [detection_results,risk_events_last_7_days]
3245

3346

3447
def perform_search_substitutions(self, detection:Detection)->None:

0 commit comments

Comments
 (0)