From b5260c95f6c1925bd951cfab07a5263d072a9760 Mon Sep 17 00:00:00 2001 From: Michael Chisholm Date: Fri, 18 Feb 2022 21:33:13 -0500 Subject: [PATCH 01/30] Fix utils.detect_spec_version() to use presence of the spec_version property in a bundle to infer spec version, not the property's value. Update unit tests accordingly. --- stix2/test/test_spec_version_detect.py | 29 ++++++++++++++++++++++++++ stix2/test/v20/test_utils.py | 14 ++++++++++++- stix2/test/v21/test_utils.py | 2 +- stix2/utils.py | 12 ++++++++--- 4 files changed, 52 insertions(+), 5 deletions(-) diff --git a/stix2/test/test_spec_version_detect.py b/stix2/test/test_spec_version_detect.py index 570cc8e7..0d03e03d 100644 --- a/stix2/test/test_spec_version_detect.py +++ b/stix2/test/test_spec_version_detect.py @@ -77,6 +77,35 @@ }, "2.0", ), + ( + { + "type": "bundle", + "id": "bundle--8379cb02-8131-47c8-8a7c-9a1f0e0986b1", + "spec_version": "2.1", + "objects": [ + { + "type": "identity", + "spec_version": "2.1", + "id": "identity--d7f72e8d-657a-43ec-9324-b3ec67a97486", + "created": "1972-05-21T05:33:09.000Z", + "modified": "1973-05-28T02:10:54.000Z", + "name": "alice", + "identity_class": "individual", + }, + { + "type": "marking-definition", + "spec_version": "2.1", + "id": "marking-definition--2a13090f-a493-4b70-85fe-fa021d91dcd2", + "created": "1998-03-27T19:44:53.000Z", + "definition_type": "statement", + "definition": { + "statement": "Copyright (c) ACME Corp.", + }, + }, + ], + }, + "2.0", + ), # STIX 2.1 examples ( { diff --git a/stix2/test/v20/test_utils.py b/stix2/test/v20/test_utils.py index 04439337..f61369b9 100644 --- a/stix2/test/v20/test_utils.py +++ b/stix2/test/v20/test_utils.py @@ -349,6 +349,10 @@ def test_is_not_sro_dict(dict_): {"type": "identity"}, {"type": "software"}, {"type": "marking-definition"}, + # Presence of spec_version property implies a STIX 2.0 bundle, + # regardless of the property's value. STIX 2.1 bundles don't have a + # "spec_version" property defined. + {"type": "bundle", "spec_version": "2.1"}, { "type": "bundle", "id": "bundle--8f431680-6278-4767-ba43-5edb682d7086", @@ -370,12 +374,20 @@ def test_is_object_dict(dict_): {"type": "identity", "spec_version": "2.1"}, {"type": "software", "spec_version": "2.1"}, {"type": "marking-definition", "spec_version": "2.1"}, - {"type": "bundle", "spec_version": "2.1"}, {"type": "language-content", "spec_version": "2.1"}, {"type": "relationship", "spec_version": "2.1"}, {"type": "sighting", "spec_version": "2.1"}, {"type": "foo", "spec_version": "2.1"}, {"type": "foo"}, + { + "type": "bundle", + "id": "bundle--8f431680-6278-4767-ba43-5edb682d7086", + "objects": [ + {"type": "identity"}, + {"type": "software"}, + {"type": "marking-definition"}, + ], + }, ], ) def test_is_not_object_dict(dict_): diff --git a/stix2/test/v21/test_utils.py b/stix2/test/v21/test_utils.py index 6d108d48..33e7ea49 100644 --- a/stix2/test/v21/test_utils.py +++ b/stix2/test/v21/test_utils.py @@ -382,7 +382,7 @@ def test_is_object_dict(dict_): {"type": "identity"}, {"type": "software"}, {"type": "marking-definition"}, - {"type": "bundle"}, + {"type": "bundle", "spec_version": "2.1"}, {"type": "language-content"}, {"type": "relationship"}, {"type": "sighting"}, diff --git a/stix2/utils.py b/stix2/utils.py index 647a89f1..8f679d43 100644 --- a/stix2/utils.py +++ b/stix2/utils.py @@ -327,9 +327,15 @@ def detect_spec_version(stix_dict): obj_type = stix_dict["type"] if 'spec_version' in stix_dict: - # For STIX 2.0, applies to bundles only. - # For STIX 2.1+, applies to SCOs, SDOs, SROs, and markings only. - v = stix_dict['spec_version'] + # For STIX 2.0, applies to bundles only. Presence in a bundle implies + # STIX 2.0; the value applies to the content of the bundle, not the + # bundle itself, so we don't care here about the value. + # + # For STIX 2.1+, applies to non-bundles only. + if obj_type == "bundle": + v = "2.0" + else: + v = stix_dict['spec_version'] elif "id" not in stix_dict: # Only 2.0 SCOs don't have ID properties v = "2.0" From 3ab3a9c33f920e1ec23504b32b9beecb10385b43 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Wed, 13 Jul 2022 15:10:48 -0400 Subject: [PATCH 02/30] Update maintainers list --- README.rst | 15 ++++++--------- setup.py | 2 -- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/README.rst b/README.rst index 70485773..ca276cf4 100644 --- a/README.rst +++ b/README.rst @@ -135,18 +135,15 @@ select additional or substitute Maintainers, per `consensus agreements **Current Maintainers of this TC Open Repository** -- `Chris Lenk `__; GitHub ID: - https://github.com/clenk/; WWW: `MITRE Corporation `__ - -- `Rich Piazza `__; GitHub ID: - https://github.com/rpiazza/; WWW: `MITRE Corporation `__ - -- `Andy Chisholm `__; GitHub ID: - https://github.com/chisholm/; WWW: `MITRE Corporation `__ - - `Jason Keirstead `__; GitHub ID: https://github.com/JasonKeirstead; WWW: `IBM `__ +- `Emily Ratliff `__; GitHub ID: + https://github.com/ejratl; WWW: `IBM `__ + +- `Duncan Sparrell `__; GitHub ID: + https://github.com/sparrell; WWW: `sFractal `__ + About OASIS TC Open Repositories -------------------------------- diff --git a/setup.py b/setup.py index f383ebdb..23b95ff5 100644 --- a/setup.py +++ b/setup.py @@ -31,8 +31,6 @@ def get_long_description(): url='https://oasis-open.github.io/cti-documentation/', author='OASIS Cyber Threat Intelligence Technical Committee', author_email='cti-users@lists.oasis-open.org', - maintainer='Chris Lenk', - maintainer_email='clenk@mitre.org', license='BSD', classifiers=[ 'Development Status :: 4 - Beta', From 07dddd1ac1fda6356155a1a8dd3e7859eec11077 Mon Sep 17 00:00:00 2001 From: jweissm Date: Fri, 29 Jul 2022 07:22:46 -0700 Subject: [PATCH 03/30] added python 3.10 to test harness removed 3.6 --- .github/workflows/python-ci-tests.yml | 2 +- setup.py | 4 ++-- tox.ini | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/python-ci-tests.yml b/.github/workflows/python-ci-tests.yml index dc9ccc0e..edb2c4b6 100644 --- a/.github/workflows/python-ci-tests.yml +++ b/.github/workflows/python-ci-tests.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.6, 3.7, 3.8, 3.9] + python-version: [3.7, 3.8, 3.9, 3.10] name: Python ${{ matrix.python-version }} Build steps: diff --git a/setup.py b/setup.py index f383ebdb..bf01b13b 100644 --- a/setup.py +++ b/setup.py @@ -40,14 +40,14 @@ def get_long_description(): 'Topic :: Security', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', ], keywords='stix stix2 json cti cyber threat intelligence', packages=find_packages(exclude=['*.test', '*.test.*']), - python_requires='>=3.6', + python_requires='>=3.7', install_requires=[ 'pytz', 'requests', diff --git a/tox.ini b/tox.ini index 90f5cfc0..26974585 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py36,py37,py38,py39,packaging,pre-commit-check +envlist = py37,py38,py39,py310,packaging,pre-commit-check [testenv] deps = @@ -32,7 +32,7 @@ commands = [gh-actions] python = - 3.6: py36 3.7: py37 3.8: py38 3.9: py39, packaging, pre-commit-check + 3.10: py310 From aab27b6559c449c85cfc3e422dcfcf7e8a7edf6c Mon Sep 17 00:00:00 2001 From: Joshua Weiss <89481736+jweissm@users.noreply.github.com> Date: Mon, 1 Aug 2022 09:48:21 -0400 Subject: [PATCH 04/30] Update python-ci-tests.yml --- .github/workflows/python-ci-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-ci-tests.yml b/.github/workflows/python-ci-tests.yml index edb2c4b6..211aa4c5 100644 --- a/.github/workflows/python-ci-tests.yml +++ b/.github/workflows/python-ci-tests.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, 3.10] + python-version: [3.7, 3.8, 3.9, '3.10'] name: Python ${{ matrix.python-version }} Build steps: From 8c29b12fa1666e71fb3085c1557b9797838ff77a Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Mon, 17 Oct 2022 11:53:28 -0400 Subject: [PATCH 05/30] Update docs dependencies Fixes issues with doc builds failing. --- docs/api/datastore/stix2.datastore.filesystem.rst | 2 +- docs/api/datastore/stix2.datastore.filters.rst | 2 +- docs/api/datastore/stix2.datastore.memory.rst | 2 +- docs/api/datastore/stix2.datastore.taxii.rst | 2 +- docs/api/equivalence/stix2.equivalence.pattern.rst | 4 ++-- docs/api/markings/stix2.markings.granular_markings.rst | 2 +- docs/api/markings/stix2.markings.object_markings.rst | 2 +- docs/api/markings/stix2.markings.utils.rst | 2 +- docs/api/stix2.confidence.rst | 4 ++-- docs/api/stix2.datastore.rst | 4 ++-- docs/api/stix2.environment.rst | 4 ++-- docs/api/stix2.equivalence.rst | 6 +++--- docs/api/stix2.exceptions.rst | 4 ++-- docs/api/stix2.markings.rst | 4 ++-- docs/api/stix2.parsing.rst | 6 +++--- docs/api/stix2.pattern_visitor.rst | 6 +++--- docs/api/stix2.patterns.rst | 4 ++-- docs/api/stix2.properties.rst | 4 ++-- docs/api/stix2.serialization.rst | 6 +++--- docs/api/stix2.utils.rst | 4 ++-- docs/api/stix2.v20.rst | 4 ++-- docs/api/stix2.v21.rst | 4 ++-- docs/api/stix2.versioning.rst | 6 +++--- docs/api/stix2.workbench.rst | 4 ++-- docs/conf.py | 5 ++--- requirements.txt | 4 ++-- stix2/environment.py | 1 - stix2/equivalence/object/__init__.py | 4 ++-- 28 files changed, 52 insertions(+), 54 deletions(-) diff --git a/docs/api/datastore/stix2.datastore.filesystem.rst b/docs/api/datastore/stix2.datastore.filesystem.rst index 2b0d2eee..665df66c 100644 --- a/docs/api/datastore/stix2.datastore.filesystem.rst +++ b/docs/api/datastore/stix2.datastore.filesystem.rst @@ -2,4 +2,4 @@ filesystem ========================== .. automodule:: stix2.datastore.filesystem - :members: + :members: \ No newline at end of file diff --git a/docs/api/datastore/stix2.datastore.filters.rst b/docs/api/datastore/stix2.datastore.filters.rst index 3c9f0b11..b556754b 100644 --- a/docs/api/datastore/stix2.datastore.filters.rst +++ b/docs/api/datastore/stix2.datastore.filters.rst @@ -2,4 +2,4 @@ filters ======================= .. automodule:: stix2.datastore.filters - :members: + :members: \ No newline at end of file diff --git a/docs/api/datastore/stix2.datastore.memory.rst b/docs/api/datastore/stix2.datastore.memory.rst index eda42cb0..b0521c73 100644 --- a/docs/api/datastore/stix2.datastore.memory.rst +++ b/docs/api/datastore/stix2.datastore.memory.rst @@ -2,4 +2,4 @@ memory ====================== .. automodule:: stix2.datastore.memory - :members: + :members: \ No newline at end of file diff --git a/docs/api/datastore/stix2.datastore.taxii.rst b/docs/api/datastore/stix2.datastore.taxii.rst index f1c43bf8..68389a01 100644 --- a/docs/api/datastore/stix2.datastore.taxii.rst +++ b/docs/api/datastore/stix2.datastore.taxii.rst @@ -2,4 +2,4 @@ taxii ===================== .. automodule:: stix2.datastore.taxii - :members: + :members: \ No newline at end of file diff --git a/docs/api/equivalence/stix2.equivalence.pattern.rst b/docs/api/equivalence/stix2.equivalence.pattern.rst index 5246ed2f..d11e9ce2 100644 --- a/docs/api/equivalence/stix2.equivalence.pattern.rst +++ b/docs/api/equivalence/stix2.equivalence.pattern.rst @@ -1,5 +1,5 @@ pattern -============== +========================= .. automodule:: stix2.equivalence.pattern - :members: + :members: \ No newline at end of file diff --git a/docs/api/markings/stix2.markings.granular_markings.rst b/docs/api/markings/stix2.markings.granular_markings.rst index d64ebc90..b4a71607 100644 --- a/docs/api/markings/stix2.markings.granular_markings.rst +++ b/docs/api/markings/stix2.markings.granular_markings.rst @@ -2,4 +2,4 @@ granular_markings ================================ .. automodule:: stix2.markings.granular_markings - :members: + :members: \ No newline at end of file diff --git a/docs/api/markings/stix2.markings.object_markings.rst b/docs/api/markings/stix2.markings.object_markings.rst index 8e8de677..d861c879 100644 --- a/docs/api/markings/stix2.markings.object_markings.rst +++ b/docs/api/markings/stix2.markings.object_markings.rst @@ -2,4 +2,4 @@ object_markings ============================== .. automodule:: stix2.markings.object_markings - :members: + :members: \ No newline at end of file diff --git a/docs/api/markings/stix2.markings.utils.rst b/docs/api/markings/stix2.markings.utils.rst index 66793aa7..ee59b6c9 100644 --- a/docs/api/markings/stix2.markings.utils.rst +++ b/docs/api/markings/stix2.markings.utils.rst @@ -2,4 +2,4 @@ utils ==================== .. automodule:: stix2.markings.utils - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.confidence.rst b/docs/api/stix2.confidence.rst index 5c2658bb..2ecf230a 100644 --- a/docs/api/stix2.confidence.rst +++ b/docs/api/stix2.confidence.rst @@ -1,5 +1,5 @@ -confidence +confidence ================ .. automodule:: stix2.confidence - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.datastore.rst b/docs/api/stix2.datastore.rst index 0d909875..aae929d0 100644 --- a/docs/api/stix2.datastore.rst +++ b/docs/api/stix2.datastore.rst @@ -1,5 +1,5 @@ -datastore +datastore =============== .. automodule:: stix2.datastore - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.environment.rst b/docs/api/stix2.environment.rst index 6b44ba5f..26e5e8ba 100644 --- a/docs/api/stix2.environment.rst +++ b/docs/api/stix2.environment.rst @@ -1,5 +1,5 @@ -environment +environment ================= .. automodule:: stix2.environment - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.equivalence.rst b/docs/api/stix2.equivalence.rst index b886fc79..db815433 100644 --- a/docs/api/stix2.equivalence.rst +++ b/docs/api/stix2.equivalence.rst @@ -1,5 +1,5 @@ -equivalence -============== +equivalence +================= .. automodule:: stix2.equivalence - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.exceptions.rst b/docs/api/stix2.exceptions.rst index ad8ddf3f..69156a08 100644 --- a/docs/api/stix2.exceptions.rst +++ b/docs/api/stix2.exceptions.rst @@ -1,5 +1,5 @@ -exceptions +exceptions ================ .. automodule:: stix2.exceptions - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.markings.rst b/docs/api/stix2.markings.rst index 881fda1c..8c9f1e1e 100644 --- a/docs/api/stix2.markings.rst +++ b/docs/api/stix2.markings.rst @@ -1,5 +1,5 @@ -markings +markings ============== .. automodule:: stix2.markings - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.parsing.rst b/docs/api/stix2.parsing.rst index bee3e4e9..e028e4a1 100644 --- a/docs/api/stix2.parsing.rst +++ b/docs/api/stix2.parsing.rst @@ -1,5 +1,5 @@ -parsing -=============== +parsing +============= .. automodule:: stix2.parsing - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.pattern_visitor.rst b/docs/api/stix2.pattern_visitor.rst index fe8e34f5..83475e64 100644 --- a/docs/api/stix2.pattern_visitor.rst +++ b/docs/api/stix2.pattern_visitor.rst @@ -1,5 +1,5 @@ -pattern_visitor -================ +pattern_visitor +===================== .. automodule:: stix2.pattern_visitor - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.patterns.rst b/docs/api/stix2.patterns.rst index f95ec344..99608c08 100644 --- a/docs/api/stix2.patterns.rst +++ b/docs/api/stix2.patterns.rst @@ -1,5 +1,5 @@ -patterns +patterns ============== .. automodule:: stix2.patterns - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.properties.rst b/docs/api/stix2.properties.rst index e357ef45..931fdc88 100644 --- a/docs/api/stix2.properties.rst +++ b/docs/api/stix2.properties.rst @@ -1,5 +1,5 @@ -properties +properties ================ .. automodule:: stix2.properties - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.serialization.rst b/docs/api/stix2.serialization.rst index bc182d83..00c5163e 100644 --- a/docs/api/stix2.serialization.rst +++ b/docs/api/stix2.serialization.rst @@ -1,5 +1,5 @@ -serialization -================ +serialization +=================== .. automodule:: stix2.serialization - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.utils.rst b/docs/api/stix2.utils.rst index 49a1e168..c3088aef 100644 --- a/docs/api/stix2.utils.rst +++ b/docs/api/stix2.utils.rst @@ -1,5 +1,5 @@ -utils +utils =========== .. automodule:: stix2.utils - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.v20.rst b/docs/api/stix2.v20.rst index 85f4a227..b523168d 100644 --- a/docs/api/stix2.v20.rst +++ b/docs/api/stix2.v20.rst @@ -1,5 +1,5 @@ -v20 +v20 ========= .. automodule:: stix2.v20 - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.v21.rst b/docs/api/stix2.v21.rst index 7157e3d6..565ae61e 100644 --- a/docs/api/stix2.v21.rst +++ b/docs/api/stix2.v21.rst @@ -1,5 +1,5 @@ -v21 +v21 ========= .. automodule:: stix2.v21 - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.versioning.rst b/docs/api/stix2.versioning.rst index adc2eab9..fcbec92b 100644 --- a/docs/api/stix2.versioning.rst +++ b/docs/api/stix2.versioning.rst @@ -1,5 +1,5 @@ -versioning -=============== +versioning +================ .. automodule:: stix2.versioning - :members: + :members: \ No newline at end of file diff --git a/docs/api/stix2.workbench.rst b/docs/api/stix2.workbench.rst index 8fa2544c..137291e8 100644 --- a/docs/api/stix2.workbench.rst +++ b/docs/api/stix2.workbench.rst @@ -1,5 +1,5 @@ -workbench +workbench =============== .. automodule:: stix2.workbench - :members: + :members: \ No newline at end of file diff --git a/docs/conf.py b/docs/conf.py index b6dd6ea5..dc43ccf9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -40,7 +40,6 @@ version = __version__ release = __version__ -language = None exclude_patterns = ['_build', '_templates', 'Thumbs.db', '.DS_Store', 'guide/.ipynb_checkpoints'] pygments_style = 'sphinx' todo_include_todos = False @@ -102,8 +101,8 @@ def can_document_member(cls, member, membername, isattr, parent): issubclass(member, _STIXBase) and \ hasattr(member, '_properties') - def add_content(self, more_content, no_docstring=False): - ClassDocumenter.add_content(self, more_content, no_docstring) + def add_content(self, more_content): + ClassDocumenter.add_content(self, more_content) obj = self.object self.add_line(':Properties:', '') diff --git a/requirements.txt b/requirements.txt index ed517e03..4cb08b6a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,12 +1,12 @@ bumpversion ipython -nbconvert<6 +nbconvert nbsphinx==0.8.6 pre-commit pygments<3,>=2.4.1 pytest pytest-cov -sphinx<2 +sphinx<6 sphinx-prompt tox diff --git a/stix2/environment.py b/stix2/environment.py index f7c13eed..eab2ba9e 100644 --- a/stix2/environment.py +++ b/stix2/environment.py @@ -119,7 +119,6 @@ class Environment(DataStoreMixin): .. automethod:: get .. automethod:: all_versions .. automethod:: query - .. automethod:: creator_of .. automethod:: relationships .. automethod:: related_to .. automethod:: add diff --git a/stix2/equivalence/object/__init__.py b/stix2/equivalence/object/__init__.py index dde52ec7..2b16a346 100644 --- a/stix2/equivalence/object/__init__.py +++ b/stix2/equivalence/object/__init__.py @@ -244,7 +244,7 @@ def partial_timestamp_based(t1, t2, tdelta): def partial_list_based(l1, l2): """Performs a partial list matching via finding the intersection between common values. Repeated values are counted only once. This method can be - used for *_refs equality checks when de-reference is not possible. + used for _refs equality checks when de-reference is not possible. Args: l1: A list of values. @@ -262,7 +262,7 @@ def partial_list_based(l1, l2): def exact_match(val1, val2): """Performs an exact value match based on two values. This method can be - used for *_ref equality check when de-reference is not possible. + used for _ref equality check when de-reference is not possible. Args: val1: A value suitable for an equality test. From 585ade563c236805f653fc1b831320ec6aef6423 Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Mon, 17 Oct 2022 11:54:09 -0400 Subject: [PATCH 06/30] Fix a couple links in the docs --- docs/guide/custom.ipynb | 6 +++--- docs/guide/ts_support.ipynb | 7 +++---- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/docs/guide/custom.ipynb b/docs/guide/custom.ipynb index c31e2040..3d65dcbc 100644 --- a/docs/guide/custom.ipynb +++ b/docs/guide/custom.ipynb @@ -1482,7 +1482,7 @@ "source": [ "### Custom Cyber Observable Extensions\n", "\n", - "Finally, custom extensions to existing Cyber Observable types can also be created. Just use the @[CustomExtension](../api/v21/stix2.v21.observables.rst#stix2.v21.observables.CustomExtension) decorator. Note that you must provide the Cyber Observable class to which the extension applies. Again, any extra validation of the properties can be implemented by providing an ``__init__()`` but it is not required. Let's say we want to make an extension to the ``File`` Cyber Observable Object:" + "Finally, custom extensions to existing Cyber Observable types can also be created. Just use the @[CustomExtension](../api/v21/stix2.v21.common.rst#stix2.v21.common.CustomExtension) decorator. Note that you must provide the Cyber Observable class to which the extension applies. Again, any extra validation of the properties can be implemented by providing an ``__init__()`` but it is not required. Let's say we want to make an extension to the ``File`` Cyber Observable Object:" ] }, { @@ -1803,7 +1803,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": "Python 3", "language": "python", "name": "python3" }, @@ -1817,7 +1817,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.8.1" + "version": "3.9.2" } }, "nbformat": 4, diff --git a/docs/guide/ts_support.ipynb b/docs/guide/ts_support.ipynb index 8c071341..eb453521 100644 --- a/docs/guide/ts_support.ipynb +++ b/docs/guide/ts_support.ipynb @@ -63,8 +63,7 @@ "\n", "Imports can be used in different ways depending on the use case and support levels.\n", "\n", - "People who want to support the latest version of STIX 2 without having to make changes, can implicitly use the latest version:", - "
\n", + "People who want to support the latest version of STIX 2 without having to make changes, can implicitly use the latest version:
\n", "\n", "**Warning**\n", "\n", @@ -372,7 +371,7 @@ "source": [ "### How custom content works\n", "\n", - "[CustomObject](../api/v21/stix2.v21.sdo.rst#stix2.v21.sdo.CustomObject), [CustomObservable](../api/v21/stix2.v21.observables.rst#stix2.v21.observables.CustomObservable), [CustomMarking](../api/v21/stix2.v21.common.rst#stix2.v21.common.CustomMarking) and [CustomExtension](../api/v21/stix2.v21.observables.rst#stix2.v21.observables.CustomExtension) must be registered explicitly by STIX version. This is a design decision since properties or requirements may change as the STIX Technical Specification advances.\n", + "[CustomObject](../api/v21/stix2.v21.sdo.rst#stix2.v21.sdo.CustomObject), [CustomObservable](../api/v21/stix2.v21.observables.rst#stix2.v21.observables.CustomObservable), [CustomMarking](../api/v21/stix2.v21.common.rst#stix2.v21.common.CustomMarking) and [CustomExtension](../api/v21/stix2.v21.common.rst#stix2.v21.common.CustomExtension) must be registered explicitly by STIX version. This is a design decision since properties or requirements may change as the STIX Technical Specification advances.\n", "\n", "You can perform this by:" ] @@ -416,7 +415,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.0a6" + "version": "3.9.2" } }, "nbformat": 4, From f1c1632f3aa916cfa30b0b3625200f01c12dc5ed Mon Sep 17 00:00:00 2001 From: OASIS-OP-Admin <47402065+OASIS-OP-Admin@users.noreply.github.com> Date: Tue, 6 Jun 2023 13:51:34 -0400 Subject: [PATCH 07/30] fixing i-cla links --- CONTRIBUTING.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 5b1f6991..ee3c8b1d 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,7 +1,7 @@

