def test_boolean_expression(): exp1 = stix2.MatchesComparisonExpression("email-message:from_ref.value", stix2.StringConstant(".+\\@example\\.com$")) exp2 = stix2.MatchesComparisonExpression("email-message:body_multipart[*].body_raw_ref.name", stix2.StringConstant("^Final Report.+\\.exe$")) exp = stix2.AndBooleanExpression([exp1, exp2]) assert str(exp) == "email-message:from_ref.value MATCHES '.+\\\\@example\\\\.com$' AND email-message:body_multipart[*].body_raw_ref.name MATCHES '^Final Report.+\\\\.exe$'" # noqa
def test_and_observable_expression(): exp1 = stix2.AndBooleanExpression([ stix2.EqualityComparisonExpression("user-account:account_type", "unix"), stix2.EqualityComparisonExpression("user-account:user_id", stix2.StringConstant("1007")), stix2.EqualityComparisonExpression("user-account:account_login", "Peter") ]) exp2 = stix2.AndBooleanExpression([ stix2.EqualityComparisonExpression("user-account:account_type", "unix"), stix2.EqualityComparisonExpression("user-account:user_id", stix2.StringConstant("1008")), stix2.EqualityComparisonExpression("user-account:account_login", "Paul") ]) exp3 = stix2.AndBooleanExpression([ stix2.EqualityComparisonExpression("user-account:account_type", "unix"), stix2.EqualityComparisonExpression("user-account:user_id", stix2.StringConstant("1009")), stix2.EqualityComparisonExpression("user-account:account_login", "Mary") ]) exp = stix2.AndObservationExpression([ stix2.ObservationExpression(exp1), stix2.ObservationExpression(exp2), stix2.ObservationExpression(exp3) ]) assert str( exp ) == "[user-account:account_type = 'unix' AND user-account:user_id = '1007' AND user-account:account_login = '******'] AND [user-account:account_type = 'unix' AND user-account:user_id = '1008' AND user-account:account_login = '******'] AND [user-account:account_type = 'unix' AND user-account:user_id = '1009' AND user-account:account_login = '******']" # 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 test_boolean_expression_with_parentheses(): exp1 = stix2.MatchesComparisonExpression(stix2.ObjectPath("email-message", [stix2.ReferenceObjectPathComponent("from_ref"), stix2.BasicObjectPathComponent("value")]), stix2.StringConstant(".+\\@example\\.com$")) exp2 = stix2.MatchesComparisonExpression("email-message:body_multipart[*].body_raw_ref.name", stix2.StringConstant("^Final Report.+\\.exe$")) exp = stix2.ParentheticalExpression(stix2.AndBooleanExpression([exp1, exp2])) assert str(exp) == "(email-message:from_ref.value MATCHES '.+\\\\@example\\\\.com$' AND email-message:body_multipart[*].body_raw_ref.name MATCHES '^Final Report.+\\\\.exe$')" # noqa
def test_startstop_qualifier(): qual = stix2.StartStopQualifier( stix2.StringConstant('2016-06-01T00:00:00Z'), stix2.StringConstant('2017-03-12T08:30:00Z'), ) assert str( qual) == "START '2016-06-01T00:00:00Z' STOP '2017-03-12T08:30:00Z'" qual2 = stix2.StartStopQualifier( stix2.StringConstant("2016-06-01T00:00:00Z"), stix2.StringConstant('2016-07-01T00:00:00Z'), ) assert str( qual2) == "START '2016-06-01T00:00:00Z' STOP '2016-07-01T00:00:00Z'"
def test_invalid_and_observable_expression(): with pytest.raises(ValueError) as excinfo: stix2.AndBooleanExpression([stix2.EqualityComparisonExpression("user-account:display_name", "admin"), stix2.EqualityComparisonExpression("email-addr:display_name", stix2.StringConstant("admin"))]) assert "All operands to an 'AND' expression must have the same object type" in str(excinfo)
def test_artifact_payload(): exp1 = stix2.EqualityComparisonExpression("artifact:mime_type", "application/vnd.tcpdump.pcap") exp2 = stix2.MatchesComparisonExpression("artifact:payload_bin", stix2.StringConstant("\\xd4\\xc3\\xb2\\xa1\\x02\\x00\\x04\\x00")) and_exp = stix2.AndBooleanExpression([exp1, exp2]) exp = stix2.ObservationExpression(and_exp) assert str(exp) == "[artifact:mime_type = 'application/vnd.tcpdump.pcap' AND artifact:payload_bin MATCHES '\\\\xd4\\\\xc3\\\\xb2\\\\xa1\\\\x02\\\\x00\\\\x04\\\\x00']" # noqa
def test_file_observable_expression(): exp1 = stix2.EqualityComparisonExpression("file:hashes.'SHA-256'", stix2.HashConstant( "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f", 'SHA-256')) exp2 = stix2.EqualityComparisonExpression("file:mime_type", stix2.StringConstant("application/x-pdf")) bool_exp = stix2.AndBooleanExpression([exp1, exp2]) exp = stix2.ObservationExpression(bool_exp) assert str(exp) == "[file:hashes.'SHA-256' = 'aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f' AND file:mime_type = 'application/x-pdf']" # noqa
def test_invalid_startstop_qualifier(): with pytest.raises(ValueError): stix2.StartStopQualifier( 'foo', stix2.StringConstant('2016-06-01T00:00:00Z'), ) with pytest.raises(ValueError): stix2.StartStopQualifier( datetime.date(2016, 6, 1), 'foo', )
def test_invalid_and_observable_expression(): with pytest.raises(ValueError): stix2.AndBooleanExpression([ stix2.EqualityComparisonExpression( "user-account:display_name", "admin", ), stix2.EqualityComparisonExpression( "email-addr:display_name", stix2.StringConstant("admin"), ), ])
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 visitTerminal(self, node): if node.symbol.type == STIXPatternParser.IntLiteral: return stix2.IntegerConstant(node.getText()) elif node.symbol.type == STIXPatternParser.FloatLiteral: return stix2.FloatConstant(node.getText()) elif node.symbol.type == STIXPatternParser.HexLiteral: return stix2.HexConstant(node.getText()) elif node.symbol.type == STIXPatternParser.BinaryLiteral: return stix2.BinaryConstant(node.getText()) elif node.symbol.type == STIXPatternParser.StringLiteral: return stix2.StringConstant(node.getText().strip('\'')) elif node.symbol.type == STIXPatternParser.BoolLiteral: return stix2.BooleanConstant(node.getText()) elif node.symbol.type == STIXPatternParser.TimestampLiteral: return stix2.TimestampConstant(node.getText()) # TODO: timestamp else: return node
def test_make_constant_already_a_constant(): str_const = stix2.StringConstant('Foo') result = stix2.patterns.make_constant(str_const) assert result is str_const
def test_timestamp(): ts = stix2.StringConstant('2014-01-13T07:03:17Z') assert str(ts) == "'2014-01-13T07:03:17Z'"