Skip to content

Gis 8825 added sentinel one power query render #205

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Dec 17, 2024
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
platform: Sentinel One Power Query
source: default
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
1 change: 1 addition & 0 deletions uncoder-core/app/translator/platforms/carbonblack/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"platform_name": "Query (Cloud)",
}


DEFAULT_CARBONBLACK_CTI_MAPPING = {
"SourceIP": "netconn_local_ipv4",
"DestinationIP": "netconn_ipv4",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)]

Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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
)
17 changes: 15 additions & 2 deletions uncoder-core/app/translator/platforms/sentinel_one/const.py
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
from app.translator.core.custom_types.values import ValueType


class SentinelOneValueType(ValueType):
double_escape_regex_value = "d_e_re_value"
Original file line number Diff line number Diff line change
@@ -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()
20 changes: 20 additions & 0 deletions uncoder-core/app/translator/platforms/sentinel_one/mapping.py
Original file line number Diff line number Diff line change
@@ -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
)
Original file line number Diff line number Diff line change
Expand Up @@ -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 = ", "
Expand Down
Original file line number Diff line number Diff line change
@@ -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)
Original file line number Diff line number Diff line change
@@ -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()
Loading
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