Skip to content

Commit b568d8b

Browse files
authored
Merge pull request #118 from UncoderIO/gis-7850
Improve AQL mapping logic; Palo Alto add support keywords; Sigma add …
2 parents 6923f01 + d9d5b0d commit b568d8b

File tree

6 files changed

+119
-5
lines changed

6 files changed

+119
-5
lines changed

uncoder-core/app/translator/mappings/platforms/sigma/windows_powershell.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ description: Text that describe current mapping
55
log_source:
66
product: [windows]
77
service: [powershell]
8+
category: [ps_classic_provider_start, ps_classic_script, ps_classic_start, ps_module, ps_script]
89

910
default_log_source:
1011
product: windows
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
platform: Sigma
2+
source: windows_registry_event
3+
4+
log_source:
5+
product: [windows]
6+
category: [registry_event, registry_set]
7+
8+
default_log_source:
9+
product: windows
10+
category: registry_event
11+
12+
field_mapping:
13+
TargetObject: TargetObject
14+
Image: Image
15+
Details: Details
16+
EventType: EventType
17+
CommandLine: CommandLine
18+
LogonId: LogonId
19+
Product: Product
20+
Company: Company
21+
IntegrityLevel: IntegrityLevel
22+
CurrentDirectory: CurrentDirectory
23+
ProcessId: ProcessId
24+
ParentProcessId: ParentProcessId
25+
ParentCommandLine: ParentCommandLine
26+
ParentImage: ParentImage
27+
ParentUser: ParentUser
28+
ParentIntegrityLevel: ParentIntegrityLevel
29+
ParentLogonId: ParentLogonId
30+
ParentProduct: ParentProduct
31+
ParentCompany: ParentCompany
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from dataclasses import dataclass
2+
3+
4+
@dataclass
5+
class AQLLogSourceMap:
6+
name: str
7+
id_map: dict[str, int]
8+
9+
10+
CATEGORYNAME_ID_MAP = {
11+
"ACL Permit": 4012,
12+
"Successful Registry Modification": 8012,
13+
"File Created": 8028,
14+
"Process Creation Success": 8110,
15+
"DNS In Progress": 18081,
16+
"Object Load Success": 19247,
17+
}
18+
19+
DEVICETYPE_ID_MAP = {
20+
"Configurable Firewall Filter": 4,
21+
"Juniper Networks Firewall and VPN": 5,
22+
"Cisco PIX Firewall": 6,
23+
"Apache HTTP Server": 10,
24+
"Linux OS": 11,
25+
"Microsoft Windows Security Event Log": 12,
26+
"Microsoft IIS": 13,
27+
"Cisco Adaptive Security Appliance (ASA)": 41,
28+
"Squid Web Proxy": 46,
29+
"F5 Networks BIG-IP LTM": 49,
30+
"Fortinet FortiGate Security Gateway": 73,
31+
"Symantec Gateway Security (SGS) Appliance": 82,
32+
"Mac OS X": 102,
33+
"Blue Coat SG Appliance": 103,
34+
"Nortel Switched Firewall 6000": 104,
35+
"Nortel Switched Firewall 5100": 120,
36+
"Imperva SecureSphere": 154,
37+
"ISC BIND": 185,
38+
"Microsoft ISA": 191,
39+
"Cisco ACE Firewall": 194,
40+
"Risk Manager Default Question": 200,
41+
"Palo Alto PA Series": 206,
42+
"Oracle BEA WebLogic": 239,
43+
"Barracuda Spam & Virus Firewall": 278,
44+
"F5 Networks BIG-IP AFM": 296,
45+
"Zscaler Nss": 331,
46+
"Vormetric Data Security": 340,
47+
"Amazon AWS CloudTrail": 347,
48+
"Microsoft DNS Debug": 384,
49+
"Microsoft Office 365": 397,
50+
"Microsoft Azure Platform": 413,
51+
"NGINX HTTP Server": 439,
52+
"Microsoft Azure Active Directory": 445,
53+
"Google Cloud Platform Firewall": 455,
54+
"Amazon AWS Network Firewall": 456,
55+
}
56+
57+
QID_NAME_ID_MAP = {
58+
"ProcessAccess": 5001829,
59+
"FileCreateStreamHash": 5001834,
60+
"Driver loaded": 5001843,
61+
"CreateRemoteThread": 5001845,
62+
}
63+
64+
LOG_SOURCE_FUNCTIONS_MAP = {
65+
r"CATEGORYNAME\(category\)": AQLLogSourceMap(name="category", id_map=CATEGORYNAME_ID_MAP),
66+
r"LOGSOURCETYPENAME\(devicetype\)": AQLLogSourceMap(name="devicetype", id_map=DEVICETYPE_ID_MAP),
67+
r"QIDNAME\(qid\)": AQLLogSourceMap(name="qid", id_map=QID_NAME_ID_MAP),
68+
}

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,11 @@ def get_suitable_source_mappings(
7474
if log_source_signature.is_suitable(devicetype, category, qid, qideventcategory):
7575
if source_mapping.fields_mapping.is_suitable(field_names):
7676
suitable_source_mappings.append(source_mapping)
77-
elif source_mapping.fields_mapping.is_suitable(field_names):
78-
suitable_source_mappings.append(source_mapping)
77+
78+
if not suitable_source_mappings:
79+
for source_mapping in self._source_mappings.values():
80+
if source_mapping.fields_mapping.is_suitable(field_names):
81+
suitable_source_mappings.append(source_mapping)
7982

8083
if not suitable_source_mappings:
8184
suitable_source_mappings = [self._source_mappings[DEFAULT_MAPPING_NAME]]

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

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from app.translator.core.models.query_container import RawQueryContainer, TokenizedQueryContainer
2323
from app.translator.core.parser import PlatformQueryParser
2424
from app.translator.platforms.base.aql.const import NUM_VALUE_PATTERN, SINGLE_QUOTES_VALUE_PATTERN
25+
from app.translator.platforms.base.aql.log_source_map import LOG_SOURCE_FUNCTIONS_MAP
2526
from app.translator.platforms.base.aql.mapping import AQLMappings, aql_mappings
2627
from app.translator.platforms.base.aql.tokenizer import AQLTokenizer
2728
from app.translator.tools.utils import get_match_group
@@ -31,10 +32,10 @@ class AQLQueryParser(PlatformQueryParser):
3132
tokenizer = AQLTokenizer()
3233
mappings: AQLMappings = aql_mappings
3334

34-
log_source_functions = ("LOGSOURCENAME", "LOGSOURCEGROUPNAME", "LOGSOURCETYPENAME", "CATEGORYNAME")
35+
log_source_functions = ("LOGSOURCENAME", "LOGSOURCEGROUPNAME")
3536
log_source_function_pattern = r"\(?(?P<key>___func_name___\([a-zA-Z]+\))(?:\s+like\s+|\s+ilike\s+|\s*=\s*)'(?P<value>[%a-zA-Z\s]+)'\s*\)?\s+(?:and|or)?\s" # noqa: E501
3637

37-
log_source_key_types = ("devicetype", "category", "qid", "qideventcategory")
38+
log_source_key_types = ("devicetype", "category", "qid", "qideventcategory", *LOG_SOURCE_FUNCTIONS_MAP.keys())
3839
log_source_pattern = rf"___source_type___(?:\s+like\s+|\s+ilike\s+|\s*=\s*)(?:{SINGLE_QUOTES_VALUE_PATTERN}|{NUM_VALUE_PATTERN})(?:\s+(?:and|or)\s+|\s+)?" # noqa: E501
3940
num_value_pattern = r"[0-9]+"
4041
multi_num_log_source_pattern = (
@@ -67,6 +68,11 @@ def __parse_multi_value_log_source(
6768
query = query[:pos_start] + query[pos_end:]
6869
return query, re.findall(pattern, value)
6970

71+
def __map_log_source_value(self, logsource_key: str, value: Union[str, int]) -> tuple[str, Union[int, str]]:
72+
if log_source_map := LOG_SOURCE_FUNCTIONS_MAP.get(logsource_key):
73+
return log_source_map.name, log_source_map.id_map.get(value, value)
74+
return logsource_key, value
75+
7076
def __parse_log_sources(self, query: str) -> tuple[dict[str, Union[list[str], list[int]]], str]:
7177
log_sources = {}
7278

@@ -80,6 +86,7 @@ def __parse_log_sources(self, query: str) -> tuple[dict[str, Union[list[str], li
8086
num_value = get_match_group(search, group_name="num_value")
8187
str_value = get_match_group(search, group_name="s_q_value")
8288
value = num_value and int(num_value) or str_value
89+
log_source_key, value = self.__map_log_source_value(log_source_key, value)
8390
log_sources.setdefault(log_source_key, []).append(value)
8491
pos_start = search.start()
8592
pos_end = search.end()

uncoder-core/app/translator/platforms/palo_alto/renders/cortex_xsiam.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,11 @@ def is_not_none(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
9696
return f"{field} != null"
9797

9898
def keywords(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG002
99-
raise UnsupportedRenderMethod(platform_name=self.details.name, method="Keywords")
99+
if isinstance(value, list):
100+
return f"({self.or_token.join(self.contains_modifier(field=field, value=v) for v in value)})"
101+
if value.endswith("\\"):
102+
return f'_raw_log ~= ".*{self.apply_value(value, value_type=ValueType.regex_value)}.*"'
103+
return f'_raw_log contains "{self.apply_value(value)}"'
100104

101105

102106
@render_manager.register

0 commit comments

Comments
 (0)