Skip to content

Commit 9e0c582

Browse files
authored
Merge branch 'main' into gis-add-anomali-mappings1612
2 parents 044119e + 8c4e32a commit 9e0c582

File tree

83 files changed

+1590
-83
lines changed

Some content is hidden

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

83 files changed

+1590
-83
lines changed

uncoder-core/app/translator/core/mapping.py

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,12 @@ class LogSourceSignature(ABC):
2222
def is_suitable(self, **kwargs) -> bool:
2323
raise NotImplementedError("Abstract method")
2424

25+
def is_probably_suitable(self, **kwargs) -> bool:
26+
"""
27+
Performs check with more options, but the result is less accurate than the "is_suitable" method
28+
"""
29+
raise NotImplementedError("Abstract method")
30+
2531
@staticmethod
2632
def _check_conditions(conditions: list[Union[bool, None]]) -> bool:
2733
conditions = [condition for condition in conditions if condition is not None]
@@ -88,11 +94,13 @@ def __init__(
8894
log_source_signature: _LogSourceSignatureType = None,
8995
fields_mapping: Optional[FieldsMapping] = None,
9096
raw_log_fields: Optional[dict] = None,
97+
conditions: Optional[dict] = None,
9198
):
9299
self.source_id = source_id
93100
self.log_source_signature = log_source_signature
94101
self.fields_mapping = fields_mapping or FieldsMapping([])
95102
self.raw_log_fields = raw_log_fields
103+
self.conditions = conditions
96104

97105

98106
class BasePlatformMappings:
@@ -123,6 +131,7 @@ def prepare_mapping(self) -> dict[str, SourceMapping]:
123131

124132
field_mappings_dict = mapping_dict.get("field_mapping", {})
125133
raw_log_fields = mapping_dict.get("raw_log_fields", {})
134+
conditions = mapping_dict.get("conditions", {})
126135
field_mappings_dict.update({field: field for field in raw_log_fields})
127136
fields_mapping = self.prepare_fields_mapping(field_mapping=field_mappings_dict)
128137
self.update_default_source_mapping(default_mapping=default_mapping, fields_mapping=fields_mapping)
@@ -131,6 +140,7 @@ def prepare_mapping(self) -> dict[str, SourceMapping]:
131140
log_source_signature=log_source_signature,
132141
fields_mapping=fields_mapping,
133142
raw_log_fields=raw_log_fields,
143+
conditions=conditions,
134144
)
135145

