Skip to content
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 2 additions & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ services:
- '4010:4010'
translator:
build:
context: './translator/'
container_name: translator
context: './uncoder-core/'
container_name: uncoder-core
restart: always
environment:
- HOST=0.0.0.0
Expand Down
90 changes: 0 additions & 90 deletions translator/app/routers/translate.py

This file was deleted.

File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@


class CTIPlatform(BaseModel):
name: str
id: str


class OneTranslationCTIData(BaseModel):
info: Optional[InfoMessage] = None
status: bool
translations: Optional[list] = None
target_siem_type: str
target_platform_id: str
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class OneTranslationData(BaseModel):
info: Optional[InfoMessage] = None
status: bool
translation: Optional[str] = None
target_siem_type: str
target_platform_id: str


class ConvertorPlatform(BaseModel):
class TranslatorPlatform(BaseModel):
name: str
id: str
code: str
Expand All @@ -28,7 +28,7 @@ class ConvertorPlatform(BaseModel):
first_choice: int = 1


class ConvertorPlatforms(BaseModel):
class TranslatorPlatforms(BaseModel):
renders: list
parsers: list

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

from app.models.ioc_translation import CTIPlatform, OneTranslationCTIData
from app.models.translation import InfoMessage
from app.translator.cti_translator import CTIConverter
from app.translator.cti_translator import CTITranslator
from app.translator.tools.const import HashType, IocParsingRule, IOCType

iocs_router = APIRouter()
converter = CTIConverter()
cti_translator = CTITranslator()


@iocs_router.post("/iocs/translate", description="Parse IOCs from text.")
@iocs_router.post("/iocs/translate", include_in_schema=False)
def parse_and_translate_iocs(
text: str = Body(..., description="Text to parse IOCs from", embed=True),
iocs_per_query: int = Body(25, description="Platforms to parse IOCs to", embed=True),
platform: CTIPlatform = Body(..., description="Platforms to parse IOCs to", embed=True),
iocs_per_query: int = Body(25, description="IOCs per query limit", embed=True),
platform: CTIPlatform = Body(..., description="Platform to parse IOCs to", embed=True),
include_ioc_types: Optional[list[IOCType]] = Body(
None, description="List of IOC types to include. By default all types are enabled.", embed=True
),
Expand All @@ -31,7 +31,7 @@ def parse_and_translate_iocs(
),
include_source_ip: Optional[bool] = Body(False, description="Include source IP in query. By default it is false."),
) -> OneTranslationCTIData:
status, translations = converter.convert(
status, translations = cti_translator.translate(
text=text,
platform_data=platform,
iocs_per_query=iocs_per_query,
Expand All @@ -42,7 +42,7 @@ def parse_and_translate_iocs(
include_source_ip=include_source_ip,
)
if status:
return OneTranslationCTIData(status=status, translations=translations, target_siem_type=platform.name)
return OneTranslationCTIData(status=status, translations=translations, target_platform_id=platform.id)

info_message = InfoMessage(message=translations, severity="error")
return OneTranslationCTIData(info=info_message, status=status, target_siem_type=platform.name)
return OneTranslationCTIData(info=info_message, status=status, target_platform_id=platform.id)
86 changes: 86 additions & 0 deletions uncoder-core/app/routers/translate.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
from fastapi import APIRouter, Body

from app.models.translation import InfoMessage, OneTranslationData, Platform, TranslatorPlatforms
from app.translator.cti_translator import CTITranslator
from app.translator.translator import Translator

st_router = APIRouter()

translator = Translator()


@st_router.post("/translate", tags=["translator"], description="Generate target translation")
@st_router.post("/translate/", include_in_schema=False)
def translate_one(
source_platform_id: str = Body(..., embed=True),
target_platform_id: str = Body(..., embed=True),
text: str = Body(..., embed=True),
) -> OneTranslationData:
status, data = translator.translate_one(text=text, source=source_platform_id, target=target_platform_id)
if status:
return OneTranslationData(status=status, translation=data, target_platform_id=target_platform_id)

info_message = InfoMessage(message=data, severity="error")
return OneTranslationData(info=info_message, status=status, target_platform_id=target_platform_id)


@st_router.post("/translate/all", tags=["translator"], description="Generate all translations")
@st_router.post("/translate/all/", include_in_schema=False)
def translate_all(
source_platform_id: str = Body(..., embed=True), text: str = Body(..., embed=True)
) -> list[OneTranslationData]:
result = translator.translate_all(text=text, source=source_platform_id)
translations = []
for platform_result in result:
if platform_result.get("status"):
translations.append(
OneTranslationData(
status=platform_result.get("status", True),
translation=platform_result.get("result"),
target_platform_id=platform_result.get("platform_id"),
)
)
else:
translations.append(
OneTranslationData(
status=platform_result.get("status", False),
info=InfoMessage(message=platform_result.get("result"), severity="error"),
target_platform_id=platform_result.get("platform_id"),
)
)
return translations


@st_router.get("/platforms", tags=["translator"], description="Get translator platforms")
@st_router.get("/platforms/", include_in_schema=False)
def get_translator_platforms() -> TranslatorPlatforms:
renders, parsers = translator.get_all_platforms()
return TranslatorPlatforms(renders=renders, parsers=parsers)


@st_router.get("/all_platforms", description="Get Sigma, RootA and iocs platforms")
@st_router.get("/all_platforms/", include_in_schema=False)
def get_all_platforms() -> list:
translator_renders, translator_parsers = translator.get_all_platforms()
return [
Platform(
id="roota",
name="RootA",
code="roota",
group_name="RootA",
group_id="roota",
renders=translator_renders,
parsers=translator_parsers,
),
Platform(
id="sigma",
name="Sigma",
code="sigma",
group_name="Sigma",
group_id="sigma",
renders=[render for render in translator_renders if render.code != "sigma"],
),
Platform(
id="ioc", name="IOCs", code="ioc", group_name="IOCs", group_id="ioc", renders=CTITranslator().get_renders()
),
]
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@ def __init__(self, platform_name: str, field_name: str):

class UnsupportedPlatform(BasePlatformException):
def __init__(self, platform: str, is_parser: bool = False):
converter_direction = "input" if is_parser else "output"
direction = "input" if is_parser else "output"
if platform:
message = (
f"The selected {converter_direction} language `{platform}` is not supported. "
f"The selected {direction} language `{platform}` is not supported. "
f"Please, select an option in the dropdown."
)
else:
message = f"Please, select an {converter_direction} language."
message = f"Please, select an {direction} language."
super().__init__(message)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ def __init__(self, platform_dir: str):
def prepare_mapping(self) -> dict[str, SourceMapping]:
source_mappings = {}
default_mapping = SourceMapping(source_id=DEFAULT_MAPPING_NAME)
for mapping_dict in self._loader.load_siem_mappings(self._platform_dir):
for mapping_dict in self._loader.load_platform_mappings(self._platform_dir):
log_source_signature = self.prepare_log_source_signature(mapping=mapping_dict)
if (source_id := mapping_dict["source"]) == DEFAULT_MAPPING_NAME:
default_mapping.log_source_signature = log_source_signature
Expand Down Expand Up @@ -131,7 +131,7 @@ def prepare_mapping(self) -> dict[str, SourceMapping]:
source_mappings = {}
common_field_mapping = self._loader.load_common_mapping(self._platform_dir).get("field_mapping", {})

for mapping_dict in self._loader.load_siem_mappings(self._platform_dir):
for mapping_dict in self._loader.load_platform_mappings(self._platform_dir):
source_id = mapping_dict["source"]
log_source_signature = self.prepare_log_source_signature(mapping=mapping_dict)
fields_mapping = self.prepare_fields_mapping(field_mapping=common_field_mapping)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

@dataclass
class PlatformDetails:
siem_type: str = ""
platform_id: str = ""
name: str = ""
platform_name: str = ""
group_id: Optional[str] = None
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,15 @@
from app.translator.const import CTI_IOCS_PER_QUERY_LIMIT, CTI_MIN_LIMIT_QUERY
from app.translator.core.models.iocs import IocsChunkValue
from app.translator.core.parser_cti import CTIParser
from app.translator.core.render_cti import RenderCTI
from app.translator.managers import RenderCTIManager, render_cti_manager
from app.translator.tools.decorators import handle_translation_exceptions


class CTIConverter:
class CTITranslator:
renders: RenderCTIManager = render_cti_manager

def __init__(self):
self.logger = logging.getLogger("cti_converter")
self.logger = logging.getLogger("cti_translator")
self.parser = CTIParser()

@handle_translation_exceptions
Expand All @@ -39,12 +38,14 @@ def __parse_iocs_from_string(

@handle_translation_exceptions
def __render_translation(self, parsed_data: dict, platform_data: CTIPlatform, iocs_per_query: int) -> list[str]:
platform = self.renders.get(platform_data.name)
return self.generate(
data=parsed_data, platform=platform, iocs_per_query=iocs_per_query, mapping=platform.default_mapping
render_cti = self.renders.get(platform_data.id)

chunked_iocs = self.__get_iocs_chunk(
chunks_size=iocs_per_query, data=parsed_data, mapping=render_cti.default_mapping
)
return render_cti.render(chunked_iocs)

def convert(
def translate(
self,
text: str,
platform_data: CTIPlatform,
Expand All @@ -70,7 +71,7 @@ def convert(
return status, parsed_data

@staticmethod
def _get_iocs_chunk(
def __get_iocs_chunk(
chunks_size: int, data: dict[str, list[str]], mapping: dict[str, str]
) -> list[list[IocsChunkValue]]:
result = []
Expand All @@ -82,12 +83,6 @@ def _get_iocs_chunk(
)
return [result[i : i + chunks_size] for i in range(0, len(result), chunks_size)]

def generate(
self, platform: RenderCTI, iocs_per_query: int, data: dict[str, list[str]], mapping: dict[str, str]
) -> list[str]:
chunked_iocs = self._get_iocs_chunk(chunks_size=iocs_per_query, data=data, mapping=mapping)
return platform.render(chunked_iocs)

@classmethod
def get_renders(cls) -> list:
return cls.renders.get_platforms_details
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