Public Participation Invited

-

This OASIS TC Open Repository ( github.com/oasis-open/cti-python-stix2 ) is a community public repository that supports participation by anyone, whether affiliated with OASIS or not. Substantive contributions (repository "code") and related feedback is invited from all parties, following the common conventions for participation in GitHub public repository projects. Participation is expected to be consistent with the OASIS TC Open Repository Guidelines and Procedures, the LICENSE designated for this particular repository (BSD-3-Clause License), and the requirement for an Individual Contributor License Agreement. Please see the repository README document for other details.

+

This OASIS TC Open Repository ( github.com/oasis-open/cti-python-stix2 ) is a community public repository that supports participation by anyone, whether affiliated with OASIS or not. Substantive contributions (repository "code") and related feedback is invited from all parties, following the common conventions for participation in GitHub public repository projects. Participation is expected to be consistent with the OASIS TC Open Repository Guidelines and Procedures, the LICENSE designated for this particular repository (BSD-3-Clause License), and the requirement for an Individual Contributor License Agreement. Please see the repository README document for other details.

@@ -17,7 +17,7 @@

Contributions Subject to Individual CLA

-

Formally, "contribution" to this TC Open Repository refers to content merged into the "Code" repository (repository changes represented by code commits), following the GitHub definition of contributor: "someone who has contributed to a project by having a pull request merged but does not have collaborator [i.e., direct write] access." Anyone who signs the TC Open Repository Individual Contributor License Agreement (CLA), signifying agreement with the licensing requirement, may contribute substantive content — subject to evaluation of a GitHub pull request. The main web page for this repository, as with any GitHub public repository, displays a link to a document listing contributions to the repository's default branch (filtered by Commits, Additions, and Deletions).

