diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/default.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/default.yml new file mode 100644 index 00000000..16f2f7e5 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/default.yml @@ -0,0 +1,2 @@ +platform: Sentinel One Power Query +source: default diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/dns.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/dns.yml new file mode 100644 index 00000000..d04d59e2 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/dns.yml @@ -0,0 +1,12 @@ +platform: Sentinel One Power Query +source: dns + +field_mapping: + Image: src.process.image.path + CommandLine: src.process.cmdline + ParentImage: src.process.parent.image.path + ParentCommandLine: src.process.parent.cmdline + query: event.dns.request + answer: event.dns.response + QueryName: event.dns.request + record_type: event.dns.response \ No newline at end of file diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/linux_file_event.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/linux_file_event.yml new file mode 100644 index 00000000..7fbf5c59 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/linux_file_event.yml @@ -0,0 +1,11 @@ +platform: Sentinel One Power Query +source: linux_file_event + +field_mapping: + Image: src.process.image.path + CommandLine: src.process.cmdline + ParentImage: src.process.parent.image.path + ParentCommandLine: src.process.parent.cmdline + TargetFilename: tgt.file.path + SourceFilename: tgt.file.oldPath + User: src.process.use \ No newline at end of file diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_image_load.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_image_load.yml new file mode 100644 index 00000000..e6533f12 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_image_load.yml @@ -0,0 +1,9 @@ +platform: Sentinel One Power Query +source: windows_image_load + +field_mapping: + Image: Image + ImageLoaded: ImageLoaded + SignatureStatus: SignatureStatus + OriginalFileName: OriginalFileName + Signed: Signed \ No newline at end of file diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_network_connection.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_network_connection.yml new file mode 100644 index 00000000..f740d589 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_network_connection.yml @@ -0,0 +1,21 @@ +platform: Sentinel One Power Query +source: windows_network_connection + +field_mapping: + Image: src.process.image.path + CommandLine: src.process.cmdline + ParentImage: src.process.parent.image.path + ParentCommandLine: src.process.parent.cmdline + DestinationHostname: + - url.address + - event.dns.request + DestinationPort: dst.port.number + DestinationIp: dst.ip.address + User: src.process.user + SourceIp: src.ip.address + SourcePort: src.port.number + Protocol: NetProtocolName + dst_ip: dst.ip.address + src_ip: src.ip.address + dst_port: dst.port.number + src_port: src.port.number \ No newline at end of file diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_pipe_created.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_pipe_created.yml new file mode 100644 index 00000000..0f670481 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_pipe_created.yml @@ -0,0 +1,9 @@ +platform: Sentinel One Power Query +source: windows_pipe_created + +field_mapping: + PipeName: namedPipe.name + Image: src.process.image.path + CommandLine: src.process.cmdline + ParentImage: src.process.parent.image.path + ParentCommandLine: src.process.parent.cmdline \ No newline at end of file diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_process_creation.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_process_creation.yml new file mode 100644 index 00000000..f736fa46 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_process_creation.yml @@ -0,0 +1,21 @@ +platform: Sentinel One Power Query +source: windows_process_creation + +field_mapping: + ProcessId: tgt.process.pid + Image: tgt.process.image.path + Description: tgt.process.displayName + Publisher: tgt.process.publisher + Product: tgt.process.displayName + Company: tgt.process.publisher + CommandLine: tgt.process.cmdline + CurrentDirectory: tgt.process.image.path + User: tgt.process.user + TerminalSessionId: tgt.process.sessionid + IntegrityLevel: tgt.process.integrityLevel + md5: tgt.process.image.md5 + sha1: tgt.process.image.sha1 + sha256: tgt.process.image.sha256 + ParentProcessId: src.process.pid + ParentImage: src.process.image.path + ParentCommandLine: src.process.cmdline \ No newline at end of file diff --git a/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_registry_event.yml b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_registry_event.yml new file mode 100644 index 00000000..72f8db79 --- /dev/null +++ b/uncoder-core/app/translator/mappings/platforms/sentinel_one/windows_registry_event.yml @@ -0,0 +1,10 @@ +platform: Sentinel One Power Query +source: windows_registry_event + +field_mapping: + Image: src.process.image.path + CommandLine: src.process.cmdline + ParentImage: src.process.parent.image.path + ParentCommandLine: src.process.parent.cmdline + TargetObject: registry.keyPath + Details: registry.value \ No newline at end of file diff --git a/uncoder-core/app/translator/platforms/carbonblack/const.py b/uncoder-core/app/translator/platforms/carbonblack/const.py index e1c2fdf1..4e7a6afe 100644 --- a/uncoder-core/app/translator/platforms/carbonblack/const.py +++ b/uncoder-core/app/translator/platforms/carbonblack/const.py @@ -8,6 +8,7 @@ "platform_name": "Query (Cloud)", } + DEFAULT_CARBONBLACK_CTI_MAPPING = { "SourceIP": "netconn_local_ipv4", "DestinationIP": "netconn_ipv4", diff --git a/uncoder-core/app/translator/platforms/carbonblack/renders/carbonblack_cti.py b/uncoder-core/app/translator/platforms/carbonblack/renders/carbonblack_cti.py index 154ee0b5..e6b3e713 100644 --- a/uncoder-core/app/translator/platforms/carbonblack/renders/carbonblack_cti.py +++ b/uncoder-core/app/translator/platforms/carbonblack/renders/carbonblack_cti.py @@ -23,6 +23,7 @@ from app.translator.platforms.carbonblack.const import DEFAULT_CARBONBLACK_CTI_MAPPING, carbonblack_query_details + @render_cti_manager.register class CarbonBlackCTI(RenderCTI): details: PlatformDetails = carbonblack_query_details diff --git a/uncoder-core/app/translator/platforms/elasticsearch/renders/elasticsearch_eql.py b/uncoder-core/app/translator/platforms/elasticsearch/renders/elasticsearch_eql.py index 8fe19cd8..1bf657fc 100644 --- a/uncoder-core/app/translator/platforms/elasticsearch/renders/elasticsearch_eql.py +++ b/uncoder-core/app/translator/platforms/elasticsearch/renders/elasticsearch_eql.py @@ -134,4 +134,3 @@ def generate_prefix(self, log_source_signature: Optional[LogSourceSignature], fu def in_brackets(self, raw_list: list[QUERY_TOKEN_TYPE]) -> list[QUERY_TOKEN_TYPE]: return [Identifier(token_type=GroupType.L_PAREN), *raw_list, Identifier(token_type=GroupType.R_PAREN)] - diff --git a/uncoder-core/app/translator/platforms/microsoft/parsers/microsoft_sentinel.py b/uncoder-core/app/translator/platforms/microsoft/parsers/microsoft_sentinel.py index 680f3e2d..e7392ea3 100644 --- a/uncoder-core/app/translator/platforms/microsoft/parsers/microsoft_sentinel.py +++ b/uncoder-core/app/translator/platforms/microsoft/parsers/microsoft_sentinel.py @@ -16,6 +16,7 @@ ----------------------------------------------------------------- """ + from app.translator.core.models.functions.base import ParsedFunctions from app.translator.core.models.platform_details import PlatformDetails from app.translator.core.models.query_container import RawQueryContainer, TokenizedQueryContainer diff --git a/uncoder-core/app/translator/platforms/sentinel_one/__init__.py b/uncoder-core/app/translator/platforms/sentinel_one/__init__.py index 0ba5cbed..d73e2978 100644 --- a/uncoder-core/app/translator/platforms/sentinel_one/__init__.py +++ b/uncoder-core/app/translator/platforms/sentinel_one/__init__.py @@ -1 +1,4 @@ from app.translator.platforms.sentinel_one.renders.s1_cti import S1EventsCTI # noqa: F401 +from app.translator.platforms.sentinel_one.renders.sentinel_one_power_query import ( + SentinelOnePowerQueryRender, # noqa: F401 +) diff --git a/uncoder-core/app/translator/platforms/sentinel_one/const.py b/uncoder-core/app/translator/platforms/sentinel_one/const.py index b9dc9dbe..869aff36 100644 --- a/uncoder-core/app/translator/platforms/sentinel_one/const.py +++ b/uncoder-core/app/translator/platforms/sentinel_one/const.py @@ -1,7 +1,20 @@ +from app.translator.core.models.platform_details import PlatformDetails + +PLATFORM_DETAILS = {"group_id": "sentinel-one", "group_name": "SentinelOne"} + SENTINEL_ONE_EVENTS_QUERY_DETAILS = { "platform_id": "s1-events", "name": "SentinelOne Events Query", - "group_name": "SentinelOne", - "group_id": "sentinel-one", "platform_name": "Query (Events)", + **PLATFORM_DETAILS, } + +SENTINEL_ONE_POWER_QUERY_DETAILS = { + "platform_id": "sentinel-one-power-query", + "name": "SentinelOne Power Query", + "platform_name": "Power Query", + **PLATFORM_DETAILS, +} + +sentinel_one_events_query_details = PlatformDetails(**SENTINEL_ONE_EVENTS_QUERY_DETAILS) +sentinel_one_power_query_details = PlatformDetails(**SENTINEL_ONE_POWER_QUERY_DETAILS) diff --git a/uncoder-core/app/translator/platforms/sentinel_one/custom_types/__init__.py b/uncoder-core/app/translator/platforms/sentinel_one/custom_types/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/uncoder-core/app/translator/platforms/sentinel_one/custom_types/values.py b/uncoder-core/app/translator/platforms/sentinel_one/custom_types/values.py new file mode 100644 index 00000000..c009aa9a --- /dev/null +++ b/uncoder-core/app/translator/platforms/sentinel_one/custom_types/values.py @@ -0,0 +1,5 @@ +from app.translator.core.custom_types.values import ValueType + + +class SentinelOneValueType(ValueType): + double_escape_regex_value = "d_e_re_value" diff --git a/uncoder-core/app/translator/platforms/sentinel_one/escape_manager.py b/uncoder-core/app/translator/platforms/sentinel_one/escape_manager.py new file mode 100644 index 00000000..04193dce --- /dev/null +++ b/uncoder-core/app/translator/platforms/sentinel_one/escape_manager.py @@ -0,0 +1,17 @@ +from typing import ClassVar + +from app.translator.core.custom_types.values import ValueType +from app.translator.core.escape_manager import EscapeManager +from app.translator.core.models.escape_details import EscapeDetails +from app.translator.platforms.sentinel_one.custom_types.values import SentinelOneValueType + + +class SentinelOnePowerQueryEscapeManager(EscapeManager): + escape_map: ClassVar[dict[str, list[EscapeDetails]]] = { + ValueType.value: [EscapeDetails(pattern=r"\\", escape_symbols=r"\\\\")], + ValueType.regex_value: [EscapeDetails(pattern=r"([$^*+()\[\]{}|.?\-\\])", escape_symbols=r"\\\1")], + SentinelOneValueType.double_escape_regex_value: [EscapeDetails(pattern=r"\\", escape_symbols=r"\\\\")], + } + + +sentinel_one_power_query_escape_manager = SentinelOnePowerQueryEscapeManager() diff --git a/uncoder-core/app/translator/platforms/sentinel_one/mapping.py b/uncoder-core/app/translator/platforms/sentinel_one/mapping.py new file mode 100644 index 00000000..f782551f --- /dev/null +++ b/uncoder-core/app/translator/platforms/sentinel_one/mapping.py @@ -0,0 +1,20 @@ +from app.translator.core.mapping import BasePlatformMappings, LogSourceSignature +from app.translator.platforms.sentinel_one.const import sentinel_one_power_query_details + + +class SentinelOnePowerQueryLogSourceSignature(LogSourceSignature): + def is_suitable(self) -> bool: + return True + + def __str__(self) -> str: + return "" + + +class SentinelOnePowerQueryMappings(BasePlatformMappings): + def prepare_log_source_signature(self, mapping: dict) -> SentinelOnePowerQueryLogSourceSignature: + ... + + +sentinel_one_power_query_query_mappings = SentinelOnePowerQueryMappings( + platform_dir="sentinel_one", platform_details=sentinel_one_power_query_details +) diff --git a/uncoder-core/app/translator/platforms/sentinel_one/renders/s1_cti.py b/uncoder-core/app/translator/platforms/sentinel_one/renders/s1_cti.py index 917ec84c..8c416a1d 100644 --- a/uncoder-core/app/translator/platforms/sentinel_one/renders/s1_cti.py +++ b/uncoder-core/app/translator/platforms/sentinel_one/renders/s1_cti.py @@ -20,13 +20,13 @@ from app.translator.core.models.platform_details import PlatformDetails from app.translator.core.render_cti import RenderCTI from app.translator.managers import render_cti_manager -from app.translator.platforms.sentinel_one.const import SENTINEL_ONE_EVENTS_QUERY_DETAILS +from app.translator.platforms.sentinel_one.const import sentinel_one_events_query_details from app.translator.platforms.sentinel_one.mappings.s1_cti import DEFAULT_S1EVENTS_MAPPING @render_cti_manager.register class S1EventsCTI(RenderCTI): - details: PlatformDetails = PlatformDetails(**SENTINEL_ONE_EVENTS_QUERY_DETAILS) + details: PlatformDetails = sentinel_one_events_query_details field_value_template: str = '"{value}"' or_operator: str = ", " diff --git a/uncoder-core/app/translator/platforms/sentinel_one/renders/sentinel_one_power_query.py b/uncoder-core/app/translator/platforms/sentinel_one/renders/sentinel_one_power_query.py new file mode 100644 index 00000000..0e827722 --- /dev/null +++ b/uncoder-core/app/translator/platforms/sentinel_one/renders/sentinel_one_power_query.py @@ -0,0 +1,102 @@ +from typing import Union + +from app.translator.const import DEFAULT_VALUE_TYPE +from app.translator.core.custom_types.values import ValueType +from app.translator.core.models.platform_details import PlatformDetails +from app.translator.core.render import BaseFieldValueRender, PlatformQueryRender +from app.translator.core.str_value_manager import StrValueManager +from app.translator.managers import render_manager +from app.translator.platforms.sentinel_one.const import sentinel_one_power_query_details +from app.translator.platforms.sentinel_one.mapping import ( + SentinelOnePowerQueryMappings, + sentinel_one_power_query_query_mappings, +) +from app.translator.platforms.sentinel_one.str_value_manager import sentinel_one_power_query_str_value_manager + + +class SentinelOnePowerQueryFieldValue(BaseFieldValueRender): + details: PlatformDetails = sentinel_one_power_query_details + str_value_manager: StrValueManager = sentinel_one_power_query_str_value_manager + list_token = ", " + + @staticmethod + def _wrap_str_value(value: str) -> str: + return f'"{value}"' + + def equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: + if isinstance(value, list): + values = self.list_token.join( + self._pre_process_value(field, v, value_type=ValueType.value, wrap_str=True) for v in value + ) + return f"{field} in ({values})" + value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True) + return f"{field} = {value}" + + def less_modifier(self, field: str, value: Union[int, str]) -> str: + value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True) + return f"{field} < {value}" + + def less_or_equal_modifier(self, field: str, value: Union[int, str]) -> str: + value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True) + return f"{field} <= {value}" + + def greater_modifier(self, field: str, value: Union[int, str]) -> str: + value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True) + return f"{field} > {value}" + + def greater_or_equal_modifier(self, field: str, value: Union[int, str]) -> str: + value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True) + return f"{field} >= {value}" + + def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: + if isinstance(value, list): + values = self.list_token.join( + self._pre_process_value(field, v, value_type=ValueType.value, wrap_str=True, wrap_int=True) + for v in value + ) + return f"{field} != ({values})" + value = self._pre_process_value(field, value, value_type=ValueType.value, wrap_str=True, wrap_int=True) + return f"{field} != {value}" + + def contains_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: + if isinstance(value, list): + values = self.list_token.join( + self._pre_process_value(field, v, value_type=ValueType.value, wrap_str=True, wrap_int=True) + for v in value + ) + return f"{field} contains ({values})" + value = self._pre_process_value(field, value, value_type=ValueType.value) + return f"{field} contains {value}" + + def endswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: + return self.contains_modifier(field, value) + + def startswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: + return self.contains_modifier(field, value) + + def regex_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: + if isinstance(value, list): + values = self.list_token.join( + self._pre_process_value(field, v, value_type=ValueType.regex_value, wrap_str=True, wrap_int=True) + for v in value + ) + return f"{field} matches ({values})" + value = self._pre_process_value(field, value, value_type=ValueType.regex_value, wrap_str=True, wrap_int=True) + return f"{field} matches {value}" + + def is_none(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG002 + return f'not ({field} matches "\\.*")' + + def is_not_none(self, field: str, value: DEFAULT_VALUE_TYPE) -> str: # noqa: ARG002 + return f'{field} matches "\\.*"' + + +@render_manager.register +class SentinelOnePowerQueryRender(PlatformQueryRender): + details: PlatformDetails = sentinel_one_power_query_details + mappings: SentinelOnePowerQueryMappings = sentinel_one_power_query_query_mappings + or_token = "or" + and_token = "and" + not_token = "not" + comment_symbol = "//" + field_value_render = SentinelOnePowerQueryFieldValue(or_token=or_token) diff --git a/uncoder-core/app/translator/platforms/sentinel_one/str_value_manager.py b/uncoder-core/app/translator/platforms/sentinel_one/str_value_manager.py new file mode 100644 index 00000000..3a48457a --- /dev/null +++ b/uncoder-core/app/translator/platforms/sentinel_one/str_value_manager.py @@ -0,0 +1,44 @@ +""" +Uncoder IO Community Edition License +----------------------------------------------------------------- +Copyright (c) 2024 SOC Prime, Inc. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +----------------------------------------------------------------- +""" +from app.translator.core.custom_types.values import ValueType +from app.translator.core.str_value_manager import BaseSpecSymbol, StrValue, StrValueManager +from app.translator.platforms.sentinel_one.custom_types.values import SentinelOneValueType +from app.translator.platforms.sentinel_one.escape_manager import ( + SentinelOnePowerQueryEscapeManager, + sentinel_one_power_query_escape_manager, +) + + +class SentinelOnePowerQueryStrValueManager(StrValueManager): + escape_manager: SentinelOnePowerQueryEscapeManager = sentinel_one_power_query_escape_manager + + def from_container_to_str(self, container: StrValue, value_type: str = ValueType.value) -> str: + result = "" + for el in container.split_value: + if isinstance(el, str): + result += self.escape_manager.escape(el, value_type) + elif isinstance(el, BaseSpecSymbol) and (pattern := self.container_spec_symbols_map.get(type(el))): + if value_type == ValueType.regex_value: + pattern = self.escape_manager.escape(pattern, SentinelOneValueType.double_escape_regex_value) + result += pattern + + return result + + +sentinel_one_power_query_str_value_manager = SentinelOnePowerQueryStrValueManager() 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