From 5c92db9861a9266a447b1a5199a7256dede22536 Mon Sep 17 00:00:00 2001 From: Michael Chisholm Date: Wed, 26 Jun 2019 17:06:26 -0400 Subject: [PATCH 1/3] Add stix2.1 malware-analysis SDO --- stix2/v21/__init__.py | 5 +++-- stix2/v21/sdo.py | 43 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/stix2/v21/__init__.py b/stix2/v21/__init__.py index 4a8fe29..f0131d1 100644 --- a/stix2/v21/__init__.py +++ b/stix2/v21/__init__.py @@ -21,8 +21,8 @@ from .observables import ( ) from .sdo import ( AttackPattern, Campaign, CourseOfAction, CustomObject, Identity, Indicator, - IntrusionSet, Location, Malware, Note, ObservedData, Opinion, Report, - ThreatActor, Tool, Vulnerability, + IntrusionSet, Location, Malware, MalwareAnalysis, Note, ObservedData, + Opinion, Report, ThreatActor, Tool, Vulnerability, ) from .sro import Relationship, Sighting @@ -37,6 +37,7 @@ OBJ_MAP = { 'language-content': LanguageContent, 'location': Location, 'malware': Malware, + 'malware-analysis': MalwareAnalysis, 'note': Note, 'marking-definition': MarkingDefinition, 'observed-data': ObservedData, diff --git a/stix2/v21/sdo.py b/stix2/v21/sdo.py index ffdc5e1..526c982 100644 --- a/stix2/v21/sdo.py +++ b/stix2/v21/sdo.py @@ -304,6 +304,49 @@ class Malware(STIXDomainObject): ]) +class MalwareAnalysis(STIXDomainObject): + # TODO: Add link + """For more detailed information on this object's properties, see + `the STIX 2.1 specification `__. + """ + + _type = 'malware-analysis' + _properties = OrderedDict([ + ('type', TypeProperty(_type)), + ('spec_version', StringProperty(fixed='2.1')), + ('id', IDProperty(_type, spec_version='2.1')), + ('created', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('modified', TimestampProperty(default=lambda: NOW, precision='millisecond')), + ('created_by_ref', ReferenceProperty(type='identity', spec_version='2.1')), + ('revoked', BooleanProperty(default=lambda: False)), + ('labels', ListProperty(StringProperty)), + ('confidence', IntegerProperty()), + ('lang', StringProperty()), + ('external_references', ListProperty(ExternalReference)), + ('object_marking_refs', ListProperty(ReferenceProperty(type='marking-definition', spec_version='2.1'))), + ('granular_markings', ListProperty(GranularMarking)), + ('product', StringProperty(required=True)), + ('version', StringProperty()), + ('host_vm_ref', ReferenceProperty(type='software', spec_version='2.1')), + ('operating_system_ref', ReferenceProperty(type='software', spec_version='2.1')), + ('installed_software_refs', ListProperty(ReferenceProperty(type='software', spec_version='2.1'))), + ('configuration_version', StringProperty()), + ('module', StringProperty()), + ('analysis_engine_version', StringProperty()), + ('analysis_definition_version', StringProperty()), + ('submitted', TimestampProperty()), + ('analysis_started', TimestampProperty()), + ('analysis_ended', TimestampProperty()), + ('av_result', StringProperty()), + ('analysis_sco_refs', ListProperty(ReferenceProperty(spec_version='2.1'))), + ]) + + def _check_object_constraints(self): + super(MalwareAnalysis, self)._check_object_constraints() + + self._check_at_least_one_property(["av_result", "analysis_sco_refs"]) + + class Note(STIXDomainObject): # TODO: Add link """For more detailed information on this object's properties, see From 68f93f4110f526d9426bf791d2c004373f1d6c06 Mon Sep 17 00:00:00 2001 From: Michael Chisholm Date: Wed, 26 Jun 2019 17:10:04 -0400 Subject: [PATCH 2/3] Oops, forgot to add the malware-analysis test suite... --- stix2/test/v21/test_malware_analysis.py | 80 +++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 stix2/test/v21/test_malware_analysis.py diff --git a/stix2/test/v21/test_malware_analysis.py b/stix2/test/v21/test_malware_analysis.py new file mode 100644 index 0000000..5192317 --- /dev/null +++ b/stix2/test/v21/test_malware_analysis.py @@ -0,0 +1,80 @@ +import json +import pytest + +import stix2.exceptions +import stix2.utils +import stix2.v21 + + +MALWARE_ANALYSIS_JSON = """{ + "type": "malware-analysis", + "spec_version": "2.1", + "id": "malware-analysis--f8afc020-f92f-4906-a971-88ee5882eb46", + "created": "2017-11-28T09:44:58.418Z", + "modified": "2017-12-31T21:27:49.754Z", + "created_by_ref": "identity--e0353ed3-991e-4f71-a332-114c2f10b84f", + "labels": [ + "label1", + "label2" + ], + "product": "Acme Malware Analyzer", + "version": "2.5", + "host_vm_ref": "software--1bda7336-fe67-469f-a8ca-ab6268b0449b", + "operating_system_ref": "software--c96bfaef-861b-408b-b0f1-b685881725ef", + "installed_software_refs": [ + "software--7325bf2d-de9e-441e-b3b3-63df43149897", + "software--46a6a91d-1160-4867-a4d1-b14e080e4e5b" + ], + "configuration_version": "1.7", + "module": "Super Analyzer", + "analysis_engine_version": "1.2", + "analysis_definition_version": "3.4", + "submitted": "2018-11-23T06:45:55.747Z", + "analysis_started": "2018-11-29T07:30:03.895Z", + "analysis_ended": "2018-11-29T08:30:03.895Z", + "av_result": "malicious", + "analysis_sco_refs": [ + "file--fc27e371-6c88-4c5c-868a-4dda0e60b167", + "url--6f7a74cd-8eb2-4b88-a4da-aa878e50ac2e" + ] +}""" + + +MALWARE_ANALYSIS_DICT = json.loads(MALWARE_ANALYSIS_JSON) + + +def test_malware_analysis_example(): + ma = stix2.v21.MalwareAnalysis(**MALWARE_ANALYSIS_DICT) + + assert str(ma) == MALWARE_ANALYSIS_JSON + + +@pytest.mark.parametrize("data", [ + MALWARE_ANALYSIS_JSON, + MALWARE_ANALYSIS_DICT +]) +def test_parse_malware_analysis(data): + ma = stix2.parse(data, version="2.1") + + # timestamp-valued attributes whose values (from JSON) can't be compared + # directly, since stix2 internally converts them to datetime objects. + ts_attrs = { + "created", + "modified", + "submitted", + "analysis_started", + "analysis_ended", + } + + for attr_name, attr_value in MALWARE_ANALYSIS_DICT.items(): + cmp_value = stix2.utils.parse_into_datetime(attr_value) \ + if attr_name in ts_attrs else attr_value + + assert getattr(ma, attr_name) == cmp_value + + +def test_malware_analysis_constraint(): + with pytest.raises(stix2.exceptions.AtLeastOnePropertyError): + stix2.v21.MalwareAnalysis( + product="Acme Malware Analyzer" + ) From c6132537b86e757e4f458de54dea71712cd2b5f4 Mon Sep 17 00:00:00 2001 From: Michael Chisholm Date: Wed, 26 Jun 2019 17:17:16 -0400 Subject: [PATCH 3/3] Changes from add-trailing-comma hook --- stix2/test/v21/test_malware_analysis.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/stix2/test/v21/test_malware_analysis.py b/stix2/test/v21/test_malware_analysis.py index 5192317..42db919 100644 --- a/stix2/test/v21/test_malware_analysis.py +++ b/stix2/test/v21/test_malware_analysis.py @@ -1,11 +1,11 @@ import json + import pytest import stix2.exceptions import stix2.utils import stix2.v21 - MALWARE_ANALYSIS_JSON = """{ "type": "malware-analysis", "spec_version": "2.1", @@ -49,10 +49,12 @@ def test_malware_analysis_example(): assert str(ma) == MALWARE_ANALYSIS_JSON -@pytest.mark.parametrize("data", [ - MALWARE_ANALYSIS_JSON, - MALWARE_ANALYSIS_DICT -]) +@pytest.mark.parametrize( + "data", [ + MALWARE_ANALYSIS_JSON, + MALWARE_ANALYSIS_DICT, + ], +) def test_parse_malware_analysis(data): ma = stix2.parse(data, version="2.1") @@ -76,5 +78,5 @@ def test_parse_malware_analysis(data): def test_malware_analysis_constraint(): with pytest.raises(stix2.exceptions.AtLeastOnePropertyError): stix2.v21.MalwareAnalysis( - product="Acme Malware Analyzer" + product="Acme Malware Analyzer", )