Skip to content

anomali render #193

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 1 commit into from
Sep 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion uncoder-core/app/translator/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@

CTI_IOCS_PER_QUERY_LIMIT = 25

DEFAULT_VALUE_TYPE = Union[int, str, StrValue, list[Union[int, str, StrValue]]]
DEFAULT_VALUE_TYPE = Union[bool, int, str, StrValue, list[Union[int, str, StrValue]]]
2 changes: 1 addition & 1 deletion uncoder-core/app/translator/core/render.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ def _map_bool_value(value: bool) -> str:
def _pre_process_value(
self,
field: str,
value: Union[int, str, StrValue],
value: Union[bool, int, str, StrValue],
value_type: str = ValueType.value,
wrap_str: bool = False,
wrap_int: bool = False,
Expand Down
19 changes: 19 additions & 0 deletions uncoder-core/app/translator/core/str_value_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,25 @@ def has_spec_symbols(self) -> bool:
return any(isinstance(el, BaseSpecSymbol) for el in self.split_value)


RE_STR_SPEC_SYMBOLS_MAP = {
"?": ReZeroOrOneQuantifier,
"*": ReZeroOrMoreQuantifier,
"+": ReOneOrMoreQuantifier,
"^": ReCaretSymbol,
"$": ReEndOfStrSymbol,
".": ReAnySymbol,
"[": ReLeftSquareBracket,
"]": ReRightSquareBracket,
"(": ReLeftParenthesis,
")": ReRightParenthesis,
"{": ReLeftCurlyBracket,
"}": ReRightCurlyBracket,
"|": ReOrOperator,
",": ReCommaSymbol,
"-": ReHyphenSymbol,
}


CONTAINER_SPEC_SYMBOLS_MAP = {
SingleSymbolWildCard: "?",
UnboundLenWildCard: "*",
Expand Down
31 changes: 31 additions & 0 deletions uncoder-core/app/translator/mappings/platforms/anomali/common.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
platform: Anomali
description: Common field mapping

field_mapping:
c-uri-query: url
c-useragent: user_agent
CommandLine: command_line
DestinationHostname: dest
DestinationIp: dest_ip
DestinationPort: dest_port
Details: reg_value_data
dst_ip: dest_ip
dst_port: dest_port
EventID: event_id
EventName: event_name
FileName: file_name
FilePath: file_path
Image: image
NewProcessName: image
OriginalFileName: original_file_name
ParentCommandLine: parent_command_line
ParentImage: parent_image
ParentProcessID: parent_process_id
Platform: platform
ProcessCommandLine: command_line
ProcessID: process_id
SourceImage: parent_image
SourcePort: src_port
TargetFilename: file_name
TargetObject: reg_key
UserAgent: user_agent
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
platform: Anomali
source: default


default_log_source: {}
1 change: 1 addition & 0 deletions uncoder-core/app/translator/platforms/anomali/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from app.translator.platforms.anomali.renders.anomali import AnomaliQueryRender # noqa: F401
11 changes: 11 additions & 0 deletions uncoder-core/app/translator/platforms/anomali/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
from app.translator.core.models.platform_details import PlatformDetails

ANOMALI_QUERY_DETAILS = {
"platform_id": "anomali-aql-query",
"name": "Anomali Security Analytics Query",
"group_name": "Anomali Security Analytics",
"platform_name": "Query",
"group_id": "anomali",
}

anomali_query_details = PlatformDetails(**ANOMALI_QUERY_DETAILS)
18 changes: 18 additions & 0 deletions uncoder-core/app/translator/platforms/anomali/mapping.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from app.translator.core.mapping import BaseCommonPlatformMappings, LogSourceSignature
from app.translator.platforms.anomali.const import anomali_query_details


class AnomaliLogSourceSignature(LogSourceSignature):
def is_suitable(self) -> bool:
return True

def __str__(self) -> str:
return ""


class AnomaliMappings(BaseCommonPlatformMappings):
def prepare_log_source_signature(self, mapping: dict) -> AnomaliLogSourceSignature: # noqa: ARG002
return AnomaliLogSourceSignature()


anomali_query_mappings = AnomaliMappings(platform_dir="anomali", platform_details=anomali_query_details)
Empty file.
100 changes: 100 additions & 0 deletions uncoder-core/app/translator/platforms/anomali/renders/anomali.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""
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.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.managers import render_manager
from app.translator.platforms.anomali.const import anomali_query_details
from app.translator.platforms.anomali.mapping import AnomaliMappings, anomali_query_mappings
from app.translator.platforms.base.sql.str_value_manager import sql_str_value_manager


class AnomaliFieldValueRender(BaseFieldValueRender):
details: PlatformDetails = anomali_query_details
str_value_manager = sql_str_value_manager

@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):
return f"({self.or_token.join([self.equal_modifier(field=field, value=v) for v in value])})"
return f"{field} = {self._pre_process_value(field, value, wrap_str=True)}"

def not_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join([self.not_equal_modifier(field=field, value=v) for v in value])})"
return f"{field} != {self._pre_process_value(field, value, wrap_str=True)}"

