Skip to content

Commit 7bd8d38

Browse files
authored
Merge pull request #22 from UncoderIO/improve-rule-description-generating
improve rule description
2 parents 81d771a + 2d521fc commit 7bd8d38

File tree

7 files changed

+84
-37
lines changed

7 files changed

+84
-37
lines changed

siem-converter/app/converter/platforms/elasticsearch/renders/elast_alert.py

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
from app.converter.core.mapping import SourceMapping
2424
from app.converter.core.models.platform_details import PlatformDetails
2525
from app.converter.core.models.parser_output import MetaInfoContainer
26-
from app.converter.tools.utils import get_author_str, concatenate_str, get_mitre_attack_str, get_licence_str
26+
from app.converter.tools.utils import get_rule_description_str
2727

2828

2929
SEVERITIES_MAP = {"informational": "5", "low": "4", "medium": "3", "high": "2", "critical": "1"}
@@ -48,11 +48,14 @@ def finalize_query(self, prefix: str, query: str, functions: str, meta_info: Met
4848
source_mapping: SourceMapping = None, not_supported_functions: list = None):
4949
query = super().finalize_query(prefix=prefix, query=query, functions=functions, meta_info=meta_info)
5050
rule = ELASTICSEARCH_ALERT.replace("<query_placeholder>", query)
51-
description = concatenate_str(meta_info.description, get_author_str(meta_info.author))
52-
description = concatenate_str(description, get_licence_str(meta_info.license))
53-
description = concatenate_str(description, get_mitre_attack_str(meta_info.mitre_attack))
54-
55-
rule = rule.replace("<description_place_holder>", description)
51+
rule = rule.replace(
52+
"<description_place_holder>",
53+
get_rule_description_str(
54+
description=meta_info.description,
55+
license=meta_info.license,
56+
mitre_attack=meta_info.mitre_attack
57+
)
58+
)
5659
rule = rule.replace("<title_place_holder>", meta_info.title)
5760
rule = rule.replace("<priority_place_holder>", SEVERITIES_MAP[meta_info.severity])
5861
if not_supported_functions:

siem-converter/app/converter/platforms/elasticsearch/renders/kibana.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,7 @@
2626
from app.converter.core.mapping import SourceMapping
2727
from app.converter.core.models.platform_details import PlatformDetails
2828
from app.converter.core.models.parser_output import MetaInfoContainer
29-
from app.converter.tools.utils import concatenate_str, get_author_str, get_licence_str, get_mitre_attack_str, \
30-
get_rule_id_str, get_references_str
29+
from app.converter.tools.utils import get_rule_description_str
3130

3231

