def test_multiple_file_observable_expression(observation_class, op):
    exp1 = stix2.EqualityComparisonExpression(
        "file:hashes.'SHA-256'",
        stix2.HashConstant(
            "bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c",
            'SHA-256',
        ),
    )
    exp2 = stix2.EqualityComparisonExpression(
        "file:hashes.MD5",
        stix2.HashConstant("cead3f77f6cda6ec00f57d76c9a6879f", "MD5"),
    )
    bool1_exp = stix2.OrBooleanExpression([exp1, exp2])
    exp3 = stix2.EqualityComparisonExpression(
        "file:hashes.'SHA-256'",
        stix2.HashConstant(
            "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f",
            'SHA-256',
        ),
    )
    op1_exp = stix2.ObservationExpression(bool1_exp)
    op2_exp = stix2.ObservationExpression(exp3)
    exp = observation_class([op1_exp, op2_exp])
    assert str(
        exp
    ) == "[file:hashes.'SHA-256' = 'bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c' OR file:hashes.MD5 = 'cead3f77f6cda6ec00f57d76c9a6879f'] {} [file:hashes.'SHA-256' = 'aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f']".format(
        op)  # noqa
Пример #2
0
def test_root_types():
    ast = stix2.ObservationExpression(
            stix2.AndBooleanExpression(
                [stix2.ParentheticalExpression(
                    stix2.OrBooleanExpression([
                        stix2.EqualityComparisonExpression("a:b", stix2.StringConstant("1")),
                        stix2.EqualityComparisonExpression("b:c", stix2.StringConstant("2"))])),
                 stix2.EqualityComparisonExpression(u"b:d", stix2.StringConstant("3"))]))
    assert str(ast) == "[(a:b = '1' OR b:c = '2') AND b:d = '3']"
    def __generate_complex_comparison_expression(self,
                                                 size,
                                                 type_constraint=None):
        """
        Generates a "complex" comparison expression, i.e. one which may consist
        of sub-expressions connected via AND or OR.  If a type constraint is
        given, the resulting expression will honor that constraint.

        :param size: The size of the desired complex comparison expression, in
            terms of the number of simple comparison expressions it must contain
        :param type_constraint: An SCO type, or None
        :return:
        """
        assert size > 0

        # This complex expression must be composed of N simple expressions.
        # This implementation builds the overall expression in two parts: a
        # left and right side.  The location of the split between left and
        # right is random.  A side is randomly chosen to just contain a series
        # of simple expressions, and the other side will have a nested
        # subexpression.
        #
        # One goal of the strategy is to avoid excessive nested parentheses.
        # Too many parentheses results in ugly crazy-looking patterns.  This
        # algorithm still can generate some silly patterns, but I hope it helps
        # a little.
        if size == 1:
            expr = self.__generate_simple_comparison_expression_list(
                1, type_constraint, False)[0]

        else:

            # Choose whether top-level operator will be AND or OR.
            # This will also determine how we handle the type constraint.
            is_and = random.random() < 0.5

            # If AND, all operands *must* be type-constrained.
            if is_and and not type_constraint:
                type_constraint = self.__random_sco_type()

            # In the following, if type_constraint is None, both left and right
            # constraints will be None.  No need for a special case.  If we
            # have a type constraint, for 'AND', the constraint must be
            # enforced on both sides.  For 'OR', we need only enforce it on one
            # side.
            if is_and:
                left_constraint = right_constraint = type_constraint
            else:
                left_constraint, right_constraint = type_constraint, None
                if random.random() < 0.5:
                    left_constraint, right_constraint = \
                        right_constraint, left_constraint

            # Don't let either side be zero size here.  Avoids the case where
            # we have an OR, and randomly choose to enforce the type constraint
            # on the zero-length side.  That can result in an invalid pattern.
            lsize = random.randint(1, size - 1)
            rsize = size - lsize

            if random.random() < 0.5:
                # Parenthesize right case
                operands = self.__generate_simple_comparison_expression_list(
                    lsize, left_constraint, is_and)

                operands.append(
                    stix2.ParentheticalExpression(
                        self.__generate_complex_comparison_expression(
                            rsize, right_constraint)))

            else:
                # Parenthesize left case
                operands = [
                    stix2.ParentheticalExpression(
                        self.__generate_complex_comparison_expression(
                            lsize, left_constraint))
                ]

                operands.extend(
                    self.__generate_simple_comparison_expression_list(
                        rsize, right_constraint, is_and))

            if is_and:
                expr = stix2.AndBooleanExpression(operands)
            else:
                expr = stix2.OrBooleanExpression(operands)

        return expr