def less_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} < {self._pre_process_value(field, value, wrap_str=True)}"

def less_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} <= {self._pre_process_value(field, value, wrap_str=True)}"

def greater_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} > {self._pre_process_value(field, value, wrap_str=True)}"

def greater_or_equal_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f"{field} >= {self._pre_process_value(field, value, wrap_str=True)}"

def contains_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.contains_modifier(field=field, value=v) for v in value)})"
return f"{field} like '%{self._pre_process_value(field, value)}%'"

def endswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.endswith_modifier(field=field, value=v) for v in value)})"
return f"{field} like '%{self._pre_process_value(field, value)}'"

def startswith_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.startswith_modifier(field=field, value=v) for v in value)})"
return f"{field} like '{self._pre_process_value(field, value)}%'"

def regex_modifier(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
if isinstance(value, list):
return f"({self.or_token.join(self.regex_modifier(field=field, value=v) for v in value)})"
regex_str = self._pre_process_value(field, value, value_type=ValueType.regex_value, wrap_str=True)
return f"regexp_like({field}, {regex_str})"

def keywords(self, field: str, value: DEFAULT_VALUE_TYPE) -> str:
return f'message contains "{self._pre_process_value(field, value)}"'


@render_manager.register
class AnomaliQueryRender(PlatformQueryRender):
details: PlatformDetails = anomali_query_details
mappings: AnomaliMappings = anomali_query_mappings

or_token = "OR"
and_token = "AND"
not_token = "NOT"

comment_symbol = "--"
is_single_line_comment = True

field_value_render = AnomaliFieldValueRender(or_token=or_token)

@staticmethod
def _finalize_search_query(query: str) -> str:
return f"| where {query}" if query else ""
Original file line number Diff line number Diff line change
Expand Up @@ -23,50 +23,19 @@
from app.translator.core.custom_types.values import ValueType
from app.translator.core.str_value_manager import (
CONTAINER_SPEC_SYMBOLS_MAP,
RE_STR_SPEC_SYMBOLS_MAP,
BaseSpecSymbol,
ReAnySymbol,
ReCaretSymbol,
ReCommaSymbol,
ReDigitalSymbol,
ReEndOfStrSymbol,
ReHyphenSymbol,
ReLeftCurlyBracket,
ReLeftParenthesis,
ReLeftSquareBracket,
ReOneOrMoreQuantifier,
ReOrOperator,
ReRightCurlyBracket,
ReRightParenthesis,
ReRightSquareBracket,
ReWhiteSpaceSymbol,
ReWordBoundarySymbol,
ReWordSymbol,
ReZeroOrMoreQuantifier,
ReZeroOrOneQuantifier,
SingleSymbolWildCard,
StrValue,
StrValueManager,
UnboundLenWildCard,
)
from app.translator.platforms.base.aql.escape_manager import aql_escape_manager

RE_STR_SPEC_SYMBOLS_MAP = {
"?": ReZeroOrOneQuantifier,
"*": ReZeroOrMoreQuantifier,
"+": ReOneOrMoreQuantifier,
"^": ReCaretSymbol,
"$": ReEndOfStrSymbol,
".": ReAnySymbol,
"[": ReLeftSquareBracket,
"]": ReRightSquareBracket,
"(": ReLeftParenthesis,
")": ReRightParenthesis,
"{": ReLeftCurlyBracket,
"}": ReRightCurlyBracket,
"|": ReOrOperator,
",": ReCommaSymbol,
"-": ReHyphenSymbol,
}
AQL_CONTAINER_SPEC_SYMBOLS_MAP = copy.copy(CONTAINER_SPEC_SYMBOLS_MAP)
AQL_CONTAINER_SPEC_SYMBOLS_MAP.update({SingleSymbolWildCard: "_", UnboundLenWildCard: "%"})

Expand Down
18 changes: 18 additions & 0 deletions uncoder-core/app/translator/platforms/base/sql/escape_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
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


class SQLEscapeManager(EscapeManager):
escape_map: ClassVar[dict[str, list[EscapeDetails]]] = {
ValueType.value: [EscapeDetails(pattern=r"(')", escape_symbols=r"'\1")],
ValueType.regex_value: [
EscapeDetails(pattern=r"([$^*+()\[\]{}|.?\-\\])", escape_symbols=r"\\\1"),
EscapeDetails(pattern=r"(')", escape_symbols=r"'\1"),
],
}


sql_escape_manager = SQLEscapeManager()
100 changes: 100 additions & 0 deletions uncoder-core/app/translator/platforms/base/sql/str_value_manager.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
"""
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.
-----------------------------------------------------------------
"""

import copy
from typing import ClassVar

from app.translator.core.custom_types.values import ValueType
from app.translator.core.str_value_manager import (
CONTAINER_SPEC_SYMBOLS_MAP,
RE_STR_SPEC_SYMBOLS_MAP,
BaseSpecSymbol,
ReDigitalSymbol,
ReWhiteSpaceSymbol,
ReWordBoundarySymbol,
ReWordSymbol,
SingleSymbolWildCard,
StrValue,
StrValueManager,
UnboundLenWildCard,
)
from app.translator.platforms.base.sql.escape_manager import sql_escape_manager

SQL_CONTAINER_SPEC_SYMBOLS_MAP = copy.copy(CONTAINER_SPEC_SYMBOLS_MAP)
SQL_CONTAINER_SPEC_SYMBOLS_MAP.update({SingleSymbolWildCard: "_", UnboundLenWildCard: "%"})


class SQLStrValueManager(StrValueManager):
escape_manager = sql_escape_manager
container_spec_symbols_map: ClassVar[dict[type[BaseSpecSymbol], str]] = SQL_CONTAINER_SPEC_SYMBOLS_MAP
re_str_alpha_num_symbols_map: ClassVar[dict[str, type[BaseSpecSymbol]]] = {
"b": ReWordBoundarySymbol,
"w": ReWordSymbol,
"d": ReDigitalSymbol,
"s": ReWhiteSpaceSymbol,
}
re_str_spec_symbols_map = RE_STR_SPEC_SYMBOLS_MAP
str_spec_symbols_map: ClassVar[dict[str, type[BaseSpecSymbol]]] = {
"_": SingleSymbolWildCard,
"%": UnboundLenWildCard,
}

def from_str_to_container(self, value: str) -> StrValue:
split = []
prev_char = None
for char in value:
if char in self.str_spec_symbols_map:
split.append(self.str_spec_symbols_map[char]())
else:
if char == "'":
if prev_char == "'":
split.append(char)
prev_char = char
continue
split.append(char)

prev_char = char

return StrValue(value, self._concat(split))

def from_re_str_to_container(self, value: str) -> StrValue:
value = value.replace("''", "'")
return super().from_re_str_to_container(value)

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):
if value_type == ValueType.regex_value:
if isinstance(el, SingleSymbolWildCard):
result += "."
continue
if isinstance(el, UnboundLenWildCard):
result += ".*"
continue

if pattern := self.container_spec_symbols_map.get(type(el)):
result += pattern

return result


sql_str_value_manager = SQLStrValueManager()
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