From 68f7ca63779cd750c2bfee3f55d1a3f15afbe858 Mon Sep 17 00:00:00 2001 From: Emmanuelle Vargas-Gonzalez Date: Wed, 13 May 2020 18:17:17 -0400 Subject: [PATCH] resolve problem with SSDEEP vocab use for 2.1, closes #391 --- stix2/patterns.py | 30 +++++++++++----------- stix2/properties.py | 4 ++- stix2/test/v20/test_observed_data.py | 16 ++++++++++++ stix2/test/v21/test_observed_data.py | 16 ++++++++++++ stix2/test/v21/test_pattern_expressions.py | 2 +- 5 files changed, 51 insertions(+), 17 deletions(-) diff --git a/stix2/patterns.py b/stix2/patterns.py index f0cceb8..a44f68e 100644 --- a/stix2/patterns.py +++ b/stix2/patterns.py @@ -121,21 +121,21 @@ class BooleanConstant(_Constant): _HASH_REGEX = { - "MD5": ("^[a-fA-F0-9]{32}$", "MD5"), - "MD6": ("^[a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{56}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128}$", "MD6"), - "RIPEMD160": ("^[a-fA-F0-9]{40}$", "RIPEMD-160"), - "SHA1": ("^[a-fA-F0-9]{40}$", "SHA-1"), - "SHA224": ("^[a-fA-F0-9]{56}$", "SHA-224"), - "SHA256": ("^[a-fA-F0-9]{64}$", "SHA-256"), - "SHA384": ("^[a-fA-F0-9]{96}$", "SHA-384"), - "SHA512": ("^[a-fA-F0-9]{128}$", "SHA-512"), - "SHA3224": ("^[a-fA-F0-9]{56}$", "SHA3-224"), - "SHA3256": ("^[a-fA-F0-9]{64}$", "SHA3-256"), - "SHA3384": ("^[a-fA-F0-9]{96}$", "SHA3-384"), - "SHA3512": ("^[a-fA-F0-9]{128}$", "SHA3-512"), - "SSDEEP": ("^[a-zA-Z0-9/+:.]{1,128}$", "ssdeep"), - "WHIRLPOOL": ("^[a-fA-F0-9]{128}$", "WHIRLPOOL"), - "TLSH": ("^[a-fA-F0-9]{70}$", "TLSH"), + "MD5": (r"^[a-fA-F0-9]{32}$", "MD5"), + "MD6": (r"^[a-fA-F0-9]{32}|[a-fA-F0-9]{40}|[a-fA-F0-9]{56}|[a-fA-F0-9]{64}|[a-fA-F0-9]{96}|[a-fA-F0-9]{128}$", "MD6"), + "RIPEMD160": (r"^[a-fA-F0-9]{40}$", "RIPEMD-160"), + "SHA1": (r"^[a-fA-F0-9]{40}$", "SHA-1"), + "SHA224": (r"^[a-fA-F0-9]{56}$", "SHA-224"), + "SHA256": (r"^[a-fA-F0-9]{64}$", "SHA-256"), + "SHA384": (r"^[a-fA-F0-9]{96}$", "SHA-384"), + "SHA512": (r"^[a-fA-F0-9]{128}$", "SHA-512"), + "SHA3224": (r"^[a-fA-F0-9]{56}$", "SHA3-224"), + "SHA3256": (r"^[a-fA-F0-9]{64}$", "SHA3-256"), + "SHA3384": (r"^[a-fA-F0-9]{96}$", "SHA3-384"), + "SHA3512": (r"^[a-fA-F0-9]{128}$", "SHA3-512"), + "SSDEEP": (r"^[a-zA-Z0-9/+:.]{1,128}$", "SSDEEP"), + "WHIRLPOOL": (r"^[a-fA-F0-9]{128}$", "WHIRLPOOL"), + "TLSH": (r"^[a-fA-F0-9]{70}$", "TLSH"), } diff --git a/stix2/properties.py b/stix2/properties.py index 060d9ca..ad7f133 100644 --- a/stix2/properties.py +++ b/stix2/properties.py @@ -417,7 +417,7 @@ HASHES_REGEX = { "SHA3256": (r"^[a-fA-F0-9]{64}$", "SHA3-256"), "SHA3384": (r"^[a-fA-F0-9]{96}$", "SHA3-384"), "SHA3512": (r"^[a-fA-F0-9]{128}$", "SHA3-512"), - "SSDEEP": (r"^[a-zA-Z0-9/+:.]{1,128}$", "ssdeep"), + "SSDEEP": (r"^[a-zA-Z0-9/+:.]{1,128}$", "SSDEEP"), "WHIRLPOOL": (r"^[a-fA-F0-9]{128}$", "WHIRLPOOL"), "TLSH": (r"^[a-fA-F0-9]{70}$", "TLSH"), } @@ -431,6 +431,8 @@ class HashesProperty(DictionaryProperty): key = k.upper().replace('-', '') if key in HASHES_REGEX: vocab_key = HASHES_REGEX[key][1] + if vocab_key == "SSDEEP" and self.spec_version == "2.0": + vocab_key = vocab_key.lower() if not re.match(HASHES_REGEX[key][0], v): raise ValueError("'{0}' is not a valid {1} hash".format(v, vocab_key)) if k != vocab_key: diff --git a/stix2/test/v20/test_observed_data.py b/stix2/test/v20/test_observed_data.py index bfe9c34..354d70c 100644 --- a/stix2/test/v20/test_observed_data.py +++ b/stix2/test/v20/test_observed_data.py @@ -714,6 +714,22 @@ def test_file_example(): assert f.decryption_key == "fred" # does the key have a format we can test for? +def test_file_ssdeep_example(): + f = stix2.v20.File( + name="example.dll", + hashes={ + "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a", + "ssdeep": "96:gS/mFkCpXTWLr/PbKQHbr/S/mFkCpXTWLr/PbKQHbrB:Tu6SXTWGQHbeu6SXTWGQHbV", + }, + size=1024, + ) + + assert f.name == "example.dll" + assert f.size == 1024 + assert f.hashes["SHA-256"] == "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a" + assert f.hashes["ssdeep"] == "96:gS/mFkCpXTWLr/PbKQHbr/S/mFkCpXTWLr/PbKQHbrB:Tu6SXTWGQHbeu6SXTWGQHbV" + + def test_file_example_with_NTFSExt(): f = stix2.v20.File( name="abc.txt", diff --git a/stix2/test/v21/test_observed_data.py b/stix2/test/v21/test_observed_data.py index abcbb7b..2b43d46 100644 --- a/stix2/test/v21/test_observed_data.py +++ b/stix2/test/v21/test_observed_data.py @@ -785,6 +785,22 @@ def test_file_example(): assert f.atime == dt.datetime(2016, 12, 21, 20, 0, 0, tzinfo=pytz.utc) +def test_file_ssdeep_example(): + f = stix2.v21.File( + name="example.dll", + hashes={ + "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a", + "SSDEEP": "96:gS/mFkCpXTWLr/PbKQHbr/S/mFkCpXTWLr/PbKQHbrB:Tu6SXTWGQHbeu6SXTWGQHbV", + }, + size=1024, + ) + + assert f.name == "example.dll" + assert f.size == 1024 + assert f.hashes["SHA-256"] == "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a" + assert f.hashes["SSDEEP"] == "96:gS/mFkCpXTWLr/PbKQHbr/S/mFkCpXTWLr/PbKQHbrB:Tu6SXTWGQHbeu6SXTWGQHbV" + + def test_file_example_with_NTFSExt(): f = stix2.v21.File( name="abc.txt", diff --git a/stix2/test/v21/test_pattern_expressions.py b/stix2/test/v21/test_pattern_expressions.py index 198edac..8294a41 100644 --- a/stix2/test/v21/test_pattern_expressions.py +++ b/stix2/test/v21/test_pattern_expressions.py @@ -518,7 +518,7 @@ def test_invalid_boolean_constant(): @pytest.mark.parametrize( "hashtype, data", [ ('MD5', 'zzz'), - ('ssdeep', 'zzz=='), + ('SSDEEP', 'zzz=='), ], ) def test_invalid_hash_constant(hashtype, data):