+

Formally, "contribution" to this TC Open Repository refers to content merged into the "Code" repository (repository changes represented by code commits), following the GitHub definition of contributor: "someone who has contributed to a project by having a pull request merged but does not have collaborator [i.e., direct write] access." Anyone who signs the TC Open Repository Individual Contributor License Agreement (CLA), signifying agreement with the licensing requirement, may contribute substantive content — subject to evaluation of a GitHub pull request. The main web page for this repository, as with any GitHub public repository, displays a link to a document listing contributions to the repository's default branch (filtered by Commits, Additions, and Deletions).

This TC Open Repository, as with GitHub public repositories generally, also accepts public feedback from any GitHub user. Public feedback includes opening issues, authoring and editing comments, participating in conversations, making wiki edits, creating repository stars, and making suggestions via pull requests. Such feedback does not constitute an OASIS TC Open Repository contribution. Some details are presented under "Read permissions" in the table of permission levels for a GitHub organization. Technical content intended as a substantive contribution (repository "Code") to an TC Open Repository is subject to evaluation, and requires a signed Individual CLA.

From 7d7104a786d451b3d6ebb9ea3dfb57e50ee3fe1c Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Tue, 28 Nov 2023 11:47:56 -0500 Subject: [PATCH 08/30] Update README.rst remove Duncan from maintainers, added Rich --- README.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index ca276cf4..2b84a609 100644 --- a/README.rst +++ b/README.rst @@ -141,8 +141,8 @@ select additional or substitute Maintainers, per `consensus agreements - `Emily Ratliff `__; GitHub ID: https://github.com/ejratl; WWW: `IBM `__ -- `Duncan Sparrell `__; GitHub ID: - https://github.com/sparrell; WWW: `sFractal `__ +- `Rich Piazza `__; GitHub ID: + https://github.com/rpiazza; WWW: `MITRE `__ About OASIS TC Open Repositories -------------------------------- From f5ae9798f8bb40c71ce4737f3b97940a7cd388ef Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Thu, 14 Mar 2024 16:46:07 -0400 Subject: [PATCH 09/30] update python versions to 3.8-3.12 --- setup.py | 5 +++-- tox.ini | 8 ++++---- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/setup.py b/setup.py index 499af4f1..80edabb4 100644 --- a/setup.py +++ b/setup.py @@ -38,14 +38,15 @@ def get_long_description(): 'Topic :: Security', 'License :: OSI Approved :: BSD License', 'Programming Language :: Python :: 3', - 'Programming Language :: Python :: 3.7', 'Programming Language :: Python :: 3.8', 'Programming Language :: Python :: 3.9', 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', ], keywords='stix stix2 json cti cyber threat intelligence', packages=find_packages(exclude=['*.test', '*.test.*']), - python_requires='>=3.7', + python_requires='>=3.8', install_requires=[ 'pytz', 'requests', diff --git a/tox.ini b/tox.ini index 26974585..bc7bd5b6 100644 --- a/tox.ini +++ b/tox.ini @@ -1,9 +1,8 @@ [tox] -envlist = py37,py38,py39,py310,packaging,pre-commit-check +envlist = py38,py39,py310,py311,py312,packaging,pre-commit-check [testenv] deps = - -U tox pytest pytest-cov @@ -32,7 +31,8 @@ commands = [gh-actions] python = - 3.7: py37 3.8: py38 - 3.9: py39, packaging, pre-commit-check + 3.9: py39 3.10: py310 + 3.11: py311, packaging, pre-commit-check + 3.12: py312 From 9f70e6860e797ff0097a0aa40f49b1b4f8fa50cc Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Thu, 14 Mar 2024 16:53:31 -0400 Subject: [PATCH 10/30] fix workflows python versions --- .github/workflows/python-ci-tests.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-ci-tests.yml b/.github/workflows/python-ci-tests.yml index 211aa4c5..6ca27d5f 100644 --- a/.github/workflows/python-ci-tests.yml +++ b/.github/workflows/python-ci-tests.yml @@ -9,7 +9,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - python-version: [3.7, 3.8, 3.9, '3.10'] + python-version: [3.8, 3.9, '3.10', '3.11', '3.12'] name: Python ${{ matrix.python-version }} Build steps: From 4f0e1d205abe43933bb17ee4f04047da88086c8a Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Sat, 16 Mar 2024 13:53:34 -0400 Subject: [PATCH 11/30] fiux test-environments - weights changed --- stix2/test/v20/test_environment.py | 12 ++++++------ stix2/test/v21/test_environment.py | 14 +++++++------- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/stix2/test/v20/test_environment.py b/stix2/test/v20/test_environment.py index c8867b01..b6f3a0b3 100644 --- a/stix2/test/v20/test_environment.py +++ b/stix2/test/v20/test_environment.py @@ -515,12 +515,12 @@ def test_graph_similarity_with_filesystem_source(ds, fs): prop_scores2 = {} env2 = stix2.Environment().graph_similarity(ds, fs, prop_scores2, ignore_spec_version=True) - assert round(env1) == 25 - assert round(prop_scores1["matching_score"]) == 451 + assert round(env1) == 19 + assert round(prop_scores1["matching_score"]) == 334 assert round(prop_scores1["len_pairs"]) == 18 - assert round(env2) == 25 - assert round(prop_scores2["matching_score"]) == 451 + assert round(env2) == 19 + assert round(prop_scores2["matching_score"]) == 334 assert round(prop_scores2["len_pairs"]) == 18 prop_scores1["matching_score"] = round(prop_scores1["matching_score"], 3) @@ -587,11 +587,11 @@ def test_graph_equivalence_with_filesystem_source(ds, fs): env2 = stix2.Environment().graph_equivalence(ds, fs, prop_scores2, ignore_spec_version=True) assert env1 is False - assert round(prop_scores1["matching_score"]) == 451 + assert round(prop_scores1["matching_score"]) == 334 assert round(prop_scores1["len_pairs"]) == 18 assert env2 is False - assert round(prop_scores2["matching_score"]) == 451 + assert round(prop_scores2["matching_score"]) == 334 assert round(prop_scores2["len_pairs"]) == 18 prop_scores1["matching_score"] = round(prop_scores1["matching_score"], 3) diff --git a/stix2/test/v21/test_environment.py b/stix2/test/v21/test_environment.py index 883ff012..51ca15a5 100644 --- a/stix2/test/v21/test_environment.py +++ b/stix2/test/v21/test_environment.py @@ -900,7 +900,7 @@ def test_object_similarity_prop_scores(): tool2 = stix2.v21.Tool(id=TOOL_ID, **TOOL2_KWARGS) stix2.Environment().object_similarity(tool1, tool2, prop_scores) assert len(prop_scores) == 4 - assert round(prop_scores["matching_score"], 1) == 8.9 + assert round(prop_scores["matching_score"], 1) == 0.0 assert round(prop_scores["sum_weights"], 1) == 100.0 @@ -1050,12 +1050,12 @@ def test_graph_similarity_with_filesystem_source(ds, fs): max_depth=1, ) - assert round(env1) == 23 - assert round(prop_scores1["matching_score"]) == 411 + assert round(env1) == 17 + assert round(prop_scores1["matching_score"]) == 308 assert round(prop_scores1["len_pairs"]) == 18 - assert round(env2) == 23 - assert round(prop_scores2["matching_score"]) == 411 + assert round(env2) == 17 + assert round(prop_scores2["matching_score"]) == 308 assert round(prop_scores2["len_pairs"]) == 18 prop_scores1["matching_score"] = round(prop_scores1["matching_score"], 3) @@ -1225,11 +1225,11 @@ def test_graph_equivalence_with_filesystem_source(ds, fs): env2 = stix2.Environment().graph_equivalence(ds, fs, prop_scores2, ignore_spec_version=True) assert env1 is False - assert round(prop_scores1["matching_score"]) == 411 + assert round(prop_scores1["matching_score"]) == 308 assert round(prop_scores1["len_pairs"]) == 18 assert env2 is False - assert round(prop_scores2["matching_score"]) == 411 + assert round(prop_scores2["matching_score"]) == 308 assert round(prop_scores2["len_pairs"]) == 18 prop_scores1["matching_score"] = round(prop_scores1["matching_score"], 3) From 4a3f99f251d4a6c75c270fd1890c5e944cf8d33b Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Mon, 18 Mar 2024 09:57:59 -0400 Subject: [PATCH 12/30] update isort to 5.12 --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 434eb957..c39aaf6d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -16,7 +16,7 @@ repos: args: - --max-line-length=160 - repo: https://github.com/PyCQA/isort - rev: 5.7.0 + rev: 5.12.0 hooks: - id: isort name: Sort python imports (shows diff) From 647987dfa6711a929d035bc5acd4bd5d7706c59c Mon Sep 17 00:00:00 2001 From: Chris Lenk Date: Mon, 15 Apr 2024 17:11:28 -0400 Subject: [PATCH 13/30] Prevent codecov workflow errors --- .github/workflows/python-ci-tests.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/python-ci-tests.yml b/.github/workflows/python-ci-tests.yml index 6ca27d5f..47f860e1 100644 --- a/.github/workflows/python-ci-tests.yml +++ b/.github/workflows/python-ci-tests.yml @@ -27,7 +27,8 @@ jobs: run: | tox - name: Upload coverage information to Codecov - uses: codecov/codecov-action@v1 + uses: codecov/codecov-action@v4.2.0 with: - fail_ci_if_error: true # optional (default = false) + token: ${{ secrets.CODECOV_TOKEN }} + fail_ci_if_error: false # optional (default = false) verbose: true # optional (default = false) From 280d34531cfa32436724f5e3aff702b9559f22e8 Mon Sep 17 00:00:00 2001 From: Pedro Henrique Fernandes Date: Thu, 11 Jul 2024 10:58:10 -0300 Subject: [PATCH 14/30] feat: add 'pretty' parameter to optimize JSON serialization performance --- stix2/datastore/filesystem.py | 17 +++++----- stix2/test/v21/test_datastore_filesystem.py | 36 +++++++++++++++++++++ 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/stix2/datastore/filesystem.py b/stix2/datastore/filesystem.py index 2209116a..d6f83273 100644 --- a/stix2/datastore/filesystem.py +++ b/stix2/datastore/filesystem.py @@ -554,7 +554,7 @@ def __init__(self, stix_dir, allow_custom=False, bundlify=False): def stix_dir(self): return self._stix_dir - def _check_path_and_write(self, stix_obj, encoding='utf-8'): + def _check_path_and_write(self, stix_obj, encoding='utf-8', pretty=True): """Write the given STIX object to a file in the STIX file directory. """ type_dir = os.path.join(self._stix_dir, stix_obj["type"]) @@ -585,9 +585,9 @@ def _check_path_and_write(self, stix_obj, encoding='utf-8'): raise DataSourceError("Attempted to overwrite file (!) at: {}".format(file_path)) with io.open(file_path, mode='w', encoding=encoding) as f: - fp_serialize(stix_obj, f, pretty=True, encoding=encoding, ensure_ascii=False) + fp_serialize(stix_obj, f, pretty=pretty, encoding=encoding, ensure_ascii=False) - def add(self, stix_data=None, version=None): + def add(self, stix_data=None, version=None, pretty=True): """Add STIX objects to file directory. Args: @@ -597,6 +597,7 @@ def add(self, stix_data=None, version=None): version (str): If present, it forces the parser to use the version provided. Otherwise, the library will make the best effort based on checking the "spec_version" property. + pretty (bool): If True, the resulting JSON will be "pretty printed" Note: ``stix_data`` can be a Bundle object, but each object in it will be @@ -607,24 +608,24 @@ def add(self, stix_data=None, version=None): if isinstance(stix_data, (v20.Bundle, v21.Bundle)): # recursively add individual STIX objects for stix_obj in stix_data.get("objects", []): - self.add(stix_obj, version=version) + self.add(stix_obj, version=version, pretty=pretty) elif isinstance(stix_data, _STIXBase): # adding python STIX object - self._check_path_and_write(stix_data) + self._check_path_and_write(stix_data, pretty=pretty) elif isinstance(stix_data, (str, dict)): parsed_data = parse(stix_data, allow_custom=self.allow_custom, version=version) if isinstance(parsed_data, _STIXBase): - self.add(parsed_data, version=version) + self.add(parsed_data, version=version, pretty=pretty) else: # custom unregistered object type - self._check_path_and_write(parsed_data) + self._check_path_and_write(parsed_data, pretty=pretty) elif isinstance(stix_data, list): # recursively add individual STIX objects for stix_obj in stix_data: - self.add(stix_obj) + self.add(stix_obj, version=version, pretty=pretty) else: raise TypeError( diff --git a/stix2/test/v21/test_datastore_filesystem.py b/stix2/test/v21/test_datastore_filesystem.py index 3eb20b5f..39b45578 100644 --- a/stix2/test/v21/test_datastore_filesystem.py +++ b/stix2/test/v21/test_datastore_filesystem.py @@ -151,6 +151,42 @@ def test_filesystem_source_bad_stix_file(fs_source, bad_stix_files): except STIXError as e: assert "Can't parse object with no 'type' property" in str(e) +def test_filesystem_sink_add_pretty_true(fs_sink, fs_source): + """Test adding a STIX object with pretty=True.""" + camp1 = stix2.v21.Campaign( + name="Hannibal", + objective="Targeting Italian and Spanish Diplomat internet accounts", + aliases=["War Elephant"], + ) + fs_sink.add(camp1, pretty=True) + filepath = os.path.join( + FS_PATH, "campaign", camp1.id, _timestamp2filename(camp1.modified) + ".json", + ) + assert os.path.exists(filepath) + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + assert '\n' in content # Check for pretty-printed output + + os.remove(filepath) + +def test_filesystem_sink_add_pretty_false(fs_sink, fs_source): + """Test adding a STIX object with pretty=False.""" + camp1 = stix2.v21.Campaign( + name="Hannibal", + objective="Targeting Italian and Spanish Diplomat internet accounts", + aliases=["War Elephant"], + ) + fs_sink.add(camp1, pretty=False) + filepath = os.path.join( + FS_PATH, "campaign", camp1.id, _timestamp2filename(camp1.modified) + ".json", + ) + assert os.path.exists(filepath) + with open(filepath, 'r', encoding='utf-8') as f: + content = f.read() + assert '\n' not in content # Check for non-pretty-printed output + + os.remove(filepath) + def test_filesystem_source_get_object(fs_source): # get (latest) object From 33455bd3bc18efd5e99133af2e07faa94c4657cd Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Mon, 19 Aug 2024 15:45:28 -0400 Subject: [PATCH 15/30] deterministic-id-checker --- determinsitic-id-checker.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 determinsitic-id-checker.py diff --git a/determinsitic-id-checker.py b/determinsitic-id-checker.py new file mode 100644 index 00000000..9f45a020 --- /dev/null +++ b/determinsitic-id-checker.py @@ -0,0 +1,15 @@ +import json +import stix2 + +def main(): + with open("sco-examples-bundle.json", "r", encoding="utf-8") as examples: + all_examples = json.load(examples) + for obj in all_examples: + existing_id = obj["id"] + del obj["id"] + stix_obj = stix2.parse(obj) + print(f"id {existing_id} should be {stix_obj['id']}") + + +if __name__ == "__main__": + main() \ No newline at end of file From 249b2db6d3f02971cd2c276790f1b8fb7324837f Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Tue, 20 Aug 2024 09:30:59 -0400 Subject: [PATCH 16/30] flaky --- determinsitic-id-checker.py | 2 + sco-examples-bundle.json | 917 ++++++++++++++++++++++++++++++++++++ 2 files changed, 919 insertions(+) create mode 100644 sco-examples-bundle.json diff --git a/determinsitic-id-checker.py b/determinsitic-id-checker.py index 9f45a020..67a9d8a2 100644 --- a/determinsitic-id-checker.py +++ b/determinsitic-id-checker.py @@ -1,6 +1,8 @@ import json + import stix2 + def main(): with open("sco-examples-bundle.json", "r", encoding="utf-8") as examples: all_examples = json.load(examples) diff --git a/sco-examples-bundle.json b/sco-examples-bundle.json new file mode 100644 index 00000000..eca6f64a --- /dev/null +++ b/sco-examples-bundle.json @@ -0,0 +1,917 @@ +[ + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--b4e29b62-2053-47c4-bab4-bbce39e5ed67", + "value": "198.51.100.3" + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--84445275-e371-444b-baea-ac7d07a180fd", + "value": "198.52.200.4" + }, + { + "type": "file", + "id": "file--1190f2c9-166f-55f1-9706-eea3971d8082", + "spec_version": "2.1", + "hashes": { + "MD5": "a92e5b2bae0b4b3a3d81c85610b95cd4", + "SHA-1": "5374e08903744ceeaedd8f5e1bfc06b2c4688e76" + }, + "size": 77312, + "name": "a92e5b2bae.exe", + "parent_directory_ref": "directory--255cb0e4-8bdb-5d63-bb32-9c6f0b733ab2" + }, + { + "type": "directory", + "id": "directory--255cb0e4-8bdb-5d63-bb32-9c6f0b733ab2", + "spec_version": "2.1", + "path": "C:\\" + }, + { + "type": "domain-name", + "spec_version": "2.1", + "id": "domain-name--ecb120bf-2694-4902-a737-62b74539a41b", + "value": "example.com", + "resolves_to_refs": [ + "ipv4-addr--efcd5e80-570d-4131-b213-62cb18eaa6a8" + ] + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--efcd5e80-570d-4131-b213-62cb18eaa6a8", + "value": "198.51.100.3" + }, + { + "type": "artifact", + "spec_version": "2.1", + "id": "artifact--ca17bcf8-9846-5ab4-8662-75c1bf6e63ee", + "mime_type": "image/jpeg", + "payload_bin": "VBORw0KGgoAAAANSUhEUgAAADI== ..." + }, + { + "type": "artifact", + "spec_version": "2.1", + "id": "artifact--6f437177-6e48-5cf8-9d9e-872a2bddd641", + "mime_type": "application/zip", + "payload_bin": "ZX7HIBWPQA99NSUhEUgAAADI== ...", + "encryption_algorithm": "mime-type-indicated", + "decryption_key": "My voice is my passport" + }, + { + "type": "autonomous-system", + "spec_version": "2.1", + "id": "autonomous-system--f720c34b-98ae-597f-ade5-27dc241e8c74", + "number": 15139, + "name": "Slime Industries", + "rir": "ARIN" + }, + { + "type": "directory", + "spec_version": "2.1", + "id": "directory--93c0a9b0-520d-545d-9094-1a08ddf46b05", + "path": "C:\\Windows\\System32" + }, + { + "type": "domain-name", + "spec_version": "2.1", + "id": "domain-name--3c10e93f-798e-5a26-a0c1-08156efab7f5", + "value": "example.com", + "resolves_to_refs": [ + "ipv4-addr--ff26c055-6336-5bc5-b98d-13d6226742dd" + ] + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--ff26c055-6336-5bc5-b98d-13d6226742dd", + "value": "198.51.100.3" + }, + { + "type": "email-addr", + "spec_version": "2.1", + "id": "email-addr--2d77a846-6264-5d51-b586-e43822ea1ea3", + "value": "john@example.com", + "display_name": "John Doe" + }, + { + "type": "email-message", + "spec_version": "2.1", + "id": "email-message--72b7698f-10c2-565a-a2a6-b4996a2f2265", + "from_ref": "email-addr--89f52ea8-d6ef-51e9-8fce-6a29236436ed", + "to_refs": [ + "email-addr--e4ee5301-b52d-59cd-a8fa-8036738c7194" + ], + "is_multipart": false, + "date": "1997-11-21T15:55:06.000Z", + "subject": "Saying Hello" + }, + { + "type": "email-addr", + "spec_version": "2.1", + "id": "email-addr--89f52ea8-d6ef-51e9-8fce-6a29236436ed", + "value": "jdoe@example.com", + "display_name": "John Doe" + }, + { + "type": "email-addr", + "spec_version": "2.1", + "id": "email-addr--e4ee5301-b52d-59cd-a8fa-8036738c7194", + "value": "mary@example.com", + "display_name": "Mary Smith" + }, + { + "type": "email-message", + "spec_version": "2.1", + "id": "email-message--cf9b4b7f-14c8-5955-8065-020e0316b559", + "is_multipart": true, + "received_lines": [ + "from mail.example.com ([198.51.100.3]) by smtp.gmail.com with ESMTPSA id q23sm23309939wme.17.2016.07.19.07.20.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Jul 2016 07:20:40 -0700 (PDT)" + ], + "content_type": "multipart/mixed", + "date": "2016-06-19T14:20:40.000Z", + "from_ref": "email-addr--89f52ea8-d6ef-51e9-8fce-6a29236436ed", + "to_refs": [ + "email-addr--d1b3bf0c-f02a-51a1-8102-11aba7959868" + ], + "cc_refs": [ + "email-addr--e4ee5301-b52d-59cd-a8fa-8036738c7194" + ], + "subject": "Check out this picture of a cat!", + "additional_header_fields": { + "Content-Disposition": "inline", + "X-Mailer": "Mutt/1.5.23", + "X-Originating-IP": "198.51.100.3" + }, + "body_multipart": [ + { + "content_type": "text/plain; charset=utf-8", + "content_disposition": "inline", + "body": "Cats are funny!" + }, + { + "content_type": "image/png", + "content_disposition": "attachment; filename=\"tabby.png\"", + "body_raw_ref": "artifact--4cce66f8-6eaa-53cb-85d5-3a85fca3a6c5" + }, + { + "content_type": "application/zip", + "content_disposition": "attachment; filename=\"tabby_pics.zip\"", + "body_raw_ref": "file--6ce09d9c-0ad3-5ebf-900c-e3cb288955b5" + } + ] + }, + { + "type": "email-addr", + "spec_version": "2.1", + "id": "email-addr--89f52ea8-d6ef-51e9-8fce-6a29236436ed", + "value": "jdoe@example.com", + "display_name": "John Doe" + }, + { + "type": "email-addr", + "spec_version": "2.1", + "id": "email-addr--d1b3bf0c-f02a-51a1-8102-11aba7959868", + "value": "bob@example.com", + "display_name": "Bob Smith" + }, + { + "type": "email-addr", + "spec_version": "2.1", + "id": "email-addr--e4ee5301-b52d-59cd-a8fa-8036738c7194", + "value": "mary@example.com", + "display_name": "Mary Smith" + }, + { + "type": "artifact", + "spec_version": "2.1", + "id": "artifact--4cce66f8-6eaa-53cb-85d5-3a85fca3a6c5", + "mime_type": "image/jpeg", + "payload_bin": "VBORw0KGgoAAAANSUhEUgAAADI== ...", + "hashes": { + "SHA-256": "effb46bba03f6c8aea5c653f9cf984f170dcdd3bbbe2ff6843c3e5da0e698766" + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--6ce09d9c-0ad3-5ebf-900c-e3cb288955b5", + "name": "tabby_pics.zip", + "magic_number_hex": "504B0304", + "hashes": { + "SHA-256": "fe90a7e910cb3a4739bed9180e807e93fa70c90f25a8915476f5e4bfbac681db" + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--e277603e-1060-5ad4-9937-c26c97f1ca68", + "hashes": { + "SHA-256": "fe90a7e910cb3a4739bed9180e807e93fa70c90f25a8915476f5e4bfbac681db" + }, + "size": 25536, + "name": "foo.dll" + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--90bd400b-89a5-51a5-b17d-55bc7719723b", + "hashes": { + "SHA-256": "841a8921140aba50671ebb0770fecc4ee308c4952cfeff8de154ab14eeef4649" + }, + "name": "quêry.dll", + "name_enc": "windows-1252" + }, + { + "type": "directory", + "spec_version": "2.1", + "id": "directory--93c0a9b0-520d-545d-9094-1a08ddf46b05", + "path": "C:\\Windows\\System32" + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--5a27d487-c542-5f97-a131-a8866b477b46", + "hashes": { + "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a" + }, + "parent_directory_ref": "directory--93c0a9b0-520d-545d-9094-1a08ddf46b05", + "name": "qwerty.dll" + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--019fde1c-94ca-5967-8b3c-a906a51d87ac", + "hashes": { + "SHA-256": "ceafbfd424be2ca4a5f0402cae090dda2fb0526cf521b60b60077c0f622b285a" + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--94fc2163-dec3-5715-b824-6e689c4de865", + "hashes": { + "SHA-256": "19c549ec2628b989382f6b280cbd7bb836a0b461332c0fe53511ce7d584b89d3" + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--d07ff290-d7e0-545b-a2ff-04602a9e0b73", + "hashes": { + "SHA-256": "0969de02ecf8a5f003e3f6d063d848c8a193aada092623f8ce408c15bcb5f038" + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--9a1f834d-2506-5367-baec-7aa63996ac43", + "name": "foo.zip", + "hashes": { + "SHA-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f" + }, + "mime_type": "application/zip", + "extensions": { + "archive-ext": { + "contains_refs": [ + "file--019fde1c-94ca-5967-8b3c-a906a51d87ac", + "file--94fc2163-dec3-5715-b824-6e689c4de865", + "file--d07ff290-d7e0-545b-a2ff-04602a9e0b73" + ] + } + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--73c4cd13-7206-5100-88ef-822c42d3f02c", + "hashes": { + "SHA-256": "35a01331e9ad96f751278b891b6ea09699806faedfa237d40513d92ad1b7100f" + }, + "extensions": { + "ntfs-ext": { + "alternate_data_streams": [ + { + "name": "second.stream", + "size": 25536 + } + ] + } + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--ec3415cc-5f4f-5ec8-bdb1-6f86996ae66d", + "name": "example.pdf", + "extensions": { + "pdf-ext": { + "version": "1.7", + "document_info_dict": { + "Title": "Sample document", + "Author": "Adobe Systems Incorporated", + "Creator": "Adobe FrameMaker 5.5.3 for Power Macintosh", + "Producer": "Acrobat Distiller 3.01 for Power Macintosh", + "CreationDate": "20070412090123-02" + }, + "pdfid0": "DFCE52BD827ECF765649852119D", + "pdfid1": "57A1E0F9ED2AE523E313C" + } + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--c7d1e135-8b34-549a-bb47-302f5cf998ed", + "name": "picture.jpg", + "hashes": { + "SHA-256": "4bac27393bdd9777ce02453256c5577cd02275510b2227f473d03f533924f877" + }, + "extensions": { + "raster-image-ext": { + "exif_tags": { + "Make": "Nikon", + "Model": "D7000", + "XResolution": 4928, + "YResolution": 3264 + } + } + } + }, + { + "type": "file", + "spec_version": "2.1", + "id": "file--fb0419a8-f09c-57f8-be64-71a80417591c", + "name": "example.exe", + "extensions": { + "windows-pebinary-ext": { + "pe_type": "exe", + "machine_hex": "014c", + "number_of_sections": 4, + "time_date_stamp": "2016-01-22T12:31:12Z", + "pointer_to_symbol_table_hex": "74726144", + "number_of_symbols": 4542568, + "size_of_optional_header": 224, + "characteristics_hex": "818f", + "optional_header": { + "magic_hex": "010b", + "major_linker_version": 2, + "minor_linker_version": 25, + "size_of_code": 512, + "size_of_initialized_data": 283648, + "size_of_uninitialized_data": 0, + "address_of_entry_point": 4096, + "base_of_code": 4096, + "base_of_data": 8192, + "image_base": 14548992, + "section_alignment": 4096, + "file_alignment": 4096, + "major_os_version": 1, + "minor_os_version": 0, + "major_image_version": 0, + "minor_image_version": 0, + "major_subsystem_version": 4, + "minor_subsystem_version": 0, + "win32_version_value_hex": "00", + "size_of_image": 299008, + "size_of_headers": 4096, + "checksum_hex": "00", + "subsystem_hex": "03", + "dll_characteristics_hex": "00", + "size_of_stack_reserve": 100000, + "size_of_stack_commit": 8192, + "size_of_heap_reserve": 100000, + "size_of_heap_commit": 4096, + "loader_flags_hex": "abdbffde", + "number_of_rva_and_sizes": 3758087646 + }, + "sections": [ + { + "name": "CODE", + "entropy": 0.061089 + }, + { + "name": "DATA", + "entropy": 7.980693 + }, + { + "name": "NicolasB", + "entropy": 0.607433 + }, + { + "name": ".idata", + "entropy": 0.607433 + } + ] + } + } + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--ff26c055-6336-5bc5-b98d-13d6226742dd", + "value": "198.51.100.3" + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--5853f6a4-638f-5b4e-9b0f-ded361ae3812", + "value": "198.51.100.0/24" + }, + { + "type": "ipv6-addr", + "spec_version": "2.1", + "id": "ipv6-addr--1e61d36c-a16c-53b7-a80f-2a00161c96b1", + "value": "2001:0db8:85a3:0000:0000:8a2e:0370:7334" + }, + { + "type": "ipv6-addr", + "spec_version": "2.1", + "id": "ipv6-addr--5daf7456-8863-5481-9d42-237d477697f4", + "value": "2001:0db8::/96" + }, + { + "type": "mac-addr", + "spec_version": "2.1", + "id": "mac-addr--65cfcf98-8a6e-5a1b-8f61-379ac4f92d00", + "value": "d2:fb:49:24:37:18" + }, + { + "type": "mutex", + "spec_version": "2.1", + "id": "mutex--eba44954-d4e4-5d3b-814c-2b17dd8de300", + "name": "__CLEANSWEEP__" + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "value": "198.51.100.2" + }, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--ff26c055-6336-5bc5-b98d-13d6226742dd", + "value": "198.51.100.3" + }, + { + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--2568d22a-8998-58eb-99ec-3c8ca74f527d", + "src_ref": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "dst_ref": "ipv4-addr--ff26c055-6336-5bc5-b98d-13d6226742dd", + "protocols": [ + "tcp" + ] + }, + { + "type": "domain-name", + "spec_version": "2.1", + "id": "domain-name--3c10e93f-798e-5a26-a0c1-08156efab7f5", + "value": "example.com" + }, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--15a157a8-26e3-56e0-820b-0c2a8e553a2c", + "dst_ref": "domain-name--3c10e93f-798e-5a26-a0c1-08156efab7f5", + "protocols": [ + "ipv4", + "tcp", + "http" + ] +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--e42c19c8-f9fe-5ae9-9fc8-22c398f78fb7", + "value": "203.0.113.1" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--03b708d9-7761-5523-ab75-5ea096294a68", + "value": "203.0.113.5" +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--630d7bb1-0bbc-53a6-a6d4-f3c2d35c2734", + "src_ref": "ipv4-addr--e42c19c8-f9fe-5ae9-9fc8-22c398f78fb7", + "dst_ref": "ipv4-addr--03b708d9-7761-5523-ab75-5ea096294a68", + "protocols": [ + "ipv4", + "tcp" + ], + "src_byte_count": 147600, + "src_packets": 100, + "ipfix": { + "minimumIpTotalLength": 32, + "maximumIpTotalLength": 2556 + } +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "value": "198.51.100.2" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--e42c19c8-f9fe-5ae9-9fc8-22c398f78fb7", + "value": "203.0.113.1" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--ffe65ce3-bf2a-577c-bb7e-947d39198637", + "value": "203.0.113.2" +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--ac267abc-1a41-536d-8e8d-98458d9bf491", + "src_ref": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "dst_ref": "ipv4-addr--e42c19c8-f9fe-5ae9-9fc8-22c398f78fb7", + "src_port": 2487, + "dst_port": 1723, + "protocols": [ + "ipv4", + "pptp" + ], + "src_byte_count": 35779, + "dst_byte_count": 935750, + "encapsulates_refs": [ + "network-traffic--53e0bf48-2eee-5c03-8bde-ed7049d2c0a3" + ] +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--53e0bf48-2eee-5c03-8bde-ed7049d2c0a3", + "src_ref": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "dst_ref": "ipv4-addr--ffe65ce3-bf2a-577c-bb7e-947d39198637", + "src_port": 24678, + "dst_port": 80, + "protocols": [ + "ipv4", + "tcp", + "http" + ], + "src_packets": 14356, + "dst_packets": 14356, + "encapsulated_by_ref": "network-traffic--ac267abc-1a41-536d-8e8d-98458d9bf491" +}, + { + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--e42c19c8-f9fe-5ae9-9fc8-22c398f78fb7", + "value": "203.0.113.1" + }, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--f2d3c796-6c1a-5c4f-8516-d4db54727f89", + "value": "198.51.100.34" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--bb884ffe-f2e4-56bb-a0c3-21f6711cb649", + "value": "198.51.100.54" +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--b4a8c150-e214-57a3-9017-e85dfa345f46", + "src_ref": "ipv4-addr--e42c19c8-f9fe-5ae9-9fc8-22c398f78fb7", + "dst_ref": "ipv4-addr--f2d3c796-6c1a-5c4f-8516-d4db54727f89", + "src_port": 2487, + "dst_port": 53, + "protocols": [ + "ipv4", + "udp", + "dns" + ], + "src_byte_count": 35779, + "dst_byte_count": 935750, + "encapsulates_refs": [ + "network-traffic--65a6016d-a91c-5781-baad-178cd55f01d4" + ] +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--65a6016d-a91c-5781-baad-178cd55f01d4", + "src_ref": "ipv4-addr--f2d3c796-6c1a-5c4f-8516-d4db54727f89", + "dst_ref": "ipv4-addr--bb884ffe-f2e4-56bb-a0c3-21f6711cb649", + "src_port": 24678, + "dst_port": 443, + "protocols": [ + "ipv4", + "tcp", + "ssl", + "http" + ], + "src_packets": 14356, + "dst_packets": 14356, + "encapsulated_by_ref": "network-traffic--b4a8c150-e214-57a3-9017-e85dfa345f46" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--6da8dad3-4de3-5f8e-ab23-45d0b8f12f16", + "value": "198.51.100.53" + +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--f8ae967a-3dc3-5cdf-8f94-8505abff00c2", + "dst_ref": "ipv4-addr--6da8dad3-4de3-5f8e-ab23-45d0b8f12f16", + "protocols": [ + "tcp", + "http" + ], + "extensions": { + "http-request-ext": { + "request_method": "get", + "request_value": "/download.html", + "request_version": "http/1.1", + "request_header": { + "Accept-Encoding": [ + "gzip,deflate" + ], + "User-Agent": [ + "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.6) Gecko/20040113" + ], + "Host": [ + "www.example.com" + ] + } + } + } +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--d7177770-fc12-586b-9244-426596a7008e", + "value": "198.51.100.9" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--03b708d9-7761-5523-ab75-5ea096294a68", + "value": "203.0.113.5" +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--e7a939ca-78c6-5f27-8ae0-4ad112454626", + "src_ref": "ipv4-addr--d7177770-fc12-586b-9244-426596a7008e", + "dst_ref": "ipv4-addr--03b708d9-7761-5523-ab75-5ea096294a68", + "protocols": [ + "icmp" + ], + "extensions": { + "icmp-ext": { + "icmp_type_hex": "08", + "icmp_code_hex": "00" + } + } +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "value": "198.51.100.2" +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--c95e972a-20a4-5307-b00d-b8393faf02c5", + "src_ref": "ipv4-addr--4d22aae0-2bf9-5427-8819-e4f6abf20a53", + "src_port": 223, + "protocols": [ + "ip", + "tcp" + ], + "extensions": { + "socket-ext": { + "is_listening": true, + "address_family": "AF_INET", + "socket_type": "SOCK_STREAM" + } + } +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--89830c10-2e94-57fa-8ca6-e0537d2719d1", + "value": "198.51.100.5" +}, +{ + "type": "ipv4-addr", + "spec_version": "2.1", + "id": "ipv4-addr--45f4c6fb-2d7d-576a-a571-edc78d899a72", + "value": "198.51.100.6" +}, +{ + "type": "network-traffic", + "spec_version": "2.1", + "id": "network-traffic--09ca55c3-97e5-5966-bad0-1d41d557ae13", + "src_ref": "ipv4-addr--89830c10-2e94-57fa-8ca6-e0537d2719d1", + "dst_ref": "ipv4-addr--45f4c6fb-2d7d-576a-a571-edc78d899a72", + "src_port": 3372, + "dst_port": 80, + "protocols": [ + "tcp" + ], + "extensions": { + "tcp-ext": { + "src_flags_hex": "00000002" + } + } +}, +{ + "type": "file", + "spec_version": "2.1", + "id": "file--edb1ebee-4387-41cc-943b-f94fd491118c", + "name": "gedit-bin", + "hashes": { + "SHA-256": "aec070645fe53ee3b3763059376134f058cc337247c978add178b6ccdfb0019f" + } +}, +{ + "type": "process", + "spec_version": "2.1", + "id": "process--d2ec5aab-808d-4492-890a-3c1a1e3cb06e", + "pid": 1221, + "created_time": "2016-01-20T14:11:25.55Z", + "command_line": "./gedit-bin --new-window", + "image_ref": "file--e04f22d1-be2c-59de-add8-10f61d15fe20" +}, +{ + "type": "process", + "spec_version": "2.1", + "id": "process--de02a3e4-4b96-460a-b799-684347004444", + "pid": 314, + "extensions": { + "windows-process-ext": { + "aslr_enabled": true, + "dep_enabled": true, + "priority": "HIGH_PRIORITY_CLASS", + "owner_sid": "S-1-5-21-186985262-1144665072-74031268-1309" + } + } +}, +{ + "type": "file", + "spec_version": "2.1", + "id": "file--4b9a516b-4974-4ff8-a50d-a8b8d552ce1f", + "hashes": { + "SHA-256": "bf07a7fbb825fc0aae7bf4a1177b2b31fcf8a3feeaf7092761e18c859ee52a9c" + }, + "name": "sirvizio.exe" +}, +{ + "type": "process", + "spec_version": "2.1", + "id": "process--70b17c6c-93e5-4c80-8683-5a4d4e51f2c1", + "pid": 2217, + "command_line": "C:\\Windows\\System32\\sirvizio.exe /s", + "image_ref": "file--3916128d-69af-5525-be7a-99fac2383a59", + "extensions": { + "windows-service-ext": { + "service_name": "sirvizio", + "display_name": "Sirvizio", + "start_type": "SERVICE_AUTO_START", + "service_type": "SERVICE_WIN32_OWN_PROCESS", + "service_status": "SERVICE_RUNNING" + } + } +}, +{ + "type": "software", + "spec_version": "2.1", + "id": "software--a1827f6d-ca53-5605-9e93-4316cd22a00a", + "name": "Word", + "cpe": "cpe:2.3:a:microsoft:word:2000:*:*:*:*:*:*:*", + "version": "2002", + "vendor": "Microsoft" +}, +{ + "type": "url", + "spec_version": "2.1", + "id": "url--c1477287-23ac-5971-a010-5c287877fa60", + "value": "https://example.com/research/index.html" +}, +{ + "type": "user-account", + "spec_version": "2.1", + "id": "user-account--0d5b424b-93b8-5cd8-ac36-306e1789d63c", + "user_id": "1001", + "account_login": "jdoe", + "account_type": "unix", + "display_name": "John Doe", + "is_service_account": false, + "is_privileged": false, + "can_escalate_privs": true, + "account_created": "2016-01-20T12:31:12Z", + "credential_last_changed": "2016-01-20T14:27:43Z", + "account_first_login": "2016-01-20T14:26:07Z", + "account_last_login": "2016-07-22T16:08:28Z" +}, +{ + "type": "user-account", + "spec_version": "2.1", + "id": "user-account--9bd3afcf-deee-54f9-83e2-520653cb6bba", + "user_id": "thegrugq_ebooks", + "account_login": "thegrugq_ebooks", + "account_type": "twitter", + "display_name": "the grugq" + }, + { + "type": "user-account", + "spec_version": "2.1", + "id": "user-account--0d5b424b-93b8-5cd8-ac36-306e1789d63c", + "user_id": "1001", + "account_login": "jdoe", + "account_type": "unix", + "display_name": "John Doe", + "is_service_account": false, + "is_privileged": false, + "can_escalate_privs": true, + "extensions": { + "unix-account-ext": { + "gid": 1001, + "groups": ["wheel"], + "home_dir": "/home/jdoe", + "shell": "/bin/bash" + } + } +}, +{ + "type": "windows-registry-key", + "spec_version": "2.1", + "id": "windows-registry-key--9d60798d-4e3e-5fe4-af8a-0e4986f0f90b", + "key": "HKEY_LOCAL_MACHINE\\System\\Foo\\Bar" + }, + { + "type": "windows-registry-key", + "spec_version": "2.1", + "id": "windows-registry-key--2ba37ae7-2745-5082-9dfd-9486dad41016", + "key": "hkey_local_machine\\system\\bar\\foo", + "values": [ + { + "name": "Foo", + "data": "qwerty", + "data_type": "REG_SZ" + }, + { + "name": "Bar", + "data": "42", + "data_type": "REG_DWORD" + } + ] +}, +{ + "type": "x509-certificate", + "spec_version": "2.1", + "id": "x509-certificate--463d7b2a-8516-5a50-a3d7-6f801465d5de", + "issuer": "C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com", + "validity_not_before": "2016-03-12T12:00:00Z", + "validity_not_after": "2016-08-21T12:00:00Z", + "subject": "C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=baccala@freesoft.org", + "serial_number": "36:f7:d4:32:f4:ab:70:ea:d3:ce:98:6e:ea:99:93:49:32:0a:b7:06" +}, +{ + "type":"x509-certificate", + "spec_version": "2.1", + "id": "x509-certificate--b595eaf0-0b28-5dad-9e8e-0fab9c1facc9", + "issuer":"C=ZA, ST=Western Cape, L=Cape Town, O=Thawte Consulting cc, OU=Certification Services Division, CN=Thawte Server CA/emailAddress=server-certs@thawte.com", + "validity_not_before":"2016-03-12T12:00:00Z", + "validity_not_after":"2016-08-21T12:00:00Z", + "subject":"C=US, ST=Maryland, L=Pasadena, O=Brent Baccala, OU=FreeSoft, CN=www.freesoft.org/emailAddress=baccala@freesoft.org", + "serial_number": "02:08:87:83:f2:13:58:1f:79:52:1e:66:90:0a:02:24:c9:6b:c7:dc", + "x509_v3_extensions":{ + "basic_constraints":"critical,CA:TRUE, pathlen:0", + "name_constraints":"permitted;IP:192.168.0.0/255.255.0.0", + "policy_constraints":"requireExplicitPolicy:3", + "key_usage":"critical, keyCertSign", + "extended_key_usage":"critical,codeSigning,1.2.3.4", + "subject_key_identifier":"hash", + "authority_key_identifier":"keyid,issuer", + "subject_alternative_name":"email:my@other.address,RID:1.2.3.4", + "issuer_alternative_name":"issuer:copy", + "crl_distribution_points":"URI:http://myhost.com/myca.crl", + "inhibit_any_policy":"2", + "private_key_usage_period_not_before":"2016-03-12T12:00:00Z", + "private_key_usage_period_not_after":"2018-03-12T12:00:00Z", + "certificate_policies":"1.2.4.5, 1.1.3.4" + } +} +] From fa8c95bba783c9dce8e2c56391077aee22767553 Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Tue, 20 Aug 2024 11:07:13 -0400 Subject: [PATCH 17/30] flaky2 --- determinsitic-id-checker.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/determinsitic-id-checker.py b/determinsitic-id-checker.py index 67a9d8a2..c657af20 100644 --- a/determinsitic-id-checker.py +++ b/determinsitic-id-checker.py @@ -14,4 +14,4 @@ def main(): if __name__ == "__main__": - main() \ No newline at end of file + main() From d2d7161fb54a7c231ccb8d3495ff1af46dc931bb Mon Sep 17 00:00:00 2001 From: Ming Fang Date: Thu, 19 Sep 2024 14:41:50 -0400 Subject: [PATCH 18/30] Fix issue #586. --- stix2/v21/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stix2/v21/common.py b/stix2/v21/common.py index 55c4a05d..103fff7d 100644 --- a/stix2/v21/common.py +++ b/stix2/v21/common.py @@ -77,7 +77,7 @@ class GranularMarking(_STIXBase21): def _check_object_constraints(self): super(GranularMarking, self)._check_object_constraints() self._check_at_least_one_property(['lang', 'marking_ref']) - + self._check_mutually_exclusive_properties(['lang', 'marking_ref']) class LanguageContent(_STIXBase21): """For more detailed information on this object's properties, see From 6299ff9b38d6d6543930654a61bb4e27f7c00fcc Mon Sep 17 00:00:00 2001 From: Ming Fang Date: Fri, 20 Sep 2024 15:54:41 -0400 Subject: [PATCH 19/30] Add v21 test for GranularMarking to close #586. --- stix2/test/v21/test_markings.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index d3fd11bb..47925499 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -170,6 +170,18 @@ def test_granular_example_with_bad_selector(): assert str(excinfo.value) == "Invalid value for GranularMarking 'selectors': must adhere to selector syntax." +def test_granular_marking_mutual_exclusion_error(): + with pytest.raises(stix2.exceptions.MutuallyExclusivePropertiesError) as excinfo: + stix2.v21.GranularMarking( + lang="en", + marking_ref=stix2.TLP_GREEN, + selectors=["foo"] + ) + assert excinfo.value.cls == stix2.v21.GranularMarking + assert excinfo.value.properties == ["lang", "marking_ref"] + assert 'are mutually exclusive' in str(excinfo.value) + + def test_campaign_with_granular_markings_example(): campaign = stix2.v21.Campaign( id="campaign--8e2e2d2b-17d4-4cbf-938f-98ee46b3cd3f", From 12ada44a63bfc5bbcab1687e81602223c7cecebe Mon Sep 17 00:00:00 2001 From: Ming Fang Date: Tue, 24 Sep 2024 17:10:24 -0400 Subject: [PATCH 20/30] Add trailing comma expected by the pre-commit hook. --- stix2/test/v21/test_markings.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stix2/test/v21/test_markings.py b/stix2/test/v21/test_markings.py index 47925499..0b2e950e 100644 --- a/stix2/test/v21/test_markings.py +++ b/stix2/test/v21/test_markings.py @@ -175,7 +175,7 @@ def test_granular_marking_mutual_exclusion_error(): stix2.v21.GranularMarking( lang="en", marking_ref=stix2.TLP_GREEN, - selectors=["foo"] + selectors=["foo"], ) assert excinfo.value.cls == stix2.v21.GranularMarking assert excinfo.value.properties == ["lang", "marking_ref"] From a2beb46f35ea070b483c61e2bc94e66ba97c440e Mon Sep 17 00:00:00 2001 From: Ming Fang Date: Wed, 25 Sep 2024 11:53:29 -0400 Subject: [PATCH 21/30] Add extra blank line to make pre-commit happy. --- stix2/v21/common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/stix2/v21/common.py b/stix2/v21/common.py index 103fff7d..ca795e02 100644 --- a/stix2/v21/common.py +++ b/stix2/v21/common.py @@ -79,6 +79,7 @@ def _check_object_constraints(self): self._check_at_least_one_property(['lang', 'marking_ref']) self._check_mutually_exclusive_properties(['lang', 'marking_ref']) + class LanguageContent(_STIXBase21): """For more detailed information on this object's properties, see `the STIX 2.1 specification `__. From 294e54a6d12bb557595b9ac2aa53d4f080dd9144 Mon Sep 17 00:00:00 2001 From: HackerShark Date: Wed, 16 Oct 2024 10:37:02 -0400 Subject: [PATCH 22/30] fixing the logic for the longitude and latitude being 0. Now it won't error on those values Signed-off-by: HackerShark --- stix2/base.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stix2/base.py b/stix2/base.py index 3ff01d98..078a7cb0 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -103,7 +103,8 @@ def _check_properties_dependency(self, list_of_properties, list_of_dependent_pro failed_dependency_pairs = [] for p in list_of_properties: for dp in list_of_dependent_properties: - if not self.get(p) and self.get(dp): + if self.get(p) is None and self.get(dp) is not None: + # if not self.get(p) and self.get(dp): failed_dependency_pairs.append((p, dp)) if failed_dependency_pairs: raise DependentPropertiesError(self.__class__, failed_dependency_pairs) From 4a659b56bcc4fe6baa43e3abfd1e0579befa39ed Mon Sep 17 00:00:00 2001 From: HackerShark Date: Thu, 17 Oct 2024 13:27:31 -0400 Subject: [PATCH 23/30] removed commented line in base.py. added tests for 0 value longitude and latitude Signed-off-by: HackerShark --- stix2/base.py | 1 - stix2/test/v21/test_location.py | 42 +++++++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 1 deletion(-) diff --git a/stix2/base.py b/stix2/base.py index 078a7cb0..6511f805 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -104,7 +104,6 @@ def _check_properties_dependency(self, list_of_properties, list_of_dependent_pro for p in list_of_properties: for dp in list_of_dependent_properties: if self.get(p) is None and self.get(dp) is not None: - # if not self.get(p) and self.get(dp): failed_dependency_pairs.append((p, dp)) if failed_dependency_pairs: raise DependentPropertiesError(self.__class__, failed_dependency_pairs) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 5d3eab8a..616d7711 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -377,3 +377,45 @@ def test_bing_map_url_multiple_props_and_long_lat_provided(): loc_url = loc.to_maps_url("Bing Maps") assert loc_url == expected_url + +def test_bing_map_url_for_0_long_lat(): + expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C0.0&lvl=16" + + loc = stix2.v21.Location( + region="northern-america", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=0, + longitude=-0, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == expected_url + +def test_bing_map_url_for_0_long(): + expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C-348.2&lvl=16" + + loc = stix2.v21.Location( + region="northern-america", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=0, + longitude=-348.2, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == expected_url + +def test_bing_map_url_for_0_lat(): + expected_url = "https://bing.com/maps/default.aspx?where1=84.2%2C0.0&lvl=16" + + loc = stix2.v21.Location( + region="northern-america", + country="United States of America", + street_address="1410 Museum Campus Drive, Chicago, IL 60605", + latitude=84.2, + longitude=-0, + ) + + loc_url = loc.to_maps_url("Bing Maps") + assert loc_url == expected_url From 9ff9b3f9e404b4b4cae4971d671286c3d630fa63 Mon Sep 17 00:00:00 2001 From: HackerShark Date: Thu, 17 Oct 2024 14:02:49 -0400 Subject: [PATCH 24/30] fixing tests by making the long and lat a float instead of integers Signed-off-by: HackerShark --- stix2/test/v21/test_location.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 616d7711..a27aacb8 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -385,8 +385,8 @@ def test_bing_map_url_for_0_long_lat(): region="northern-america", country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", - latitude=0, - longitude=-0, + latitude=0.0, + longitude=-0.0, ) loc_url = loc.to_maps_url("Bing Maps") @@ -399,7 +399,7 @@ def test_bing_map_url_for_0_long(): region="northern-america", country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", - latitude=0, + latitude=0.0, longitude=-348.2, ) @@ -414,7 +414,7 @@ def test_bing_map_url_for_0_lat(): country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", latitude=84.2, - longitude=-0, + longitude=-0.0, ) loc_url = loc.to_maps_url("Bing Maps") From d824c0ba5437a19021d4efdd938ebd97b1f74c3d Mon Sep 17 00:00:00 2001 From: HackerShark Date: Thu, 17 Oct 2024 14:04:44 -0400 Subject: [PATCH 25/30] updating longitude value in one of the tests Signed-off-by: HackerShark --- stix2/test/v21/test_location.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index a27aacb8..782b9a6f 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -414,7 +414,7 @@ def test_bing_map_url_for_0_lat(): country="United States of America", street_address="1410 Museum Campus Drive, Chicago, IL 60605", latitude=84.2, - longitude=-0.0, + longitude=0.0, ) loc_url = loc.to_maps_url("Bing Maps") From a440d343893b28124b814db335afcb5f9c8b679b Mon Sep 17 00:00:00 2001 From: HackerShark Date: Fri, 18 Oct 2024 10:25:05 -0400 Subject: [PATCH 26/30] fixed the tests, now they all pass Signed-off-by: HackerShark --- stix2/test/v21/test_location.py | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index 782b9a6f..c3a167e8 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -382,38 +382,38 @@ def test_bing_map_url_for_0_long_lat(): expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C0.0&lvl=16" loc = stix2.v21.Location( - region="northern-america", - country="United States of America", - street_address="1410 Museum Campus Drive, Chicago, IL 60605", + region="Gulf of Guinea", + country="International waters", + street_address="0°N, 0°E – Null Island", latitude=0.0, - longitude=-0.0, + longitude=0.0, ) loc_url = loc.to_maps_url("Bing Maps") assert loc_url == expected_url def test_bing_map_url_for_0_long(): - expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C-348.2&lvl=16" + expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C39.668&lvl=16" loc = stix2.v21.Location( - region="northern-america", - country="United States of America", - street_address="1410 Museum Campus Drive, Chicago, IL 60605", + region="Eastern Africa", + country="Kenya", + street_address="0°N, 39.668°E", latitude=0.0, - longitude=-348.2, + longitude=39.668, ) loc_url = loc.to_maps_url("Bing Maps") assert loc_url == expected_url def test_bing_map_url_for_0_lat(): - expected_url = "https://bing.com/maps/default.aspx?where1=84.2%2C0.0&lvl=16" + expected_url = "https://bing.com/maps/default.aspx?where1=51.477%2C0.0&lvl=16" loc = stix2.v21.Location( - region="northern-america", - country="United States of America", - street_address="1410 Museum Campus Drive, Chicago, IL 60605", - latitude=84.2, + region="Western Europe", + country="United Kingdom", + street_address="Royal Observatory, Blackheath Ave, Greenwich, London SE10 8XJ, United Kingdom", + latitude=51.477, longitude=0.0, ) From 7665f23184c2441df4836c720792e1988932dcbd Mon Sep 17 00:00:00 2001 From: HackerShark Date: Fri, 25 Oct 2024 10:14:07 -0400 Subject: [PATCH 27/30] Issue with old code was it checks for None specifically, this change in behavior caused the fail because is_encrypted is set to False which is a falsy value. Adjusted the code to handle both None and other falsy values Signed-off-by: HackerShark --- stix2/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stix2/base.py b/stix2/base.py index 6511f805..79de2b6a 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -103,7 +103,7 @@ def _check_properties_dependency(self, list_of_properties, list_of_dependent_pro failed_dependency_pairs = [] for p in list_of_properties: for dp in list_of_dependent_properties: - if self.get(p) is None and self.get(dp) is not None: + if (self.get(p) is None or self.get(p) is False) and self.get(dp) is not None: failed_dependency_pairs.append((p, dp)) if failed_dependency_pairs: raise DependentPropertiesError(self.__class__, failed_dependency_pairs) From 5629e7cc9034a53231230e5e6d023f5c1ba0dea9 Mon Sep 17 00:00:00 2001 From: HackerShark Date: Fri, 25 Oct 2024 15:20:01 -0400 Subject: [PATCH 28/30] fixing spacing between functions to address styling issues Signed-off-by: HackerShark --- stix2/test/v21/test_location.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stix2/test/v21/test_location.py b/stix2/test/v21/test_location.py index c3a167e8..e5d3f862 100644 --- a/stix2/test/v21/test_location.py +++ b/stix2/test/v21/test_location.py @@ -378,6 +378,7 @@ def test_bing_map_url_multiple_props_and_long_lat_provided(): loc_url = loc.to_maps_url("Bing Maps") assert loc_url == expected_url + def test_bing_map_url_for_0_long_lat(): expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C0.0&lvl=16" @@ -392,6 +393,7 @@ def test_bing_map_url_for_0_long_lat(): loc_url = loc.to_maps_url("Bing Maps") assert loc_url == expected_url + def test_bing_map_url_for_0_long(): expected_url = "https://bing.com/maps/default.aspx?where1=0.0%2C39.668&lvl=16" @@ -406,6 +408,7 @@ def test_bing_map_url_for_0_long(): loc_url = loc.to_maps_url("Bing Maps") assert loc_url == expected_url + def test_bing_map_url_for_0_lat(): expected_url = "https://bing.com/maps/default.aspx?where1=51.477%2C0.0&lvl=16" From d7b14cb6a52a6eec03aa16b8ee3dfb31b8815d87 Mon Sep 17 00:00:00 2001 From: HackerShark Date: Thu, 7 Nov 2024 14:05:12 -0500 Subject: [PATCH 29/30] fixing _default_properties_dependency to check for the presence of the property that way it won't incorrectly raise a DependentPropertiesError Signed-off-by: HackerShark --- stix2/base.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/stix2/base.py b/stix2/base.py index 79de2b6a..a4f3f03b 100644 --- a/stix2/base.py +++ b/stix2/base.py @@ -103,7 +103,9 @@ def _check_properties_dependency(self, list_of_properties, list_of_dependent_pro failed_dependency_pairs = [] for p in list_of_properties: for dp in list_of_dependent_properties: - if (self.get(p) is None or self.get(p) is False) and self.get(dp) is not None: + if p not in self and dp in self: + failed_dependency_pairs.append((p, dp)) + elif p in self and (self[p] is None or self[p] is False) and dp in self and self[dp] is not None: failed_dependency_pairs.append((p, dp)) if failed_dependency_pairs: raise DependentPropertiesError(self.__class__, failed_dependency_pairs) From b5ffcc17a8c598b1daa70189b9b1c497aea16315 Mon Sep 17 00:00:00 2001 From: Rich Piazza Date: Mon, 2 Dec 2024 09:48:45 -0500 Subject: [PATCH 30/30] flaky fix --- stix2/test/v21/test_datastore_filesystem.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/stix2/test/v21/test_datastore_filesystem.py b/stix2/test/v21/test_datastore_filesystem.py index 39b45578..037146e6 100644 --- a/stix2/test/v21/test_datastore_filesystem.py +++ b/stix2/test/v21/test_datastore_filesystem.py @@ -151,6 +151,7 @@ def test_filesystem_source_bad_stix_file(fs_source, bad_stix_files): except STIXError as e: assert "Can't parse object with no 'type' property" in str(e) + def test_filesystem_sink_add_pretty_true(fs_sink, fs_source): """Test adding a STIX object with pretty=True.""" camp1 = stix2.v21.Campaign( @@ -169,6 +170,7 @@ def test_filesystem_sink_add_pretty_true(fs_sink, fs_source): os.remove(filepath) + def test_filesystem_sink_add_pretty_false(fs_sink, fs_source): """Test adding a STIX object with pretty=False.""" camp1 = stix2.v21.Campaign(