def test_multiple_qualifiers(): exp_and = stix2.AndBooleanExpression([stix2.EqualityComparisonExpression("network-traffic:dst_ref.type", "domain-name"), stix2.EqualityComparisonExpression("network-traffic:dst_ref.value", "example.com")]) exp_ob = stix2.ObservationExpression(exp_and) qual_rep = stix2.RepeatQualifier(5) qual_within = stix2.WithinQualifier(stix2.IntegerConstant(1800)) exp = stix2.QualifiedObservationExpression(stix2.QualifiedObservationExpression(exp_ob, qual_rep), qual_within) assert str(exp) == "[network-traffic:dst_ref.type = 'domain-name' AND network-traffic:dst_ref.value = 'example.com'] REPEATS 5 TIMES WITHIN 1800 SECONDS" # noqa
def test_hash_followed_by_registryKey_expression(): hash_exp = stix2.EqualityComparisonExpression("file:hashes.MD5", stix2.HashConstant("79054025255fb1a26e4bc422aef54eb4", "MD5")) o_exp1 = stix2.ObservationExpression(hash_exp) reg_exp = stix2.EqualityComparisonExpression(stix2.ObjectPath("windows-registry-key", ["key"]), stix2.StringConstant("HKEY_LOCAL_MACHINE\\foo\\bar")) o_exp2 = stix2.ObservationExpression(reg_exp) fb_exp = stix2.FollowedByObservationExpression([o_exp1, o_exp2]) para_exp = stix2.ParentheticalExpression(fb_exp) qual_exp = stix2.WithinQualifier(stix2.IntegerConstant(300)) exp = stix2.QualifiedObservationExpression(para_exp, qual_exp) assert str(exp) == "([file:hashes.MD5 = '79054025255fb1a26e4bc422aef54eb4'] FOLLOWEDBY [windows-registry-key:key = 'HKEY_LOCAL_MACHINE\\\\foo\\\\bar']) WITHIN 300 SECONDS" # noqa
def __generate_observation_expression(self, size): """ Generate a random complex observation expression, which may consist of sub-expressions and qualifiers. :param size: The size of the desired observation expression, in terms of the number of simple comparison expressions it must contain :return: The observation expression AST """ assert size > 0 # The generation strategy is similar to that for comparison expressions # (see __generate_complex_comparison_expression()). It is generated in # two parts of random size; one side is constructed as a sub-expression. if size == 1: obs_expr = stix2.ObservationExpression( self.__generate_complex_comparison_expression(1)) else: lsize = random.randint(0, size) rsize = size - lsize if random.random() < 0.5: # Parenthesize right case obs_exprs = [ stix2.ObservationExpression( self.__generate_complex_comparison_expression(sz)) for sz in _rand_series(lsize) ] if rsize > 0: obs_exprs.append( stix2.ParentheticalExpression( self.__generate_observation_expression(rsize))) else: # Parenthesize left case if lsize == 0: obs_exprs = [] else: obs_exprs = [ stix2.ParentheticalExpression( self.__generate_observation_expression(lsize)) ] obs_exprs.extend( stix2.ObservationExpression( self.__generate_complex_comparison_expression(sz)) for sz in _rand_series(rsize)) ast_class = random.choice( (stix2.AndObservationExpression, stix2.OrObservationExpression, stix2.FollowedByObservationExpression)) obs_expr = ast_class(obs_exprs) if random.random() < self.__config.probability_qualifier: qualifier = self.__generate_random_qualifier() obs_expr = stix2.QualifiedObservationExpression( obs_expr, qualifier) return obs_expr