3332
class KibanaFieldValue(ElasticSearchFieldValue):
@@ -49,12 +48,14 @@ def finalize_query(self, prefix: str, query: str, functions: str, meta_info: Met
4948
rule = copy.deepcopy(KIBANA_RULE)
5049
rule["_source"]["kibanaSavedObjectMeta"]["searchSourceJSON"] = dumped_rule
5150
rule["_source"]["title"] = meta_info.title
52-
description = meta_info.description or rule["_source"]["description"]
53-
description = concatenate_str(description, get_author_str(meta_info.author))
54-
description = concatenate_str(description, get_rule_id_str(meta_info.id))
55-
description = concatenate_str(description, get_licence_str(meta_info.license))
56-
description = concatenate_str(description, get_references_str(meta_info.references))
57-
rule["_source"]["description"] = concatenate_str(description, get_mitre_attack_str(meta_info.mitre_attack))
51+
rule["_source"]["description"] = get_rule_description_str(
52+
description=meta_info.description or rule["_source"]["description"],
53+
author=meta_info.author,
54+
rule_id=meta_info.id,
55+
license=meta_info.license,
56+
references=meta_info.references,
57+
mitre_attack=meta_info.mitre_attack
58+
)
5859
rule_str = json.dumps(rule, indent=4, sort_keys=False)
5960
if not_supported_functions:
6061
rendered_not_supported = self.render_not_supported_functions(not_supported_functions)

siem-converter/app/converter/platforms/elasticsearch/renders/xpack_watcher.py

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
from app.converter.core.mapping import SourceMapping
2727
from app.converter.core.models.platform_details import PlatformDetails
2828
from app.converter.core.models.parser_output import MetaInfoContainer
29-
from app.converter.tools.utils import concatenate_str, get_author_str, get_licence_str, get_mitre_attack_str
29+
from app.converter.tools.utils import get_rule_description_str
3030

3131

3232
class XpackWatcherRuleFieldValue(ElasticSearchFieldValue):
@@ -43,13 +43,15 @@ def finalize_query(self, prefix: str, query: str, functions: str, meta_info: Met
4343
source_mapping: SourceMapping = None, not_supported_functions: list = None):
4444
query = super().finalize_query(prefix=prefix, query=query, functions=functions, meta_info=meta_info)
4545
rule = copy.deepcopy(XPACK_WATCHER_RULE)
46-
description = concatenate_str(meta_info.description, get_author_str(meta_info.author))
47-
description = concatenate_str(description, get_licence_str(meta_info.license))
48-
description = concatenate_str(description, get_mitre_attack_str(meta_info.mitre_attack))
4946
rule["metadata"].update({
5047
"query": query,
5148
"title": meta_info.title,
52-
"description": description,
49+
"description": get_rule_description_str(
50+
description=meta_info.description,
51+
author=meta_info.author,
52+
license=meta_info.license,
53+
mitre_attack=meta_info.mitre_attack
54+
),
5355
"tags": meta_info.mitre_attack
5456
})
5557
rule["input"]["search"]["request"]["body"]["query"]["bool"]["must"][0]["query_string"]["query"] = query

siem-converter/app/converter/platforms/logscale/renders/logscale_alert.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
from app.converter.core.mapping import SourceMapping
2626
from app.converter.core.models.platform_details import PlatformDetails
2727
from app.converter.core.models.parser_output import MetaInfoContainer
28+
from app.converter.tools.utils import get_rule_description_str
2829

2930

3031
_AUTOGENERATED_TITLE = "Autogenerated Falcon LogScale Alert"
@@ -44,10 +45,12 @@ def finalize_query(self, prefix: str, query: str, functions: str, meta_info: Met
4445
rule = copy.deepcopy(DEFAULT_LOGSCALE_ALERT)
4546
rule['query']['queryString'] = query
4647
rule['name'] = meta_info.title or _AUTOGENERATED_TITLE
47-
description = f"{meta_info.description}. Author: {meta_info.author}. License: {meta_info.license}."
48-
if meta_info.mitre_attack:
49-
description += f" MITRE ATT&CK: {', '.join(meta_info.mitre_attack)}"
50-
rule['description'] = description
48+
rule['description'] = get_rule_description_str(
49+
description=meta_info.description,
50+
license=meta_info.license,
51+
mitre_attack=meta_info.mitre_attack,
52+
author=meta_info.author
53+
)
5154

5255
json_query = json.dumps(rule, indent=4, sort_keys=False)
5356
if not_supported_functions:

siem-converter/app/converter/platforms/microsoft/renders/microsoft_sentinel_rule.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
from app.converter.core.mapping import SourceMapping
2929
from app.converter.core.models.platform_details import PlatformDetails
3030
from app.converter.core.models.parser_output import MetaInfoContainer
31-
from app.converter.tools.utils import concatenate_str, get_author_str, get_licence_str
31+
from app.converter.tools.utils import get_rule_description_str
3232

3333

3434
class MicrosoftSentinelRuleFieldValue(MicrosoftSentinelFieldValue):
@@ -46,10 +46,11 @@ def finalize_query(self, prefix: str, query: str, functions: str, meta_info: Met
4646
rule = copy.deepcopy(DEFAULT_MICROSOFT_SENTINEL_RULE)
4747
rule["query"] = query
4848
rule["displayName"] = meta_info.title
49-
description = meta_info.description or rule["description"]
50-
description = concatenate_str(description, get_author_str(meta_info.author))
51-
description = concatenate_str(description, get_licence_str(meta_info.license))
52-
rule["description"] = description
49+
rule["description"] = get_rule_description_str(
50+
description=meta_info.description or rule["description"],
51+
author=meta_info.author,
52+
license=meta_info.license
53+
)
5354
rule["severity"] = meta_info.severity
5455
rule["techniques"] = [el.upper() for el in meta_info.mitre_attack]
5556
json_rule = json.dumps(rule, indent=4, sort_keys=False)

siem-converter/app/converter/platforms/splunk/renders/splunk_alert.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from app.converter.core.mapping import SourceMapping
2323
from app.converter.core.models.platform_details import PlatformDetails
2424
from app.converter.core.models.parser_output import MetaInfoContainer
25+
from app.converter.tools.utils import get_rule_description_str
2526

2627

2728
_AUTOGENERATED_TITLE = "Autogenerated Splunk Alert"
@@ -43,11 +44,13 @@ def finalize_query(self, prefix: str, query: str, functions: str, meta_info: Met
4344
rule = DEFAULT_SPLUNK_ALERT.replace("<query_place_holder>", query)
4445
rule = rule.replace("<title_place_holder>", meta_info.title or _AUTOGENERATED_TITLE)
4546
rule = rule.replace("<severity_place_holder>", severity_map.get(meta_info.severity, "1"))
47+
rule_description = get_rule_description_str(
48+
description=meta_info.description or 'Autogenerated Splunk Alert.',
49+
license=meta_info.license,
50+
mitre_attack=meta_info.mitre_attack
51+
)
52+
rule = rule.replace("<description_place_holder>", rule_description)
4653

47-
description = f"{meta_info.description or 'Autogenerated Splunk Alert'}. License: {meta_info.license}."
48-
if meta_info.mitre_attack:
49-
description += f" MITRE ATT&CK: {', '.join(meta_info.mitre_attack)}"
50-
rule = rule.replace("<description_place_holder>", description)
5154
if not_supported_functions:
5255
rendered_not_supported = self.render_not_supported_functions(not_supported_functions)
5356
return rule + rendered_not_supported

siem-converter/app/converter/tools/utils.py

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,20 +14,54 @@ def concatenate_str(str1: str, str2: str) -> str:
1414

1515

1616
def get_mitre_attack_str(mitre_attack: List[str]) -> str:
17-
return f"MITRE ATT&CK: {', '.join(mitre_attack).upper()}." if mitre_attack else ""
17+
return f"MITRE ATT&CK: {', '.join(mitre_attack).upper()}."
1818

1919

2020
def get_author_str(author: str) -> str:
21-
return f"Author: {author}." if author else ""
21+
return f"Author: {author}."
2222

2323

24-
def get_licence_str(licence: str) -> str:
25-
return f"Licence: {licence}."
24+
def get_license_str(license: str) -> str:
25+
license_str = f"License: {license}"
26+
if not license_str.endswith('.'):
27+
license_str += '.'
28+
return license_str
2629

30+
def get_description_str(description: str) -> str:
31+
if not description.endswith('.'):
32+
description += '.'
33+
return description
2734

2835
def get_rule_id_str(rule_id: str) -> str:
2936
return f"Rule ID: {rule_id}."
3037

3138

3239
def get_references_str(references: List[str]) -> str:
33-
return f"References: {', '.join(references)}." if references else ""
40+
return f"References: {', '.join(references)}."
41+
42+
def get_rule_description_str(
43+
description: str,
44+
author: str = None,
45+
rule_id: str = None,
46+
license: str = None,
47+
mitre_attack: str = None,
48+
references: str = None
49+
) -> str:
50+
description_str = get_description_str(description)
51+
author_str = get_author_str(author) if author else None
52+
rule_id = get_rule_id_str(rule_id) if rule_id else None
53+
license_str = get_license_str(license) if license else None
54+
mitre_attack = get_mitre_attack_str(mitre_attack) if mitre_attack else None
55+
references = get_references_str(references) if references else None
56+
rule_description = description_str
57+
if author_str:
58+
rule_description = concatenate_str(rule_description, author_str)
59+
if rule_id:
60+
rule_description = concatenate_str(rule_description, rule_id)
61+
if license_str:
62+
rule_description = concatenate_str(rule_description, license_str)
63+
if mitre_attack:
64+
rule_description = concatenate_str(rule_description, mitre_attack)
65+
if references:
66+
rule_description = concatenate_str(rule_description, references)
67+
return rule_description

0 commit comments

Comments
 (0)