2018-04-02 22:38:04 +02:00
import datetime
import pytest
2017-06-27 18:29:42 +02:00
import stix2
2018-12-11 19:07:53 +01:00
from stix2 . pattern_visitor import create_pattern_object
2017-06-27 18:29:42 +02:00
def test_create_comparison_expression ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . EqualityComparisonExpression (
" file:hashes. ' SHA-256 ' " ,
stix2 . HashConstant ( " aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f " , " SHA-256 " ) ,
) # noqa
2018-12-11 19:07:53 +01:00
2017-06-27 18:29:42 +02:00
assert str ( exp ) == " file:hashes. ' SHA-256 ' = ' aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f ' "
def test_boolean_expression ( ) :
2018-07-13 17:10:05 +02:00
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$ " ) ,
)
2017-06-27 18:29:42 +02:00
exp = stix2 . AndBooleanExpression ( [ exp1 , exp2 ] )
2018-12-11 19:07:53 +01:00
2017-06-27 18:29:42 +02:00
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_boolean_expression_with_parentheses ( ) :
2018-07-13 17:10:05 +02:00
exp1 = stix2 . MatchesComparisonExpression (
stix2 . ObjectPath (
" email-message " ,
[
stix2 . ReferenceObjectPathComponent ( " from_ref " ) ,
2018-12-11 19:07:53 +01:00
stix2 . BasicObjectPathComponent ( " value " , False ) ,
2018-07-13 17:10:05 +02:00
] ,
) ,
stix2 . StringConstant ( " .+ \\ @example \\ .com$ " ) ,
)
exp2 = stix2 . MatchesComparisonExpression (
" email-message:body_multipart[*].body_raw_ref.name " ,
stix2 . StringConstant ( " ^Final Report.+ \\ .exe$ " ) ,
)
2017-06-27 18:29:42 +02:00
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
2017-07-12 23:02:51 +02:00
def test_hash_followed_by_registryKey_expression_python_constant ( ) :
2018-07-13 17:10:05 +02:00
hash_exp = stix2 . EqualityComparisonExpression (
" file:hashes.MD5 " ,
stix2 . HashConstant ( " 79054025255fb1a26e4bc422aef54eb4 " , " MD5 " ) ,
)
2017-07-19 15:39:17 +02:00
o_exp1 = stix2 . ObservationExpression ( hash_exp )
2018-07-13 17:10:05 +02:00
reg_exp = stix2 . EqualityComparisonExpression (
stix2 . ObjectPath ( " windows-registry-key " , [ " key " ] ) ,
stix2 . StringConstant ( " HKEY_LOCAL_MACHINE \\ foo \\ bar " ) ,
)
2017-07-19 15:39:17 +02:00
o_exp2 = stix2 . ObservationExpression ( reg_exp )
fb_exp = stix2 . FollowedByObservationExpression ( [ o_exp1 , o_exp2 ] )
2017-07-12 23:02:51 +02:00
para_exp = stix2 . ParentheticalExpression ( fb_exp )
qual_exp = stix2 . WithinQualifier ( 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
2017-06-27 18:29:42 +02:00
def test_hash_followed_by_registryKey_expression ( ) :
2018-07-13 17:10:05 +02:00
hash_exp = stix2 . EqualityComparisonExpression (
" file:hashes.MD5 " ,
stix2 . HashConstant ( " 79054025255fb1a26e4bc422aef54eb4 " , " MD5 " ) ,
)
2017-07-19 15:39:17 +02:00
o_exp1 = stix2 . ObservationExpression ( hash_exp )
2018-07-13 17:10:05 +02:00
reg_exp = stix2 . EqualityComparisonExpression (
stix2 . ObjectPath ( " windows-registry-key " , [ " key " ] ) ,
stix2 . StringConstant ( " HKEY_LOCAL_MACHINE \\ foo \\ bar " ) ,
)
2017-07-19 15:39:17 +02:00
o_exp2 = stix2 . ObservationExpression ( reg_exp )
fb_exp = stix2 . FollowedByObservationExpression ( [ o_exp1 , o_exp2 ] )
2017-06-27 18:29:42 +02:00
para_exp = stix2 . ParentheticalExpression ( fb_exp )
2017-07-07 22:27:39 +02:00
qual_exp = stix2 . WithinQualifier ( stix2 . IntegerConstant ( 300 ) )
2017-06-27 18:29:42 +02:00
exp = stix2 . QualifiedObservationExpression ( para_exp , qual_exp )
2017-07-12 23:02:51 +02:00
assert str ( exp ) == " ([file:hashes.MD5 = ' 79054025255fb1a26e4bc422aef54eb4 ' ] FOLLOWEDBY [windows-registry-key:key = ' HKEY_LOCAL_MACHINE \\ \\ foo \\ \\ bar ' ]) WITHIN 300 SECONDS " # noqa
2017-06-27 18:29:42 +02:00
def test_file_observable_expression ( ) :
2018-07-13 17:10:05 +02:00
exp1 = stix2 . EqualityComparisonExpression (
" file:hashes. ' SHA-256 ' " ,
stix2 . HashConstant (
" aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f " ,
' SHA-256 ' ,
) ,
)
2017-07-07 22:27:39 +02:00
exp2 = stix2 . EqualityComparisonExpression ( " file:mime_type " , stix2 . StringConstant ( " application/x-pdf " ) )
2018-12-11 19:07:53 +01:00
bool_exp = stix2 . ObservationExpression ( stix2 . AndBooleanExpression ( [ exp1 , exp2 ] ) )
assert str ( bool_exp ) == " [file:hashes. ' SHA-256 ' = ' aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f ' AND file:mime_type = ' application/x-pdf ' ] " # noqa
2017-06-27 18:29:42 +02:00
2018-07-13 17:10:05 +02:00
@pytest.mark.parametrize (
" observation_class, op " , [
( stix2 . AndObservationExpression , ' AND ' ) ,
( stix2 . OrObservationExpression , ' OR ' ) ,
] ,
)
2018-04-02 22:38:04 +02:00
def test_multiple_file_observable_expression ( observation_class , op ) :
2018-07-13 17:10:05 +02:00
exp1 = stix2 . EqualityComparisonExpression (
" file:hashes. ' SHA-256 ' " ,
stix2 . HashConstant (
" bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c " ,
' SHA-256 ' ,
) ,
)
exp2 = stix2 . EqualityComparisonExpression (
" file:hashes.MD5 " ,
stix2 . HashConstant ( " cead3f77f6cda6ec00f57d76c9a6879f " , " MD5 " ) ,
)
2017-06-27 18:29:42 +02:00
bool1_exp = stix2 . OrBooleanExpression ( [ exp1 , exp2 ] )
2018-07-13 17:10:05 +02:00
exp3 = stix2 . EqualityComparisonExpression (
" file:hashes. ' SHA-256 ' " ,
stix2 . HashConstant (
" aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f " ,
' SHA-256 ' ,
) ,
)
2017-07-19 15:39:17 +02:00
op1_exp = stix2 . ObservationExpression ( bool1_exp )
op2_exp = stix2 . ObservationExpression ( exp3 )
2018-04-02 22:38:04 +02:00
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
2017-07-06 16:06:24 +02:00
def test_root_types ( ) :
2017-07-19 15:39:17 +02:00
ast = stix2 . ObservationExpression (
2017-07-06 16:06:24 +02:00
stix2 . AndBooleanExpression (
2018-07-13 17:10:05 +02:00
[
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 " ) ) ,
] ,
) ,
)
2017-07-06 16:06:24 +02:00
assert str ( ast ) == " [(a:b = ' 1 ' OR b:c = ' 2 ' ) AND b:d = ' 3 ' ] "
2017-07-07 22:27:39 +02:00
def test_artifact_payload ( ) :
2018-07-13 17:10:05 +02:00
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 " ) ,
)
2018-12-11 19:07:53 +01:00
and_exp = stix2 . ObservationExpression ( stix2 . AndBooleanExpression ( [ exp1 , exp2 ] ) )
assert str ( and_exp ) == " [artifact:mime_type = ' application/vnd.tcpdump.pcap ' AND artifact:payload_bin MATCHES ' \\ \\ xd4 \\ \\ xc3 \\ \\ xb2 \\ \\ xa1 \\ \\ x02 \\ \\ x00 \\ \\ x04 \\ \\ x00 ' ] " # noqa
2017-07-07 22:27:39 +02:00
2017-07-12 23:02:51 +02:00
def test_greater_than_python_constant ( ) :
2018-12-11 19:07:53 +01:00
exp1 = stix2 . GreaterThanComparisonExpression ( " file:extensions. ' windows-pebinary-ext ' .sections[*].entropy " , 7.0 )
2017-07-19 15:39:17 +02:00
exp = stix2 . ObservationExpression ( exp1 )
2018-12-11 19:07:53 +01:00
assert str ( exp ) == " [file:extensions. ' windows-pebinary-ext ' .sections[*].entropy > 7.0] "
2017-07-12 23:02:51 +02:00
2017-07-07 22:27:39 +02:00
def test_greater_than ( ) :
2018-07-13 17:10:05 +02:00
exp1 = stix2 . GreaterThanComparisonExpression (
2018-12-11 19:07:53 +01:00
" file:extensions. ' windows-pebinary-ext ' .sections[*].entropy " ,
2018-07-13 17:10:05 +02:00
stix2 . FloatConstant ( 7.0 ) ,
)
2017-07-19 15:39:17 +02:00
exp = stix2 . ObservationExpression ( exp1 )
2018-12-11 19:07:53 +01:00
assert str ( exp ) == " [file:extensions. ' windows-pebinary-ext ' .sections[*].entropy > 7.0] "
2017-07-12 23:02:51 +02:00
2018-04-02 22:38:04 +02:00
def test_less_than ( ) :
2018-12-11 19:07:53 +01:00
exp = stix2 . LessThanComparisonExpression ( " file:size " , 1024 )
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " file:size < 1024 "
def test_greater_than_or_equal ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . GreaterThanEqualComparisonExpression (
" file:size " ,
1024 ,
)
2018-12-11 19:07:53 +01:00
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " file:size >= 1024 "
def test_less_than_or_equal ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . LessThanEqualComparisonExpression (
" file:size " ,
1024 ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " file:size <= 1024 "
def test_not ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . LessThanComparisonExpression (
" file:size " ,
1024 ,
negated = True ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " file:size NOT < 1024 "
2017-07-12 23:02:51 +02:00
def test_and_observable_expression ( ) :
2018-07-13 17:10:05 +02:00
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 ) ,
] )
2017-07-12 23:02:51 +02:00
assert str ( exp ) == " [user-account:account_type = ' unix ' AND user-account:user_id = ' 1007 ' AND user-account:account_login = ' Peter ' ] AND [user-account:account_type = ' unix ' AND user-account:user_id = ' 1008 ' AND user-account:account_login = ' Paul ' ] AND [user-account:account_type = ' unix ' AND user-account:user_id = ' 1009 ' AND user-account:account_login = ' Mary ' ] " # noqa
2018-04-02 22:38:04 +02:00
def test_invalid_and_observable_expression ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-07-13 17:10:05 +02:00
stix2 . AndBooleanExpression ( [
stix2 . EqualityComparisonExpression (
" user-account:display_name " ,
" admin " ,
) ,
stix2 . EqualityComparisonExpression (
" email-addr:display_name " ,
stix2 . StringConstant ( " admin " ) ,
) ,
] )
2018-04-02 22:38:04 +02:00
2017-07-12 23:02:51 +02:00
def test_hex ( ) :
2018-07-13 17:10:05 +02:00
exp_and = stix2 . AndBooleanExpression ( [
stix2 . EqualityComparisonExpression (
" file:mime_type " ,
" image/bmp " ,
) ,
stix2 . EqualityComparisonExpression (
" file:magic_number_hex " ,
stix2 . HexConstant ( " ffd8 " ) ,
) ,
] )
2017-07-19 15:39:17 +02:00
exp = stix2 . ObservationExpression ( exp_and )
2017-07-12 23:02:51 +02:00
assert str ( exp ) == " [file:mime_type = ' image/bmp ' AND file:magic_number_hex = h ' ffd8 ' ] "
def test_multiple_qualifiers ( ) :
2018-07-13 17:10:05 +02:00
exp_and = stix2 . AndBooleanExpression ( [
stix2 . EqualityComparisonExpression (
" network-traffic:dst_ref.type " ,
" domain-name " ,
) ,
stix2 . EqualityComparisonExpression (
" network-traffic:dst_ref.value " ,
" example.com " ,
) ,
] )
2017-07-19 15:39:17 +02:00
exp_ob = stix2 . ObservationExpression ( exp_and )
2017-07-12 23:02:51 +02:00
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_set_op ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . ObservationExpression ( stix2 . IsSubsetComparisonExpression (
" network-traffic:dst_ref.value " ,
" 2001:0db8:dead:beef:0000:0000:0000:0000/64 " ,
) )
2017-07-12 23:02:51 +02:00
assert str ( exp ) == " [network-traffic:dst_ref.value ISSUBSET ' 2001:0db8:dead:beef:0000:0000:0000:0000/64 ' ] "
2017-10-05 19:43:56 +02:00
def test_timestamp ( ) :
2020-06-02 04:34:40 +02:00
ts = stix2 . StringConstant ( ' 2014-01-13T07:03:17Z ' )
assert str ( ts ) == " ' 2014-01-13T07:03:17Z ' "
2018-04-02 22:38:04 +02:00
def test_boolean ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . EqualityComparisonExpression (
" email-message:is_multipart " ,
True ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " email-message:is_multipart = true "
def test_binary ( ) :
const = stix2 . BinaryConstant ( " dGhpcyBpcyBhIHRlc3Q= " )
2018-07-13 17:10:05 +02:00
exp = stix2 . EqualityComparisonExpression (
" artifact:payload_bin " ,
const ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " artifact:payload_bin = b ' dGhpcyBpcyBhIHRlc3Q= ' "
def test_list ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . InComparisonExpression (
" process:name " ,
[ ' proccy ' , ' proximus ' , ' badproc ' ] ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " process:name IN ( ' proccy ' , ' proximus ' , ' badproc ' ) "
def test_list2 ( ) :
# alternate way to construct an "IN" Comparison Expression
2018-07-13 17:10:05 +02:00
exp = stix2 . EqualityComparisonExpression (
" process:name " ,
[ ' proccy ' , ' proximus ' , ' badproc ' ] ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " process:name IN ( ' proccy ' , ' proximus ' , ' badproc ' ) "
def test_invalid_constant_type ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-07-13 17:10:05 +02:00
stix2 . EqualityComparisonExpression (
" artifact:payload_bin " ,
{ ' foo ' : ' bar ' } ,
)
2018-04-02 22:38:04 +02:00
def test_invalid_integer_constant ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . IntegerConstant ( ' foo ' )
def test_invalid_float_constant ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . FloatConstant ( ' foo ' )
2018-07-13 17:10:05 +02:00
@pytest.mark.parametrize (
" data, result " , [
( True , True ) ,
( False , False ) ,
( ' True ' , True ) ,
( ' False ' , False ) ,
( ' true ' , True ) ,
( ' false ' , False ) ,
( ' t ' , True ) ,
( ' f ' , False ) ,
( ' T ' , True ) ,
( ' F ' , False ) ,
( 1 , True ) ,
( 0 , False ) ,
] ,
)
2018-04-02 22:38:04 +02:00
def test_boolean_constant ( data , result ) :
boolean = stix2 . BooleanConstant ( data )
assert boolean . value == result
def test_invalid_boolean_constant ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . BooleanConstant ( ' foo ' )
2018-07-13 17:10:05 +02:00
@pytest.mark.parametrize (
" hashtype, data " , [
( ' MD5 ' , ' zzz ' ) ,
( ' ssdeep ' , ' zzz== ' ) ,
] ,
)
2018-04-02 22:38:04 +02:00
def test_invalid_hash_constant ( hashtype , data ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . HashConstant ( data , hashtype )
def test_invalid_hex_constant ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . HexConstant ( ' mm ' )
def test_invalid_binary_constant ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . BinaryConstant ( ' foo ' )
def test_escape_quotes_and_backslashes ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . MatchesComparisonExpression (
" file:name " ,
" ^Final Report.+ \\ .exe$ " ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " file:name MATCHES ' ^Final Report.+ \\ \\ .exe$ ' "
def test_like ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . LikeComparisonExpression (
" directory:path " ,
" C: \\ Windows \\ % \\ foo " ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " directory:path LIKE ' C: \\ \\ Windows \\ \\ % \\ \\ foo ' "
def test_issuperset ( ) :
2018-07-13 17:10:05 +02:00
exp = stix2 . IsSupersetComparisonExpression (
" ipv4-addr:value " ,
" 198.51.100.0/24 " ,
)
2018-04-02 22:38:04 +02:00
assert str ( exp ) == " ipv4-addr:value ISSUPERSET ' 198.51.100.0/24 ' "
def test_repeat_qualifier ( ) :
qual = stix2 . RepeatQualifier ( stix2 . IntegerConstant ( 5 ) )
assert str ( qual ) == ' REPEATS 5 TIMES '
def test_invalid_repeat_qualifier ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . RepeatQualifier ( ' foo ' )
def test_invalid_within_qualifier ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-04-02 22:38:04 +02:00
stix2 . WithinQualifier ( ' foo ' )
def test_startstop_qualifier ( ) :
2018-07-13 17:10:05 +02:00
qual = stix2 . StartStopQualifier (
2020-06-02 04:34:40 +02:00
stix2 . StringConstant ( ' 2016-06-01T00:00:00Z ' ) ,
stix2 . StringConstant ( ' 2017-03-12T08:30:00Z ' ) ,
2018-07-13 17:10:05 +02:00
)
2020-06-02 04:34:40 +02:00
assert str ( qual ) == " START ' 2016-06-01T00:00:00Z ' STOP ' 2017-03-12T08:30:00Z ' "
2018-04-02 22:38:04 +02:00
2018-07-13 17:10:05 +02:00
qual2 = stix2 . StartStopQualifier (
2020-06-02 04:34:40 +02:00
stix2 . StringConstant ( " 2016-06-01T00:00:00Z " ) ,
stix2 . StringConstant ( ' 2016-07-01T00:00:00Z ' ) ,
2018-07-13 17:10:05 +02:00
)
2020-06-02 04:34:40 +02:00
assert str ( qual2 ) == " START ' 2016-06-01T00:00:00Z ' STOP ' 2016-07-01T00:00:00Z ' "
2018-04-02 22:38:04 +02:00
def test_invalid_startstop_qualifier ( ) :
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-07-13 17:10:05 +02:00
stix2 . StartStopQualifier (
' foo ' ,
2020-06-02 04:34:40 +02:00
stix2 . StringConstant ( ' 2016-06-01T00:00:00Z ' ) ,
2018-07-13 17:10:05 +02:00
)
2018-04-02 22:38:04 +02:00
2019-07-09 19:34:19 +02:00
with pytest . raises ( ValueError ) :
2018-07-13 17:10:05 +02:00
stix2 . StartStopQualifier (
datetime . date ( 2016 , 6 , 1 ) ,
' foo ' ,
)
2018-04-26 16:20:46 +02:00
def test_make_constant_already_a_constant ( ) :
str_const = stix2 . StringConstant ( ' Foo ' )
result = stix2 . patterns . make_constant ( str_const )
assert result is str_const
2018-12-11 19:07:53 +01:00
def test_parsing_comparison_expression ( ) :
2020-04-03 16:45:36 +02:00
patt_obj = create_pattern_object ( " [file:hashes. ' SHA-256 ' = ' aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f ' ] " , version = " 2.0 " )
2018-12-11 19:07:53 +01:00
assert str ( patt_obj ) == " [file:hashes. ' SHA-256 ' = ' aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f ' ] "
def test_parsing_qualified_expression ( ) :
patt_obj = create_pattern_object (
2018-12-11 19:23:43 +01:00
" [network-traffic:dst_ref.type = ' domain-name ' AND network-traffic:dst_ref.value = ' example.com ' ] REPEATS 5 TIMES WITHIN 1800 SECONDS " ,
2020-04-03 16:45:36 +02:00
version = " 2.0 " ,
2018-12-11 19:23:43 +01:00
)
2018-12-11 19:07:53 +01:00
assert str (
2018-12-11 19:23:43 +01:00
patt_obj ,
) == " [network-traffic:dst_ref.type = ' domain-name ' AND network-traffic:dst_ref.value = ' example.com ' ] REPEATS 5 TIMES WITHIN 1800 SECONDS "
2018-12-11 19:07:53 +01:00
2020-05-26 21:12:02 +02:00
def test_parsing_start_stop_qualified_expression ( ) :
patt_obj = create_pattern_object ( " [ipv4-addr:value = ' 1.2.3.4 ' ] START ' 2016-06-01T00:00:00Z ' STOP ' 2017-03-12T08:30:00Z ' " , version = " 2.0 " )
assert str (
patt_obj ,
2020-06-02 04:34:40 +02:00
) == " [ipv4-addr:value = ' 1.2.3.4 ' ] START ' 2016-06-01T00:00:00Z ' STOP ' 2017-03-12T08:30:00Z ' "
2020-07-24 17:40:21 +02:00
def test_parsing_mixed_boolean_expression_1 ( ) :
2020-07-25 20:47:40 +02:00
patt_obj = create_pattern_object ( " [a:b = 1 AND a:b = 2 OR a:b = 3] " )
2020-07-24 17:40:21 +02:00
assert str ( patt_obj ) == " [a:b = 1 AND a:b = 2 OR a:b = 3] "
def test_parsing_mixed_boolean_expression_2 ( ) :
2020-07-25 20:47:40 +02:00
patt_obj = create_pattern_object ( " [a:b = 1 OR a:b = 2 AND a:b = 3] " )
2020-07-24 17:40:21 +02:00
assert str ( patt_obj ) == " [a:b = 1 OR a:b = 2 AND a:b = 3] "
2020-07-25 20:47:40 +02:00
def test_parsing_integer_index ( ) :
patt_obj = create_pattern_object ( " [a:b[1]=2] " )
assert str ( patt_obj ) == " [a:b[1] = 2] "
2020-07-30 21:32:06 +02:00
# This should never occur, because the first component will always be a property_name, and they should not be quoted.
def test_parsing_quoted_first_path_component ( ) :
patt_obj = create_pattern_object ( " [a: ' b ' [1]=2] " )
assert str ( patt_obj ) == " [a: ' b ' [1] = 2] "
def test_parsing_quoted_second_path_component ( ) :
patt_obj = create_pattern_object ( " [a:b. ' b ' [1]=2] " )
assert str ( patt_obj ) == " [a:b. ' b ' [1] = 2] "
2020-06-02 04:34:40 +02:00
def test_parsing_illegal_start_stop_qualified_expression ( ) :
with pytest . raises ( ValueError ) :
2020-06-05 15:17:42 +02:00
create_pattern_object ( " [ipv4-addr:value = ' 1.2.3.4 ' ] START ' 2016-06-01 ' STOP ' 2017-03-12T08:30:00Z ' " , version = " 2.0 " )
2020-05-26 21:12:02 +02:00
2018-12-11 19:07:53 +01:00
def test_list_constant ( ) :
2020-04-03 16:45:36 +02:00
patt_obj = create_pattern_object ( " [network-traffic:src_ref.value IN ( ' 10.0.0.0 ' , ' 10.0.0.1 ' , ' 10.0.0.2 ' )] " , version = " 2.0 " )
2018-12-11 19:07:53 +01:00
assert str ( patt_obj ) == " [network-traffic:src_ref.value IN ( ' 10.0.0.0 ' , ' 10.0.0.1 ' , ' 10.0.0.2 ' )] "