Skip to content

Commit b63c0ab

Browse files
committed
gis-7683 automate parser/render collection
1 parent 19bf966 commit b63c0ab

File tree

68 files changed

+233
-122
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

68 files changed

+233
-122
lines changed

uncoder-core/app/translator/cti_translator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111

1212
class CTITranslator:
13-
renders: RenderCTIManager = render_cti_manager
13+
render_manager: RenderCTIManager = render_cti_manager
1414

1515
def __init__(self):
1616
self.logger = logging.getLogger("cti_translator")
@@ -38,7 +38,7 @@ def __parse_iocs_from_string(
3838

3939
@handle_translation_exceptions
4040
def __render_translation(self, parsed_data: dict, platform_data: CTIPlatform, iocs_per_query: int) -> list[str]:
41-
render_cti = self.renders.get(platform_data.id)
41+
render_cti = self.render_manager.get(platform_data.id)
4242

4343
chunked_iocs = self.__get_iocs_chunk(
4444
chunks_size=iocs_per_query, data=parsed_data, mapping=render_cti.default_mapping
@@ -85,4 +85,4 @@ def __get_iocs_chunk(
8585

8686
@classmethod
8787
def get_renders(cls) -> list:
88-
return cls.renders.get_platforms_details
88+
return cls.render_manager.get_platforms_details

uncoder-core/app/translator/managers.py

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,26 @@
11
from abc import ABC
2+
from functools import cached_property
23

34
from app.models.translation import TranslatorPlatform
45
from app.translator.core.exceptions.core import UnsupportedRootAParser
5-
from app.translator.platforms import __ALL_PARSERS as PARSERS
6-
from app.translator.platforms import __ALL_RENDERS as RENDERS
7-
from app.translator.platforms import __ALL_RENDERS_CTI as RENDERS_CTI
86

97

108
class Manager(ABC):
11-
platforms_class = ()
9+
platforms = {}
1210

13-
@property
14-
def platforms(self) -> dict:
15-
return {platform.details.platform_id: platform for platform in self.platforms_class}
11+
def register(self, cls):
12+
self.platforms[cls.details.platform_id] = cls()
13+
return cls
1614

1715
def get(self, platform_id: str): # noqa: ANN201
1816
if platform := self.platforms.get(platform_id):
1917
return platform
2018
raise UnsupportedRootAParser(parser=platform_id)
2119

2220
def all_platforms(self) -> list:
23-
return list(self.platforms)
21+
return list(self.platforms.keys())
2422

25-
@property
23+
@cached_property
2624
def get_platforms_details(self) -> list[TranslatorPlatform]:
2725
platforms = [
2826
TranslatorPlatform(
@@ -37,21 +35,55 @@ def get_platforms_details(self) -> list[TranslatorPlatform]:
3735
alt_platform=platform.details.alt_platform,
3836
first_choice=platform.details.first_choice,
3937
)
40-
for platform in self.platforms_class
38+
for platform in self.platforms.values()
4139
]
4240
return sorted(platforms, key=lambda platform: platform.group_name)
4341

4442

45-
class RenderManager(Manager):
46-
platforms_class = RENDERS
43+
class ParserManager(Manager):
44+
platforms = {}
45+
roota_parsers = {}
46+
parsers = {}
4747

48+
def get_roota_parser(self, platform_id: str): # noqa: ANN201
49+
if platform := self.roota_parsers.get(platform_id):
50+
return platform
51+
raise UnsupportedRootAParser(parser=platform_id)
4852

49-
class ParserManager(Manager):
50-
platforms_class = PARSERS
53+
def register_roota_parser(self, cls):
54+
self.roota_parsers[cls.details.platform_id] = cls()
55+
return super().register(cls)
56+
57+
def register_parser(self, cls):
58+
self.parsers[cls.details.platform_id] = cls()
59+
return super().register(cls)
60+
61+
@cached_property
62+
def get_platforms_details(self) -> list[TranslatorPlatform]:
63+
platforms = [
64+
TranslatorPlatform(
65+
id=platform.details.platform_id,
66+
name=platform.details.name,
67+
code=platform.details.platform_id,
68+
group_name=platform.details.group_name,
69+
group_id=platform.details.group_id,
70+
platform_name=platform.details.platform_name,
71+
platform_id=platform.details.platform_id,
72+
alt_platform_name=platform.details.alt_platform_name,
73+
alt_platform=platform.details.alt_platform,
74+
first_choice=platform.details.first_choice,
75+
)
76+
for platform in self.parsers.values()
77+
]
78+
return sorted(platforms, key=lambda platform: platform.group_name)
79+
80+
81+
class RenderManager(Manager):
82+
platforms = {}
5183

5284

5385
class RenderCTIManager(Manager):
54-
platforms_class = RENDERS_CTI
86+
platforms = {}
5587

5688

5789
parser_manager = ParserManager()
Lines changed: 1 addition & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from app.translator.platforms.arcsight.renders.arcsight_cti import ArcsightKeyword
12
from app.translator.platforms.athena.parsers.athena import AthenaQueryParser
23
from app.translator.platforms.athena.renders.athena import AthenaQueryRender
34
from app.translator.platforms.athena.renders.athena_cti import AthenaCTI
@@ -59,74 +60,3 @@
5960
from app.translator.platforms.splunk.renders.splunk_alert import SplunkAlertRender
6061
from app.translator.platforms.splunk.renders.splunk_cti import SplunkCTI
6162
from app.translator.platforms.sumo_logic.renders.sumologic_cti import SumologicCTI
62-
63-
__ALL_RENDERS = (
64-
SigmaRender(),
65-
MicrosoftSentinelQueryRender(),
66-
MicrosoftSentinelRuleRender(),
67-
MicrosoftDefenderQueryRender(),
68-
QradarQueryRender(),
69-
CrowdStrikeQueryRender(),
70-
SplunkQueryRender(),
71-
SplunkAlertRender(),
72-
ChronicleQueryRender(),
73-
ChronicleSecurityRuleRender(),
74-
AthenaQueryRender(),
75-
ElasticSearchQueryRender(),
76-
LogRhythmAxonQueryRender(),
77-
LogRhythmAxonRuleRender(),
78-
LogScaleQueryRender(),
79-
LogScaleAlertRender(),
80-
ElasticSearchRuleRender(),
81-
ElastAlertRuleRender(),
82-
KibanaRuleRender(),
83-
XPackWatcherRuleRender(),
84-
OpenSearchQueryRender(),
85-
OpenSearchRuleRender(),
86-
GraylogQueryRender(),
87-
FortiSiemRuleRender(),
88-
)
89-
90-
__ALL_PARSERS = (
91-
AthenaQueryParser(),
92-
ChronicleQueryParser(),
93-
ChronicleRuleParser(),
94-
SplunkQueryParser(),
95-
SplunkAlertParser(),
96-
SigmaParser(),
97-
QradarQueryParser(),
98-
MicrosoftSentinelQueryParser(),
99-
MicrosoftSentinelRuleParser(),
100-
MicrosoftDefenderQueryParser(),
101-
CrowdStrikeQueryParser(),
102-
LogScaleQueryParser(),
103-
LogScaleAlertParser(),
104-
ElasticSearchQueryParser(),
105-
ElasticSearchRuleParser(),
106-
OpenSearchQueryParser(),
107-
GraylogQueryParser(),
108-
)
109-
110-
111-
__ALL_RENDERS_CTI = (
112-
MicrosoftSentinelCTI(),
113-
MicrosoftDefenderCTI(),
114-
QRadarCTI(),
115-
SplunkCTI(),
116-
ChronicleQueryCTI(),
117-
CrowdStrikeCTI(),
118-
SumologicCTI(),
119-
ElasticsearchCTI(),
120-
LogScaleCTI(),
121-
OpenSearchCTI(),
122-
FireeyeHelixCTI(),
123-
CarbonBlackCTI(),
124-
GraylogCTI(),
125-
LogpointCTI(),
126-
QualysCTI(),
127-
RSANetwitnessCTI(),
128-
S1EventsCTI(),
129-
SecuronixCTI(),
130-
SnowflakeCTI(),
131-
AthenaCTI(),
132-
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from app.translator.core.models.platform_details import PlatformDetails
2+
from app.translator.core.render_cti import RenderCTI
3+
from app.translator.managers import render_cti_manager
4+
from app.translator.platforms.arcsight.const import ARCSIGHT_QUERY_DETAILS
5+
from app.translator.platforms.arcsight.mappings.arcsight_cti import DEFAULT_ARCSIGHT_MAPPING
6+
7+
8+
@render_cti_manager.register
9+
class ArcsightKeyword(RenderCTI):
10+
details: PlatformDetails = PlatformDetails(**ARCSIGHT_QUERY_DETAILS)
11+
12+
default_mapping = DEFAULT_ARCSIGHT_MAPPING
13+
field_value_template: str = "{key} = {value}"
14+
or_operator: str = " OR "
15+
group_or_operator: str = " OR "
16+
or_group: str = "{or_group}"
17+
result_join: str = ""
18+
final_result_for_many: str = '({result}) AND type != 2 | rex field = flexString1 mode=sed "s//Sigma: None/g"\n'
19+
final_result_for_one: str = '{result} AND type != 2 | rex field = flexString1 mode=sed "s//Sigma: None/g"\n'

uncoder-core/app/translator/platforms/athena/parsers/athena.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,13 @@
2222
from app.translator.core.models.platform_details import PlatformDetails
2323
from app.translator.core.models.query_container import RawQueryContainer, TokenizedQueryContainer
2424
from app.translator.core.parser import PlatformQueryParser
25+
from app.translator.managers import parser_manager
2526
from app.translator.platforms.athena.const import athena_details
2627
from app.translator.platforms.athena.mapping import AthenaMappings, athena_mappings
2728
from app.translator.platforms.athena.tokenizer import AthenaTokenizer
2829

2930

31+
@parser_manager.register_roota_parser
3032
class AthenaQueryParser(PlatformQueryParser):
3133
details: PlatformDetails = athena_details
3234
mappings: AthenaMappings = athena_mappings

uncoder-core/app/translator/platforms/athena/renders/athena.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
from app.translator.core.mapping import LogSourceSignature
2424
from app.translator.core.models.platform_details import PlatformDetails
2525
from app.translator.core.render import BaseQueryFieldValue, PlatformQueryRender
26+
from app.translator.managers import render_manager
2627
from app.translator.platforms.athena.const import athena_details
2728
from app.translator.platforms.athena.mapping import AthenaMappings, athena_mappings
2829

@@ -76,6 +77,7 @@ def keywords(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG00
7677
raise UnsupportedRenderMethod(platform_name=self.details.name, method="Keywords")
7778

7879

80+
@render_manager.register
7981
class AthenaQueryRender(PlatformQueryRender):
8082
details: PlatformDetails = athena_details
8183
mappings: AthenaMappings = athena_mappings

uncoder-core/app/translator/platforms/athena/renders/athena_cti.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
from app.translator.core.models.platform_details import PlatformDetails
2121
from app.translator.core.render_cti import RenderCTI
22+
from app.translator.managers import render_cti_manager
2223
from app.translator.platforms.athena.const import athena_details
2324
from app.translator.platforms.athena.mappings.athena_cti import DEFAULT_ATHENA_MAPPING
2425

2526

27+
@render_cti_manager.register
2628
class AthenaCTI(RenderCTI):
2729
details: PlatformDetails = athena_details
2830

uncoder-core/app/translator/platforms/carbonblack/renders/carbonblack_cti.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,12 @@
1919

2020
from app.translator.core.models.platform_details import PlatformDetails
2121
from app.translator.core.render_cti import RenderCTI
22+
from app.translator.managers import render_cti_manager
2223
from app.translator.platforms.carbonblack.const import CARBON_BLACK_QUERY_DETAILS
2324
from app.translator.platforms.carbonblack.mappings.carbonblack_cti import DEFAULT_CARBONBLACK_MAPPING
2425

2526

27+
@render_cti_manager.register
2628
class CarbonBlackCTI(RenderCTI):
2729
details: PlatformDetails = PlatformDetails(**CARBON_BLACK_QUERY_DETAILS)
2830

uncoder-core/app/translator/platforms/chronicle/parsers/chronicle.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
from app.translator.core.models.platform_details import PlatformDetails
2121
from app.translator.core.models.query_container import RawQueryContainer, TokenizedQueryContainer
2222
from app.translator.core.parser import PlatformQueryParser
23+
from app.translator.managers import parser_manager
2324
from app.translator.platforms.chronicle.const import chronicle_query_details
2425
from app.translator.platforms.chronicle.mapping import ChronicleMappings, chronicle_mappings
2526
from app.translator.platforms.chronicle.tokenizer import ChronicleQueryTokenizer
2627

2728

29+
@parser_manager.register_roota_parser
2830
class ChronicleQueryParser(PlatformQueryParser):
2931
mappings: ChronicleMappings = chronicle_mappings
3032
tokenizer: ChronicleQueryTokenizer = ChronicleQueryTokenizer()

uncoder-core/app/translator/platforms/chronicle/parsers/chronicle_rule.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,14 @@
2121
from app.translator.core.exceptions.parser import TokenizerGeneralException
2222
from app.translator.core.models.platform_details import PlatformDetails
2323
from app.translator.core.models.query_container import MetaInfoContainer, RawQueryContainer
24+
from app.translator.managers import parser_manager
2425
from app.translator.platforms.chronicle.const import chronicle_rule_details
2526
from app.translator.platforms.chronicle.mapping import ChronicleMappings, chronicle_mappings
2627
from app.translator.platforms.chronicle.parsers.chronicle import ChronicleQueryParser
2728
from app.translator.platforms.chronicle.tokenizer import ChronicleRuleTokenizer
2829

2930

31+
@parser_manager.register
3032
class ChronicleRuleParser(ChronicleQueryParser):
3133
details: PlatformDetails = chronicle_rule_details
3234
rule_name_pattern = "rule\s(?P<rule_name>[a-z0-9_]+)\s{"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy