Skip to content

Commit 35587fa

Browse files
committed
IOC`s fix mapping and hash types
1 parent c6cbbe7 commit 35587fa

File tree

6 files changed

+46
-58
lines changed

6 files changed

+46
-58
lines changed
Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
DEFAULT_GRAYLOG_MAPPING = {
2-
"SourceIP": "sourceAddress",
3-
"DestinationIP": "destinationAddress",
4-
"Domain": "destinationDnsDomain",
5-
"URL": "requestUrl",
6-
"HashMd5": "fileHash",
7-
"HashSha1": "fileHash",
8-
"HashSha256": "fileHash",
9-
"HashSha512": "fileHash",
2+
"SourceIP": "source.ip",
3+
"DestinationIP": "destination.ip",
4+
"Domain": "destination.domain",
5+
"URL": "url.original",
6+
"HashMd5": "file.hash.md5",
7+
"HashSha1": "file.hash.sha1",
8+
"HashSha256": "file.hash.sha256",
9+
"HashSha512": "file.hash.sha512",
1010
"Emails": "emails",
1111
"Files": "filePath"
1212
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
DEFAULT_MICROSOFT_SENTINEL_MAPPING = {
2-
"DestinationIP": "DestinationIP",
2+
"DestinationIP": "DestinationIp",
33
"SourceIP": "SourceIp",
44
"HashSha512": "FileHashSha512",
55
"HashSha256": "FileHashSha256",
66
"HashMd5": "FileHashMd5",
77
"Emails": "SenderFromAddress",
88
"Domain": "DestinationHostname",
99
"HashSha1": "FileHashSha1",
10-
"Files": "FileName",
10+
"Files": "TargetFileName",
1111
"URL": "URL"
1212
}

siem-converter/app/converter/core/parser_cti.py

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,29 @@
55
from pydantic import BaseModel
66

77
from app.converter.core.exceptions.iocs import IocsLimitExceededException, EmptyIOCSException
8-
from app.converter.tools.const import IP_IOC_REGEXP_PATTERN, DOMAIN_IOC_REGEXP_PATTERN, URL_IOC_REGEXP_PATTERN,\
9-
hash_regexes, IOCType, HashType, IocParsingRule
8+
from app.converter.tools.const import IP_IOC_REGEXP_PATTERN, DOMAIN_IOC_REGEXP_PATTERN, URL_IOC_REGEXP_PATTERN, \
9+
hash_regexes, IOCType, HashType, IocParsingRule, HASH_MAP
1010

1111

1212
class Iocs(BaseModel):
1313
ip: list[str] = []
1414
url: list[str] = []
1515
domain: list[str] = []
16-
hash: list[str] = []
16+
hash_dict: dict = {}
1717

1818
def get_total_count(self) -> int:
19-
return len(self.ip) + len(self.url) + len(self.domain) + len(self.hash)
19+
hash_len = 0
20+
for value in self.hash_dict.values():
21+
hash_len += len(value)
22+
return len(self.ip) + len(self.url) + len(self.domain) + hash_len
2023

2124
def return_iocs(self) -> dict:
22-
if all(not value for value in [self.ip, self.url, self.domain, self.hash]):
25+
if all(not value for value in [self.ip, self.url, self.domain, self.hash_dict]):
2326
raise EmptyIOCSException()
24-
return {"ip": self.ip, "url": self.url, "domain": self.domain, "hash": self.hash}
27+
result = {"DestinationIP": self.ip, "URL": self.url, "Domain": self.domain}
28+
for key, value in self.hash_dict.items():
29+
result[HASH_MAP[key]] = value
30+
return result
2531

2632

2733
class CTIParser:
@@ -47,7 +53,7 @@ def get_iocs_from_string(
4753
if not include_hash_types:
4854
include_hash_types = list(hash_regexes.keys())
4955
for hash_type in include_hash_types:
50-
iocs.hash.extend(self._find_all_str_by_regex(string, hash_regexes[hash_type]))
56+
iocs.hash_dict[hash_type] = self._find_all_str_by_regex(string, hash_regexes[hash_type])
5157
iocs = self.remove_duplicates(iocs)
5258
iocs = self.remove_exceptions(iocs, exceptions)
5359
if ioc_parsing_rules is None or "remove_private_and_reserved_ips" in ioc_parsing_rules:
@@ -69,14 +75,16 @@ def remove_duplicates(self, iocs):
6975
iocs.ip = self._remove_duplicates_from_list(iocs.ip)
7076
iocs.domain = self._remove_duplicates_from_list(iocs.domain)
7177
iocs.url = self._remove_duplicates_from_list(iocs.url)
72-
iocs.hash = self._remove_duplicates_from_list(iocs.hash)
78+
for key, value in iocs.hash_dict.items():
79+
iocs.hash_dict[key] = self._remove_duplicates_from_list(value)
7380
return iocs
7481

7582
def remove_exceptions(self, iocs, exceptions=None):
7683
iocs.ip = self._remove_exceptions(iocs.ip, exceptions)
7784
iocs.domain = self._remove_exceptions(iocs.domain, exceptions)
7885
iocs.url = self._remove_exceptions(iocs.url, exceptions)
79-
iocs.hash = self._remove_exceptions(iocs.hash, exceptions)
86+
for key, value in iocs.hash_dict.items():
87+
iocs.hash_dict[key] = self._remove_exceptions(value, exceptions)
8088
return iocs
8189

8290
@staticmethod

siem-converter/app/converter/core/render_cti.py

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,6 @@ class RenderCTI:
3434
final_result_for_one: str = "union * | where {result}\n"
3535
default_mapping = None
3636

37-
def get_default_mapping(self, include_source_ip=False):
38-
return self.prepare_mapping(self.default_mapping, include_source_ip)
39-
4037
def create_field_value(self, field: str, value: str, generic_field: str):
4138
return self.data_map.format(key=field, value=value)
4239

@@ -53,35 +50,17 @@ def render(self, data: List[List[IocsChunkValue]]) -> list[str]:
5350
def collect_data_values(self, chunk):
5451
data_values = []
5552
key_chunk = []
56-
processing_key = chunk[0].generic_field
53+
processing_key = chunk[0].platform_field
5754
for value in chunk:
58-
if processing_key != value.generic_field:
55+
if processing_key != value.platform_field:
5956
data_values.append(self.or_group.format(or_group=self.or_operator.join(key_chunk),
6057
processing_key=processing_key))
6158
key_chunk = []
62-
processing_key = value.generic_field
63-
key_chunk.append(self.create_field_value(field=value.generic_field,
59+
processing_key = value.platform_field
60+
key_chunk.append(self.create_field_value(field=value.platform_field,
6461
value=value.value,
6562
generic_field=value.generic_field))
6663
if key_chunk:
6764
data_values.append(
6865
self.or_group.format(or_group=self.or_operator.join(key_chunk), processing_key=processing_key))
6966
return data_values
70-
71-
def prepare_mapping(self, mapping: dict, include_source_ip: bool = False) -> dict:
72-
m = {
73-
"DestinationIP": "ip",
74-
"Domain": "domain",
75-
"URL": "url",
76-
"HashMd5": "hash",
77-
"HashSha1": "hash",
78-
"HashSha256": "hash",
79-
"HashSha512": "hash",
80-
}
81-
if include_source_ip:
82-
m["SourceIP"] = "ip"
83-
res = {}
84-
for key, new_field_name in mapping.items():
85-
if key in m:
86-
res[new_field_name] = m[key]
87-
return res

siem-converter/app/converter/cti_converter.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,14 +17,8 @@ def __init__(self):
1717
self.logger = logging.getLogger("cti_converter")
1818
self.parser = CTIParser()
1919

20-
def _reverse_mapping(self, platform: CTIPlatform, data: Dict[str, List[str]],
21-
include_source_ip: bool = False) -> Dict[str, str]:
22-
mapping: Dict = self.renders.get(platform.name).get_default_mapping(include_source_ip)
23-
reverse_mapping = {}
24-
for platform_field, generic_field in mapping.items():
25-
if data.get(generic_field):
26-
reverse_mapping.update({generic_field: platform_field})
27-
return reverse_mapping
20+
def _get_render_mapping(self, platform: CTIPlatform, include_source_ip: bool = False) -> Dict[str, str]:
21+
return self.renders.get(platform.name).default_mapping
2822

2923
@handle_translation_exceptions
3024
def __parse_iocs_from_string(self, text: str, include_ioc_types: list = None, include_hash_types: list = None,
@@ -39,11 +33,10 @@ def __parse_iocs_from_string(self, text: str, include_ioc_types: list = None, in
3933
@handle_translation_exceptions
4034
def __render_translation(self, parsed_data: dict, platform_data: CTIPlatform, iocs_per_query: int,
4135
include_source_ip: bool = False) -> List[str]:
42-
reverse_mapping = self._reverse_mapping(data=parsed_data,
43-
include_source_ip=include_source_ip, platform=platform_data)
36+
mapping = self._get_render_mapping(platform=platform_data, include_source_ip=include_source_ip)
4437
platform = self.renders.get(platform_data.name)
4538
platform_generation = self.generate(data=parsed_data, platform=platform, iocs_per_query=iocs_per_query,
46-
mapping=reverse_mapping)
39+
mapping=mapping)
4740
return platform_generation
4841

4942
def convert(self, text: str,
@@ -73,9 +66,10 @@ def _get_iocs_chunk(chunks_size: int, data: Dict[str, List[str]],
7366
result = []
7467
for generic_field, iocs_list in data.items():
7568
for ioc in iocs_list:
76-
result.append(IocsChunkValue(generic_field=generic_field,
77-
platform_field=mapping.get(generic_field, generic_field),
78-
value=ioc))
69+
if mapping.get(generic_field):
70+
result.append(IocsChunkValue(generic_field=generic_field,
71+
platform_field=mapping[generic_field],
72+
value=ioc))
7973
return [result[i:i + chunks_size] for i in range(0, len(result), chunks_size)]
8074

8175
def generate(self, platform: RenderCTI, iocs_per_query, data: Dict[str, List[str]],

siem-converter/app/converter/tools/const.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,13 @@
1010
"replace_dots", "remove_private_and_reserved_ips", "replace_hxxp"
1111
]
1212

13+
HASH_MAP = {
14+
"md5": "HashMd5",
15+
"sha1": "HashSha1",
16+
"sha256": "HashSha256",
17+
"sha512": "HashSha512"
18+
}
19+
1320
hash_regexes = {
1421
"md5": r"(?:^|[\s\/\[(\"',;{>|])([A-Fa-f0-9]{32})(?=[\s)\]\"',;\n<|]|$)",
1522
"sha1": r"(?:^|[\s\/\[(\"',;{>|])([A-Fa-f0-9]{40})(?=[\s)\]\"',;\n<|]|$)",

0 commit comments

Comments
 (0)
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