Skip to content

Commit 50bb6e4

Browse files
author
oleksandr.volha
committed
Merge remote-tracking branch 'origin' into gis-8678
2 parents 504d089 + f766f38 commit 50bb6e4

File tree

16 files changed

+356
-111
lines changed

16 files changed

+356
-111
lines changed

uncoder-core/app/translator/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,4 @@
99

1010
CTI_IOCS_PER_QUERY_LIMIT = 25
1111

12-
DEFAULT_VALUE_TYPE = Union[int, str, StrValue, list[Union[int, str, StrValue]]]
12+
DEFAULT_VALUE_TYPE = Union[bool, int, str, StrValue, list[Union[int, str, StrValue]]]

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,25 @@ def has_spec_symbols(self) -> bool:
130130
return any(isinstance(el, BaseSpecSymbol) for el in self.split_value)
131131

132132

133+
RE_STR_SPEC_SYMBOLS_MAP = {
134+
"?": ReZeroOrOneQuantifier,
135+
"*": ReZeroOrMoreQuantifier,
136+
"+": ReOneOrMoreQuantifier,
137+
"^": ReCaretSymbol,
138+
"$": ReEndOfStrSymbol,
139+
".": ReAnySymbol,
140+
"[": ReLeftSquareBracket,
141+
"]": ReRightSquareBracket,
142+
"(": ReLeftParenthesis,
143+
")": ReRightParenthesis,
144+
"{": ReLeftCurlyBracket,
145+
"}": ReRightCurlyBracket,
146+
"|": ReOrOperator,
147+
",": ReCommaSymbol,
148+
"-": ReHyphenSymbol,
149+
}
150+
151+
133152
CONTAINER_SPEC_SYMBOLS_MAP = {
134153
SingleSymbolWildCard: "?",
135154
UnboundLenWildCard: "*",
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
platform: Anomali
2+
description: Common field mapping
3+
4+
field_mapping:
5+
c-uri-query: url
6+
c-useragent: user_agent
7+
CommandLine: command_line
8+
DestinationHostname: dest
9+
DestinationIp: dest_ip
10+
DestinationPort: dest_port
11+
Details: reg_value_data
12+
dst_ip: dest_ip
13+
dst_port: dest_port
14+
EventID: event_id
15+
EventName: event_name
16+
FileName: file_name
17+
FilePath: file_path
18+
Image: image
19+
NewProcessName: image
20+
OriginalFileName: original_file_name
21+
ParentCommandLine: parent_command_line
22+
ParentImage: parent_image
23+
ParentProcessID: parent_process_id
24+
Platform: platform
25+
ProcessCommandLine: command_line
26+
ProcessID: process_id
27+
SourceImage: parent_image
28+
SourcePort: src_port
29+
TargetFilename: file_name
30+
TargetObject: reg_key
31+
UserAgent: user_agent
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
platform: Anomali
2+
source: default
3+
4+
5+
default_log_source: {}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
from app.translator.platforms.anomali.renders.anomali import AnomaliQueryRender # noqa: F401
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
from app.translator.core.models.platform_details import PlatformDetails
2+
3+
ANOMALI_QUERY_DETAILS = {
4+
"platform_id": "anomali-aql-query",
5+
"name": "Anomali Security Analytics Query",
6+
"group_name": "Anomali Security Analytics",
7+
"platform_name": "Query",
8+
"group_id": "anomali",
9+
}
10+
11+
anomali_query_details = PlatformDetails(**ANOMALI_QUERY_DETAILS)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from app.translator.core.mapping import BaseCommonPlatformMappings, LogSourceSignature
2+
from app.translator.platforms.anomali.const import anomali_query_details
3+
4+
5+
class AnomaliLogSourceSignature(LogSourceSignature):
6+
def is_suitable(self) -> bool:
7+
return True
8+
9+
def __str__(self) -> str:
10+
return ""
11+
12+
13+
class AnomaliMappings(BaseCommonPlatformMappings):
14+
def prepare_log_source_signature(self, mapping: dict) -> AnomaliLogSourceSignature: # noqa: ARG002
15+
return AnomaliLogSourceSignature()
16+
17+
18+
anomali_query_mappings = AnomaliMappings(platform_dir="anomali", platform_details=anomali_query_details)

uncoder-core/app/translator/platforms/anomali/renders/__init__.py

Whitespace-only changes.
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
"""
2+
Uncoder IO Community Edition License
3+
-----------------------------------------------------------------
4+
Copyright (c) 2024 SOC Prime, Inc.
5+
6+
Licensed under the Apache License, Version 2.0 (the "License");
7+
you may not use this file except in compliance with the License.
8+
You may obtain a copy of the License at
9+
10+
http://www.apache.org/licenses/LICENSE-2.0
11+
12+
Unless required by applicable law or agreed to in writing, software
13+
distributed under the License is distributed on an "AS IS" BASIS,
14+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
See the License for the specific language governing permissions and
16+
limitations under the License.
17+
-----------------------------------------------------------------
18+
"""
19+
from app.translator.const import DEFAULT_VALUE_TYPE
20+
from app.translator.core.custom_types.values import ValueType
21+
from app.translator.core.models.platform_details import PlatformDetails
22+
from app.translator.core.render import BaseFieldValueRender, PlatformQueryRender
23+
from app.translator.managers import render_manager
24+
from app.translator.platforms.anomali.const import anomali_query_details
25+
from app.translator.platforms.anomali.mapping import AnomaliMappings, anomali_query_mappings
26+
from app.translator.platforms.base.sql.str_value_manager import sql_str_value_manager
27+
28+
29+
class AnomaliFieldValueRender(BaseFieldValueRender):
30+
details: PlatformDetails = anomali_query_details
31+
str_value_manager = sql_str_value_manager
32+
33+
@staticmethod
34+
def _wrap_str_value(value: str) -> str:
35+
return f"'{value}'"
36+
37+
def equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
38+
if isinstance(value, list):
39+
return f"({self.or_token.join([self.equal_modifier(field=field, value=v) for v in value])})"
40+
return f"{field} = {self._pre_process_value(field, value, wrap_str=True)}"
41+
42+
def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
43+
if isinstance(value, list):
44+
return f"({self.or_token.join([self.not_equal_modifier(field=field, value=v) for v in value])})"
45+
return f"{field} != {self._pre_process_value(field, value, wrap_str=True)}"
46+
47+
def less_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
48+
return f"{field} < {self._pre_process_value(field, value, wrap_str=True)}"
49+
50+
def less_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
51+
return f"{field} <= {self._pre_process_value(field, value, wrap_str=True)}"
52+
53+
def greater_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
54+
return f"{field} > {self._pre_process_value(field, value, wrap_str=True)}"
55+
56+
def greater_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
57+
return f"{field} >= {self._pre_process_value(field, value, wrap_str=True)}"
58+
59+
def contains_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
60+
if isinstance(value, list):
61+
return f"({self.or_token.join(self.contains_modifier(field=field, value=v) for v in value)})"
62+
return f"{field} like '%{self._pre_process_value(field, value)}%'"
63+
64+
def endswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
65+
if isinstance(value, list):
66+
return f"({self.or_token.join(self.endswith_modifier(field=field, value=v) for v in value)})"
67+
return f"{field} like '%{self._pre_process_value(field, value)}'"
68+
69+
def startswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
70+
if isinstance(value, list):
71+
return f"({self.or_token.join(self.startswith_modifier(field=field, value=v) for v in value)})"
72+
return f"{field} like '{self._pre_process_value(field, value)}%'"
73+
74+
def regex_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
75+
if isinstance(value, list):
76+
return f"({self.or_token.join(self.regex_modifier(field=field, value=v) for v in value)})"
77+
regex_str = self._pre_process_value(field, value, value_type=ValueType.regex_value, wrap_str=True)
78+
return f"regexp_like({field}, {regex_str})"
79+
80+
def keywords(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
81+
return f'message contains "{self._pre_process_value(field, value)}"'
82+
83+
84+
@render_manager.register
85+
class AnomaliQueryRender(PlatformQueryRender):
86+
details: PlatformDetails = anomali_query_details
87+
mappings: AnomaliMappings = anomali_query_mappings
88+
89+
or_token = "OR"
90+
and_token = "AND"
91+
not_token = "NOT"
92+
93+
comment_symbol = "--"
94+
is_single_line_comment = True
95+
96+
field_value_render = AnomaliFieldValueRender(or_token=or_token)
97+
98+
@staticmethod
99+
def _finalize_search_query(query: str) -> str:
100+
return f"| where {query}" if query else ""

uncoder-core/app/translator/platforms/base/aql/str_value_manager.py

Lines changed: 1 addition & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -23,50 +23,19 @@
2323
from app.translator.core.custom_types.values import ValueType
2424
from app.translator.core.str_value_manager import (
2525
CONTAINER_SPEC_SYMBOLS_MAP,
26+
RE_STR_SPEC_SYMBOLS_MAP,
2627
BaseSpecSymbol,
27-
ReAnySymbol,
28-
ReCaretSymbol,
29-
ReCommaSymbol,
3028
ReDigitalSymbol,
31-
ReEndOfStrSymbol,
32-
ReHyphenSymbol,
33-
ReLeftCurlyBracket,
34-
ReLeftParenthesis,
35-
ReLeftSquareBracket,
36-
ReOneOrMoreQuantifier,
37-
ReOrOperator,
38-
ReRightCurlyBracket,
39-
ReRightParenthesis,
40-
ReRightSquareBracket,
4129
ReWhiteSpaceSymbol,
4230
ReWordBoundarySymbol,
4331
ReWordSymbol,
44-
ReZeroOrMoreQuantifier,
45-
ReZeroOrOneQuantifier,
4632
SingleSymbolWildCard,
4733
StrValue,
4834
StrValueManager,
4935
UnboundLenWildCard,
5036
)
5137
from app.translator.platforms.base.aql.escape_manager import aql_escape_manager
5238

53-
RE_STR_SPEC_SYMBOLS_MAP = {
54-
"?": ReZeroOrOneQuantifier,
55-
"*": ReZeroOrMoreQuantifier,
56-
"+": ReOneOrMoreQuantifier,
57-
"^": ReCaretSymbol,
58-
"$": ReEndOfStrSymbol,
59-
".": ReAnySymbol,
60-
"[": ReLeftSquareBracket,
61-
"]": ReRightSquareBracket,
62-
"(": ReLeftParenthesis,
63-
")": ReRightParenthesis,
64-
"{": ReLeftCurlyBracket,
65-
"}": ReRightCurlyBracket,
66-
"|": ReOrOperator,
67-
",": ReCommaSymbol,
68-
"-": ReHyphenSymbol,
69-
}
7039
AQL_CONTAINER_SPEC_SYMBOLS_MAP = copy.copy(CONTAINER_SPEC_SYMBOLS_MAP)
7140
AQL_CONTAINER_SPEC_SYMBOLS_MAP.update({SingleSymbolWildCard: "_", UnboundLenWildCard: "%"})
7241

0 commit comments

Comments
 (0)