Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:MISP/misp-stix
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisr3d committed Jul 20, 2023
2 parents 0eab3e5 + 32858de commit 82c2ef3
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 22 deletions.
4 changes: 2 additions & 2 deletions misp_stix_converter/misp2stix/misp_to_stix1.py
Original file line number Diff line number Diff line change
Expand Up @@ -1586,7 +1586,7 @@ def _parse_domain_ip_object(self, misp_object: dict) -> Observable:
observable_composition = self._create_observable_composition(
observables,
misp_object['uuid'],
name=misp_object['name']
name=misp_object['name'].replace('|', '-')
)
return observable_composition

Expand Down Expand Up @@ -1730,7 +1730,7 @@ def _parse_ip_port_object(self, misp_object: dict) -> Observable:
observable_composition = self._create_observable_composition(
observables,
misp_object['uuid'],
name=misp_object['name']
name=misp_object['name'].replace('|', '-')
)
return observable_composition

Expand Down
2 changes: 1 addition & 1 deletion misp_stix_converter/misp2stix/misp_to_stix2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2898,7 +2898,7 @@ def _create_labels(attribute: Union[MISPAttribute, dict]) -> list:
@staticmethod
def _create_object_labels(misp_object: Union[MISPObject, dict], to_ids: Optional[bool] = None) -> list:
labels = [
f'misp:name="{misp_object["name"]}"',
f'misp:name="{misp_object["name"].replace("|", "-")}"',
f'misp:meta-category="{misp_object["meta-category"]}"'
]
if to_ids is not None:
Expand Down
2 changes: 2 additions & 0 deletions misp_stix_converter/misp2stix/stix1_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -403,9 +403,11 @@ class MISPtoSTIX1Mapping(MISPtoSTIXMapping):
"asn": '_parse_asn_object',
"credential": '_parse_credential_object',
"domain-ip": '_parse_domain_ip_object',
"domain|ip": '_parse_domain_ip_object',
"email": '_parse_email_object',
"file": '_parse_file_object',
"ip-port": '_parse_ip_port_object',
"ip|port": '_parse_ip_port_object',
"mutex": "_parse_mutex_object",
"network-connection": '_parse_network_connection_object',
"network-socket": '_parse_network_socket_object',
Expand Down
2 changes: 2 additions & 0 deletions misp_stix_converter/misp2stix/stix2_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ class MISPtoSTIX2Mapping(MISPtoSTIXMapping):
'cpe-asset': '_parse_cpe_asset_object',
'credential': '_parse_credential_object',
'domain-ip': '_parse_domain_ip_object',
'domain|ip': '_parse_domain_ip_object',
'email': '_parse_email_object',
'employee': '_parse_employee_object',
'facebook-account': '_parse_account_object_with_attachment',
Expand All @@ -281,6 +282,7 @@ class MISPtoSTIX2Mapping(MISPtoSTIXMapping):
'identity': '_parse_identity_object',
'image': '_parse_image_object',
'ip-port': '_parse_ip_port_object',
'ip|port': '_parse_ip_port_object',
'legal-entity': '_parse_legal_entity_object',
'lnk': '_parse_lnk_object',
'mutex': '_parse_mutex_object',
Expand Down
3 changes: 2 additions & 1 deletion misp_stix_converter/misp_stix_converter.py
Original file line number Diff line number Diff line change
Expand Up @@ -1009,7 +1009,8 @@ def _stix_to_misp(stix_args):
single_event=stix_args.single_output
)
if traceback.pop('success', 0) == 1:
results.update(traceback)
for key, value in traceback.items():
results[key].extend(value)
continue
results['fails'].extend(traceback['errors'])
return results
Expand Down
80 changes: 68 additions & 12 deletions misp_stix_converter/stix2misp/importparser.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@
Indicator_v20,
Indicator_v21
]
_ROOT_PATH = Path(__file__).parents[1].resolve()
_DATA_PATH = Path(__file__).parents[1].resolve() / 'data'

_VALID_DISTRIBUTIONS = (0, 1, 2, 3, 4)
_RFC_VERSIONS = (1, 3, 4, 5)
_UUIDv4 = UUID('76beed5f-7251-457e-8c2a-b45f7b589d3d')

Expand All @@ -30,18 +31,53 @@ def __init__(self, distribution: int, sharing_group_id: Union[int, None],
galaxies_as_tags: bool):
self._identifier: str
self._clusters: dict = {}
self.__distribution = distribution
self.__sharing_group_id = sharing_group_id
if galaxies_as_tags:
self.__errors: defaultdict = defaultdict(set)
self.__warnings: defaultdict = defaultdict(set)
self.__distribution = self._sanitise_distribution(distribution)
self.__sharing_group_id = self._sanitise_sharing_group_id(
sharing_group_id
)
self.__galaxies_as_tags = self._sanitise_galaxies_as_tags(
galaxies_as_tags
)
if self.galaxies_as_tags:
self.__galaxy_feature = 'as_tag_names'
self.__synonyms_path = _ROOT_PATH / 'data' / 'synonymsToTagNames.json'
self.__synonyms_path = _DATA_PATH / 'synonymsToTagNames.json'
else:
self._galaxies: dict = {}
self.__galaxy_feature = 'as_container'
self.__galaxies_as_tags = galaxies_as_tags
self.__replacement_uuids: dict = {}
self.__errors: defaultdict = defaultdict(set)
self.__warnings: defaultdict = defaultdict(set)

def _sanitise_distribution(self, distribution: int) -> int:
try:
sanitised = int(distribution)
except (TypeError, ValueError) as error:
self._distribution_error(error)
return 0
if sanitised in _VALID_DISTRIBUTIONS:
return sanitised
self._distribution_value_error(sanitised)
return 0

