async def transform_context(sighting: Sighting, transform_cmd: str) -> Sighting: """ Transforms the context of a sighting using the command configured in `transform_context` @param sighting the sighting as it was reported by VAST @param transform_cmd The command to use to pipe sightings to. Treated as template string: occurrences of '%ioc' in the cmd string get replaced with the matched IoC. @return a copy of the original sighting with the x_threatbus_context field set and transformed accordingly """ context = ( sighting.x_threatbus_sighting_context if ThreatBusSTIX2Constants.X_THREATBUS_SIGHTING_CONTEXT.value in sighting.object_properties() else None ) if not context: logger.error( f"Cannot invoke `transform_context` command because no context data is found in the sighting {sighting}" ) return indicator = ( sighting.x_threatbus_indicator if ThreatBusSTIX2Constants.X_THREATBUS_INDICATOR.value in sighting.object_properties() else None ) if indicator: _, ioc_value = split_object_path_and_value(indicator.pattern) else: # try to find the indicator value instead ioc_value = ( sighting.x_threatbus_indicator_value if ThreatBusSTIX2Constants.X_THREATBUS_INDICATOR_VALUE.value in sighting.object_properties() else None ) if not ioc_value: logger.error( f"Cannot invoke `transform_context` command because no indicator value is found in the sighting {sighting}" ) return transformed_context_raw = await invoke_cmd_for_context( transform_cmd, context, ioc_value ) try: transformed_context = json.loads(transformed_context_raw) # recreate the sighting with the new transformed context ser = json.loads(sighting.serialize()) ser[ ThreatBusSTIX2Constants.X_THREATBUS_SIGHTING_CONTEXT.value ] = transformed_context return parse(json.dumps(ser), allow_custom=True) except Exception as e: logger.error( f"Cannot parse transformed sighting context (expecting JSON): {transformed_context_raw}", e, )
def stix2_sighting_to_misp(sighting: Sighting): """ Maps the STIX-2 sighting format to a MISP sighting. @param sighting A STIX-2 Sighting object @return the mapped MISP sighting object or None """ if not sighting or type(sighting) != Sighting: return None misp_sighting = pymisp.MISPSighting() source = None if "x_threatbus_source" in sighting.object_properties(): source = str(sighting.x_threatbus_source) misp_sighting.from_dict( id=misp_id(sighting.sighting_of_ref), source=source, type="0", # true positive sighting: https://www.misp-standard.org/rfc/misp-standard-core.html#sighting timestamp=sighting.created, ) return misp_sighting