136146
if self.skip_load_default_mappings:
@@ -170,19 +180,26 @@ def get_source_mappings_by_fields_and_log_sources(
170180

171181
return by_log_sources_and_fields or by_fields or [self._source_mappings[DEFAULT_MAPPING_NAME]]
172182

173-
def get_source_mappings_by_ids(self, source_mapping_ids: list[str]) -> list[SourceMapping]:
183+
def get_source_mapping(self, source_id: str) -> Optional[SourceMapping]:
184+
return self._source_mappings.get(source_id)
185+
186+
def get_source_mappings_by_ids(
187+
self, source_mapping_ids: list[str], return_default: bool = True
188+
) -> list[SourceMapping]:
174189
source_mappings = []
175190
for source_mapping_id in source_mapping_ids:
191+
if source_mapping_id == DEFAULT_MAPPING_NAME:
192+
continue
176193
if source_mapping := self.get_source_mapping(source_mapping_id):
177194
source_mappings.append(source_mapping)
178195

179-
if not source_mappings:
196+
if not source_mappings and return_default:
180197
source_mappings = [self.get_source_mapping(DEFAULT_MAPPING_NAME)]
181198

182199
return source_mappings
183200

184-
def get_source_mapping(self, source_id: str) -> Optional[SourceMapping]:
185-
return self._source_mappings.get(source_id)
201+
def get_source_mappings_by_log_sources(self, log_sources: dict) -> Optional[list[str]]:
202+
raise NotImplementedError("Abstract method")
186203

187204
@property
188205
def default_mapping(self) -> SourceMapping:

uncoder-core/app/translator/core/mixins/rule.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def parse_mitre_attack(self, tags: list[str]) -> MitreInfoContainer:
4242
tag = tag.lower()
4343
if tag.startswith("attack."):
4444
tag = tag[7::]
45-
if tag.startswith("t"):
45+
if tag[-1].isdigit():
4646
parsed_techniques.append(tag)
4747
else:
4848
parsed_tactics.append(tag)
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from typing import Union
2+
3+
from app.translator.core.const import QUERY_TOKEN_TYPE
4+
from app.translator.core.custom_types.tokens import LogicalOperatorType, OperatorType
5+
from app.translator.core.mapping import SourceMapping
6+
from app.translator.core.models.query_tokens.field_value import FieldValue
7+
from app.translator.core.models.query_tokens.identifier import Identifier
8+
9+
10+
class ExtraConditionMixin:
11+
def generate_extra_conditions(self, source_mapping: SourceMapping) -> list[QUERY_TOKEN_TYPE]:
12+
extra_tokens = []
13+
for field, value in source_mapping.conditions.items():
14+
extra_tokens.extend(
15+
[
16+
FieldValue(source_name=field, operator=Identifier(token_type=OperatorType.EQ), value=value),
17+
Identifier(token_type=LogicalOperatorType.AND),
18+
]
19+
)
20+
return extra_tokens

uncoder-core/app/translator/core/models/query_container.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def __init__(
7878
parsed_logsources: Optional[dict] = None,
7979
timeframe: Optional[timedelta] = None,
8080
query_period: Optional[timedelta] = None,
81-
mitre_attack: MitreInfoContainer = MitreInfoContainer(),
81+
mitre_attack: Optional[MitreInfoContainer] = None,
8282
raw_metainfo_container: Optional[RawMetaInfoContainer] = None,
8383
) -> None:
8484
self.id = id_ or str(uuid.uuid4())
@@ -88,7 +88,7 @@ def __init__(
8888
self.risk_score = risk_score
8989
self.type_ = type_ or ""
9090
self.description = description or ""
91-
self.author = [v.strip() for v in author] if author else []
91+
self.author = [v.strip() for v in author] if author and author != [None] else []
9292
self.date = date or datetime.now().date().strftime("%Y-%m-%d")
9393
self.output_table_fields = output_table_fields or []
9494
self.query_fields = query_fields or []
@@ -98,15 +98,15 @@ def __init__(
9898
self.severity = severity or SeverityType.low
9999
self.references = references or []
100100
self.tags = tags or []
101-
self.mitre_attack = mitre_attack or None
101+
self.mitre_attack = mitre_attack or MitreInfoContainer()
102102
self.raw_mitre_attack = raw_mitre_attack or []
103103
self.status = status or "stable"
104104
self.false_positives = false_positives or []
105105
self._source_mapping_ids = source_mapping_ids or [DEFAULT_MAPPING_NAME]
106106
self.parsed_logsources = parsed_logsources or {}
107107
self.timeframe = timeframe
108108
self.query_period = query_period
109-
self.raw_metainfo_container = raw_metainfo_container
109+
self.raw_metainfo_container = raw_metainfo_container or RawMetaInfoContainer()
110110

111111
@property
112112
def author_str(self) -> str:

uncoder-core/app/translator/core/render.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,9 @@ def process_raw_log_field_prefix(self, field: str, source_mapping: SourceMapping
403403
if raw_log_field_type := source_mapping.raw_log_fields.get(field):
404404
return [self.process_raw_log_field(field=field, field_type=raw_log_field_type)]
405405

406+
def generate_extra_conditions(self, source_mapping: SourceMapping) -> list[QUERY_TOKEN_TYPE]: # noqa: ARG002
407+
return []
408+
406409
def generate_raw_log_fields(self, fields: list[Field], source_mapping: SourceMapping) -> str:
407410
if not self.raw_log_field_patterns_map:
408411
return ""
@@ -442,6 +445,9 @@ def _generate_from_tokenized_query_container_by_source_mapping(
442445
source_mapping=source_mapping,
443446
)
444447
prefix += f"\n{defined_raw_log_fields}"
448+
if source_mapping.conditions:
449+
extra_tokens = self.generate_extra_conditions(source_mapping=source_mapping)
450+
query_container.tokens = [*extra_tokens, *query_container.tokens]
445451
query = self.generate_query(tokens=query_container.tokens, source_mapping=source_mapping)
446452
not_supported_functions = query_container.functions.not_supported + rendered_functions.not_supported
447453
return self.finalize_query(

uncoder-core/app/translator/mappings/platforms/anomali/common.yml renamed to uncoder-core/app/translator/mappings/platforms/anomali/proxy.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,19 @@
11
platform: Anomali
2-
description: Common field mapping
2+
source: proxy
33

44
field_mapping:
55
c-uri-query: url
66
c-useragent: user_agent
7+
c-uri: url
8+
cs-method: http_method
9+
cs-bytes: bytes_out
10+
cs-referrer: http_referrer
11+
sc-status: return_code
12+
13+
dns-query: query
14+
dns-answer: answer
15+
dns-record: record_type
16+
717
CommandLine: command_line
818
DestinationHostname: dest
919
DestinationIp: dest_ip
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
platform: Anomali
2+
source: webserver
3+
4+
field_mapping:
5+
c-uri-query: url
6+
c-useragent: user_agent
7+
c-uri: url
8+
cs-method: http_method
9+
cs-bytes: bytes_out
10+
cs-referrer: http_referrer
11+
sc-status: return_code
12+
13+
dns-query: query
14+
dns-answer: answer
15+
dns-record: record_type
16+
17+
CommandLine: command_line
18+
DestinationHostname: dest
19+
DestinationIp: dest_ip
20+
DestinationPort: dest_port
21+
Details: reg_value_data
22+
dst_ip: dest_ip
23+
dst_port: dest_port
24+
EventID: event_id
25+
EventName: event_name
26+
FileName: file_name
27+
FilePath: file_path
28+
Image: image
29+
NewProcessName: image
30+
OriginalFileName: original_file_name
31+
ParentCommandLine: parent_command_line
32+
ParentImage: parent_image
33+
ParentProcessID: parent_process_id
34+
Platform: platform
35+
ProcessCommandLine: command_line
36+
ProcessID: process_id
37+
SourceImage: parent_image
38+
SourcePort: src_port
39+
TargetFilename: file_name
40+
TargetObject: reg_key
41+
UserAgent: user_agent
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
platform: ArcSight
2+
source: default
3+
4+
5+
default_log_source: {}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
platform: ArcSight
2+
source: linux_network_connection
3+
4+
5+
default_log_source: {}
6+
7+
8+
field_mapping:
9+
SourceHostname: sourceHostName
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
platform: ArcSight
2+
source: macos_network_connection
3+
4+
5+
default_log_source: {}
6+
7+
8+
field_mapping:
9+
SourceHostname: sourceHostName

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