def _sanitise_galaxies_as_tags(self, galaxies_as_tags: bool):
if isinstance(galaxies_as_tags, bool):
return galaxies_as_tags
if galaxies_as_tags in ('true', 'True', '1', 1):
return True
if galaxies_as_tags in ('false', 'False', '0', 0):
return False
self._galaxies_as_tags_error(galaxies_as_tags)
return False

def _sanitise_sharing_group_id(
self, sharing_group_id: Union[int, None]) -> Union[int, None]:
if sharing_group_id is None:
return None
try:
return int(sharing_group_id)
except (TypeError, ValueError) as error:
self._sharing_group_id_error(error)
return None

################################################################################
# PROPERTIES #
Expand Down Expand Up @@ -115,6 +151,21 @@ def _critical_error(self, exception: Exception):
f'The Following exception was raised: {exception}'
)

def _distribution_error(self, exception: Exception):
self.__errors['init'].add(
f'Wrong distribution format: {exception}'
)

def _distribution_value_error(self, distribution: int):
self.__errors['init'].add(
f'Invalid distribution value: {distribution}'
)

def _galaxies_as_tags_error(self, galaxies_as_tags):
self.__errors['init'].add(
f'Invalid galaxies_as_tags flag: {galaxies_as_tags} (bool expected)'
)

def _identity_error(self, identity_id: str, exception: Exception):
tb = self._parse_traceback(exception)
self.__errors[self._identifier].add(
Expand Down Expand Up @@ -181,6 +232,11 @@ def _parse_traceback(exception: Exception) -> str:
tb = ''.join(traceback.format_tb(exception.__traceback__))
return f'{tb}{exception.__str__()}'

def _sharing_group_id_error(self, exception: Exception):
self.__errors['init'].add(
f'Wrong sharing group id format: {exception}'
)

def _threat_actor_error(self, threat_actor_id: str, exception: Exception):
self.__errors[self._identifier].add(
f'Error with the Threat Actor object with id {threat_actor_id}'
Expand Down Expand Up @@ -272,7 +328,7 @@ def _vulnerability_error(self, vulnerability_id: str, exception: Exception):
################################################################################

def __galaxies_up_to_date(self) -> bool:
fingerprint_path = _ROOT_PATH / 'data' / 'synonymsToTagNames.fingerprint'
fingerprint_path = _DATA_PATH / 'synonymsToTagNames.fingerprint'
if not fingerprint_path.exists():
return False
latest_fingerprint = self.__get_misp_galaxy_fingerprint()
Expand All @@ -283,7 +339,7 @@ def __galaxies_up_to_date(self) -> bool:
return fingerprint == latest_fingerprint

def __generate_synonyms_mapping(self):
data_path = _ROOT_PATH / 'data' / 'misp-galaxy' / 'clusters'
data_path = _DATA_PATH / 'misp-galaxy' / 'clusters'
if not data_path.exists():
raise UnavailableGalaxyResourcesError(data_path)
synonyms_mapping = defaultdict(list)
Expand All @@ -302,13 +358,13 @@ def __generate_synonyms_mapping(self):
f.write(json.dumps(synonyms_mapping))
latest_fingerprint = self.__get_misp_galaxy_fingerprint()
if latest_fingerprint is not None:
fingerprint_path = _ROOT_PATH / 'data' / 'synonymsToTagNames.fingerprint'
fingerprint_path = _DATA_PATH / 'synonymsToTagNames.fingerprint'
with open(fingerprint_path, 'wt', encoding='utf-8') as f:
f.write(latest_fingerprint)

@staticmethod
def __get_misp_galaxy_fingerprint():
galaxy_path = _ROOT_PATH / 'data' / 'misp-galaxy'
galaxy_path = _DATA_PATH / 'misp-galaxy'
status = subprocess.Popen(
[
'git',
Expand Down
1 change: 1 addition & 0 deletions misp_stix_converter/stix2misp/internal_stix2_mapping.py
Original file line number Diff line number Diff line change
Expand Up @@ -772,6 +772,7 @@ class InternalSTIX2toMISPMapping(STIX2toMISPMapping):
name = STIX2toMISPMapping.name_attribute(),
description = STIX2toMISPMapping.description_attribute(),
roles = __role_attribute,
sectors = {'type': 'text', 'object_relation': 'sector'},
x_misp_role = __role_attribute,
x_misp_alias = __alias_attribute,
x_misp_date_of_inception = {
Expand Down
25 changes: 19 additions & 6 deletions misp_stix_converter/stix2misp/internal_stix2_to_misp.py
Original file line number Diff line number Diff line change
Expand Up @@ -556,14 +556,27 @@ def _parse_identity_object(
mapping = getattr(
self._mapping, f'{feature}_contact_information_mapping'
)
contact_information = []
for contact_info in identity.contact_information.split(' / '):
object_relation, value = contact_info.split(': ')
if ': ' in contact_info:
try:
object_relation, value = contact_info.split(': ')
except ValueError:
contact_information.append(contact_info)
continue
attribute = mapping(object_relation)
if attribute is not None:
misp_object.add_attribute(
**{
'object_relation': object_relation,
'value': value, **attribute
}
)
continue
contact_information.append(contact_info)
if contact_information:
misp_object.add_attribute(
**{
'object_relation': object_relation,
'value': value,
**mapping(object_relation)
}
'contact_information', '; '.join(contact_information)
)
return misp_object

Expand Down

0 comments on commit 82c2ef3

Please sign in to comment.