コード例 #1
0
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())
コード例 #2
0
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)
コード例 #3
0
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)
コード例 #4
0
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)
コード例 #5
0
ファイル: stixmarx-example.py プロジェクト: mitre/stix-edh
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)
コード例 #6
0
    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"])
コード例 #7
0
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)
コード例 #8
0
    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"])
コード例 #9
0
    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)
コード例 #10
0
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))