def main(): # Parse the input into a MarkingContainer container = stixmarx.parse("stix-document.xml") # Get container package package = container.package # Get the markings that apply to the entire XML document global_markings = container.get_markings(package) # Print the dictionary representation for our only global marking marking = global_markings[0] pprint.pprint(marking.to_dict()) # Get our only indicator from the STIX Package indicator = package.indicators[0] # Get the markings from the Indicator. # Note: This will include the global markings and any other markings # applied by an ancestor! indicator_markings = container.get_markings(indicator) # Print the Indicator markings! for marking in indicator_markings: pprint.pprint(marking.to_dict())
def elevate_string(string): global MESSAGES_GENERATED clear_id_mapping() clear_1x_markings_map() clear_pattern_cache() clear_object_id_mapping() clear_observable_mappings() cybox.utils.caches.cache_clear() MESSAGES_GENERATED = False validator_options = get_validator_options() try: output.set_level(validator_options.verbose) output.set_silent(validator_options.silent) io = StringIO(string) container = stixmarx.parse(io) stix_package = container.package set_option_value("marking_container", container) if not isinstance(stix_package, STIXPackage): raise TypeError("Must be an instance of stix.core.STIXPackage") setup_logger(stix_package.id_) warn( "Results produced by the stix2-elevator are not for production purposes.", 201) if get_option_value("default_timestamp"): timestamp = datetime.strptime( get_option_value("default_timestamp"), "%Y-%m-%dT%H:%M:%S.%fZ"), else: timestamp = None env = Environment(get_option_value("package_created_by_id"), timestamp) json_string = json.dumps(convert_package(stix_package, env), ensure_ascii=False, indent=4, separators=(',', ': '), sort_keys=True) validation_results = validate_stix2_string(json_string, validator_options) output.print_results([validation_results]) if get_option_value("policy") == "no_policy": return json_string else: if not MESSAGES_GENERATED and validation_results._is_valid: return json_string else: return None except ValidationError as ex: output.error("Validation error occurred: '%s'" % ex, codes.EXIT_VALIDATION_ERROR) except OSError as ex: log.error(ex)
def elevate_file(fn): # TODO: combine elevate_file, elevate_string and elevate_package warnings.warn( "This method is deprecated and will be removed in the next major release. Please use elevate() instead.", DeprecationWarning) global MESSAGES_GENERATED MESSAGES_GENERATED = False print( "Results produced by the stix2-elevator are not for production purposes." ) clear_globals() validator_options = get_validator_options() try: output.set_level(validator_options.verbose) output.set_silent(validator_options.silent) if os.path.isfile(fn) is False: raise IOError("The file '{}' was not found.".format(fn)) container = stixmarx.parse(fn) stix_package = container.package set_option_value("marking_container", container) if not isinstance(stix_package, STIXPackage): raise TypeError("Must be an instance of stix.core.STIXPackage") setup_logger(stix_package.id_) warn( "Results produced by the stix2-elevator may generate warning messages which should be investigated.", 201) env = Environment(get_option_value("package_created_by_id")) json_string = json.dumps(convert_package(stix_package, env), ensure_ascii=False, indent=4, separators=(',', ': '), sort_keys=True) validation_results = validate_stix2_string(json_string, validator_options, fn) output.print_results([validation_results]) if get_option_value("policy") == "no_policy": return json_string else: if not MESSAGES_GENERATED and validation_results._is_valid: return json_string else: return None except ValidationError as ex: output.error("Validation error occurred: '{}'".format(ex)) output.error("Error Code: {}".format(codes.EXIT_VALIDATION_ERROR)) except (OSError, IOError, lxml.etree.Error) as ex: log.error("Error occurred: %s", ex)
def elevate_file(fn): # TODO: combine elevate_file, elevate_string and elevate_package global MESSAGES_GENERATED print( "Results produced by the stix2-elevator are not for production purposes." ) clear_id_mapping() clear_1x_markings_map() clear_pattern_cache() clear_object_id_mapping() clear_observable_mappings() MESSAGES_GENERATED = False validator_options = get_validator_options() try: output.set_level(validator_options.verbose) output.set_silent(validator_options.silent) container = stixmarx.parse(fn) stix_package = container.package set_option_value("marking_container", container) if not isinstance(stix_package, STIXPackage): raise TypeError("Must be an instance of stix.core.STIXPackage") setup_logger(stix_package.id_) warn( "Results produced by the stix2-elevator are not for production purposes.", 201) json_string = json.dumps(convert_package( stix_package, get_option_value("package_created_by_id"), get_option_value("default_timestamp")), indent=4, separators=(',', ': '), sort_keys=True) if get_option_value("policy") == "no_policy": return json_string else: validation_results = validate_string(json_string, validator_options) output.print_results(validation_results) if not MESSAGES_GENERATED and validation_results._is_valid: return json_string else: return None except ValidationError as ex: output.error("Validation error occurred: '%s'" % ex, codes.EXIT_VALIDATION_ERROR) except OSError as ex: log.error(ex)
def main(): container = stixmarx.parse(FILE_REVOKED) global_markings = container.global_markings for marking in global_markings: print(marking.to_dict()) for indicator in container.package.indicators: # Get markings from Indicator or any descendants. markings = container.get_markings(indicator, descendants=True) print(indicator.id_, len(markings)) print(markings)
def test_marking_path_parsing_for_observable(self): """Test that parsed paths are applied correctly to Observable""" # paths to attempt for a component RED marking observable_xpaths = [{ "path": "../../../indicator:Observable[1]/descendant-or-self::node() | ../../../indicator:Observable[1]/descendant-or-self::node()/@*", "should_pass": True }, { "path": "this is not a real xpath", "should_pass": False }] # paths to attempt for a component AMBER marking component_xpaths = [{ "path": "../../../descendant-or-self::node() | ../../../descendant-or-self::node()/@*", "should_pass": True }, { "path": "this is not a real xpath", "should_pass": False }] for observable_path_dict in observable_xpaths: for component_path_dict in component_xpaths: # Format our STIX XML template xml = STIX_XML_TEMPLATE_EMBEDDED_OBSERVABLE.format( observable_path_dict["path"], component_path_dict["path"]) xml_readable = StringIO(xml) # Build and parse the MarkingContainer try: container = stixmarx.parse(xml_readable) except etree.XPathEvalError: self.assertTrue( observable_path_dict["should_pass"] is False or component_path_dict["should_pass"] is False) continue package = container.package colors = [ marking_spec.marking_structures[0].color for marking_spec in container.get_markings(package.indicators[0].observable) ] self.assertTrue( ('RED' in colors) == observable_path_dict["should_pass"]) self.assertTrue( ('AMBER' in colors) == component_path_dict["should_pass"])
def test_elevate_with_marking_container(): setup_options() directory = os.path.dirname(__file__) xml_idioms_dir = find_dir(directory, "idioms-xml") archive_file = os.path.join(xml_idioms_dir, "141-TLP-marking-structures.xml") with io.open(archive_file, mode="r", encoding="utf-8") as f: input_stix = f.read() container = stixmarx.parse(StringIO(input_stix)) json_result = elevate(container) assert json_result print(json_result)
def test_marking_path_parsing(self): """Test that parsed paths are applied correctly""" # paths to attempt for a global AMBER marking global_xpaths = [{ "path": "//node() | //@*", "should_pass": True }, { "path": "this is not a real xpath", "should_pass": False }] # paths to attempt for a local RED marking local_xpaths = [{ "path": "../../../descendant-or-self::node() | ../../../descendant-or-self::node()/@*", "should_pass": True }, { "path": "this is not a real xpath", "should_pass": False }] for global_path_dict in global_xpaths: for local_path_dict in local_xpaths: # Format our STIX XML template xml = STIX_XML_TEMPLATE_GLOBAL_AND_COMPONENT.format( global_path_dict["path"], local_path_dict["path"]) xml_readable = StringIO(xml) # Build and parse the MarkingContainer try: container = stixmarx.parse(xml_readable) except etree.XPathEvalError: self.assertTrue(global_path_dict["should_pass"] is False or local_path_dict["should_pass"] is False) continue package = container.package colors = [ marking_spec.marking_structures[0].color for marking_spec in container.get_markings(package.indicators[0]) ] self.assertTrue( ('AMBER' in colors) == global_path_dict["should_pass"]) self.assertTrue( ('RED' in colors) == local_path_dict["should_pass"])
def test_marking_round_trip(self): """Test that get_markings() yields the same number of results after calling to_xml().""" container = stixmarx.new() package = container.package red_marking = generate_marking_spec(generate_red_marking_struct()) amber_marking = generate_marking_spec(generate_amber_marking_struct()) incident = Incident(title="Test Incident") package.add_incident(incident) indicator = Indicator(idref="example:Indicator-test-1234") incident.related_indicators.append(indicator) container.add_marking(incident, red_marking, descendants=True) container.add_global(amber_marking) self.assertTrue(container.is_marked(indicator, red_marking)) self.assertTrue(container.is_marked(indicator, amber_marking)) markings = container.get_markings(indicator) self.assertEqual(len(markings), 2) xml = container.to_xml() sio = StringIO(xml.decode("utf-8")) new_xml_container = stixmarx.parse(sio) parsed_indicator = new_xml_container.package.incidents[ 0].related_indicators[0] parsed_markings = new_xml_container.get_markings(parsed_indicator) for x in parsed_markings: print(x.to_dict()) self.assertEqual(len(parsed_markings), 2)
def elevate(stix_package): global MESSAGES_GENERATED MESSAGES_GENERATED = False print("Results produced by the stix2-elevator are not for production purposes.") clear_globals() fn = None validator_options = get_validator_options() output.set_level(validator_options.verbose) output.set_silent(validator_options.silent) try: if isinstance(stix_package, MarkingContainer): # No need to re-parse the MarkingContainer. container = stix_package elif isinstance(stix_package, STIXPackage): io = BytesIO(stix_package.to_xml()) container = stixmarx.parse(io) elif isinstance(stix_package, text_type): if stix_package.endswith(".xml") or os.path.isfile(stix_package): # a path-like string was passed fn = stix_package if os.path.exists(fn) is False: raise IOError("The file '{}' was not found.".format(fn)) else: stix_package = StringIO(stix_package) container = stixmarx.parse(stix_package) elif isinstance(stix_package, binary_type): if stix_package.endswith(b".xml") or os.path.isfile(stix_package): # a path-like string was passed fn = stix_package if os.path.exists(fn) is False: raise IOError("The file '{}' was not found.".format(fn)) else: stix_package = BytesIO(stix_package) container = stixmarx.parse(stix_package) else: raise RuntimeError("Unable to resolve object {} of type {}".format(stix_package, type(stix_package))) container_package = container.package set_option_value("marking_container", container) if not isinstance(container_package, STIXPackage): raise TypeError("Must be an instance of stix.core.STIXPackage") except (OSError, IOError, lxml.etree.Error) as ex: log.error("Error occurred: %s", ex) # log.exception(ex) return None try: setup_logger(container_package.id_) warn("Results produced by the stix2-elevator may generate warning messages which should be investigated.", 201) env = Environment(get_option_value("package_created_by_id")) json_string = json.dumps( convert_package(container_package, env), ensure_ascii=False, indent=4, separators=(',', ': '), sort_keys=True ) bundle_id = re.findall( r"bundle--[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}", json_string ) validation_results = validate_stix2_string(json_string, validator_options, fn or bundle_id[0]) output.print_results([validation_results]) if get_option_value("policy") == "no_policy": return json_string else: if not MESSAGES_GENERATED and validation_results._is_valid: return json_string except ValidationError as ex: output.error("Validation error occurred: '{}'".format(ex)) output.error("Error Code: {}".format(codes.EXIT_VALIDATION_ERROR))