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
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