cti-python-stix2/stix2/test/test_malware.py

162 lines
5.2 KiB
Python
Raw Normal View History

2017-03-22 13:46:39 +01:00
import datetime as dt
import re
2017-03-22 13:46:39 +01:00
import pytest
import pytz
2017-03-22 13:46:39 +01:00
import stix2
from .constants import FAKE_TIME, MALWARE_ID, MALWARE_KWARGS
EXPECTED_MALWARE = """{
"type": "malware",
2017-03-22 13:46:39 +01:00
"id": "malware--fedcba98-7654-3210-fedc-ba9876543210",
"created": "2016-05-12T08:17:27.000Z",
"modified": "2016-05-12T08:17:27.000Z",
2017-03-22 13:46:39 +01:00
"name": "Cryptolocker",
"labels": [
"ransomware"
]
2017-03-22 13:46:39 +01:00
}"""
def test_malware_with_all_required_properties():
2017-03-22 13:46:39 +01:00
now = dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
2017-03-22 14:05:59 +01:00
mal = stix2.Malware(
2017-03-22 13:46:39 +01:00
type="malware",
id=MALWARE_ID,
created=now,
modified=now,
labels=["ransomware"],
name="Cryptolocker",
)
2017-03-22 14:05:59 +01:00
assert str(mal) == EXPECTED_MALWARE
2017-03-22 13:46:39 +01:00
def test_malware_autogenerated_properties(malware):
2017-03-22 13:46:39 +01:00
assert malware.type == 'malware'
assert malware.id == 'malware--00000000-0000-0000-0000-000000000001'
assert malware.created == FAKE_TIME
assert malware.modified == FAKE_TIME
assert malware.labels == ['ransomware']
assert malware.name == "Cryptolocker"
assert malware['type'] == 'malware'
assert malware['id'] == 'malware--00000000-0000-0000-0000-000000000001'
assert malware['created'] == FAKE_TIME
assert malware['modified'] == FAKE_TIME
assert malware['labels'] == ['ransomware']
assert malware['name'] == "Cryptolocker"
def test_malware_type_must_be_malware():
2017-04-18 21:42:59 +02:00
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
2017-03-22 14:05:59 +01:00
stix2.Malware(type='xxx', **MALWARE_KWARGS)
2017-03-22 13:46:39 +01:00
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.prop_name == "type"
assert excinfo.value.reason == "must equal 'malware'."
2017-03-22 13:46:39 +01:00
assert str(excinfo.value) == "Invalid value for Malware 'type': must equal 'malware'."
def test_malware_id_must_start_with_malware():
2017-04-18 21:42:59 +02:00
with pytest.raises(stix2.exceptions.InvalidValueError) as excinfo:
2017-03-22 14:05:59 +01:00
stix2.Malware(id='my-prefix--', **MALWARE_KWARGS)
2017-03-22 13:46:39 +01:00
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.prop_name == "id"
assert excinfo.value.reason == "must start with 'malware--'."
2017-03-22 13:46:39 +01:00
assert str(excinfo.value) == "Invalid value for Malware 'id': must start with 'malware--'."
def test_malware_required_properties():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
2017-03-22 14:05:59 +01:00
stix2.Malware()
2017-04-18 21:41:18 +02:00
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.properties == ["labels", "name"]
2017-03-22 13:46:39 +01:00
def test_malware_required_property_name():
with pytest.raises(stix2.exceptions.MissingPropertiesError) as excinfo:
2017-03-22 14:05:59 +01:00
stix2.Malware(labels=['ransomware'])
2017-04-18 21:41:18 +02:00
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.properties == ["name"]
2017-03-22 13:46:39 +01:00
2017-04-07 22:36:42 +02:00
def test_cannot_assign_to_malware_attributes(malware):
with pytest.raises(stix2.exceptions.ImmutableError) as excinfo:
2017-03-22 13:46:39 +01:00
malware.name = "Cryptolocker II"
2017-06-02 13:34:37 +02:00
assert str(excinfo.value) == "Cannot modify 'name' property in 'Malware' after creation."
2017-03-22 13:46:39 +01:00
def test_invalid_kwarg_to_malware():
with pytest.raises(stix2.exceptions.ExtraPropertiesError) as excinfo:
2017-03-22 14:05:59 +01:00
stix2.Malware(my_custom_property="foo", **MALWARE_KWARGS)
assert excinfo.value.cls == stix2.Malware
assert excinfo.value.properties == ['my_custom_property']
assert str(excinfo.value) == "Unexpected properties for Malware: (my_custom_property)."
2017-04-05 23:12:44 +02:00
@pytest.mark.parametrize("data", [
EXPECTED_MALWARE,
{
"type": "malware",
"id": "malware--fedcba98-7654-3210-fedc-ba9876543210",
"created": "2016-05-12T08:17:27.000Z",
"modified": "2016-05-12T08:17:27.000Z",
"labels": ["ransomware"],
"name": "Cryptolocker",
},
])
def test_parse_malware(data):
mal = stix2.parse(data)
2017-04-05 23:12:44 +02:00
assert mal.type == 'malware'
assert mal.id == MALWARE_ID
2017-04-11 18:10:55 +02:00
assert mal.created == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
assert mal.modified == dt.datetime(2016, 5, 12, 8, 17, 27, tzinfo=pytz.utc)
2017-04-05 23:12:44 +02:00
assert mal.labels == ['ransomware']
assert mal.name == "Cryptolocker"
def test_parse_malware_invalid_labels():
data = re.compile('\[.+\]', re.DOTALL).sub('1', EXPECTED_MALWARE)
with pytest.raises(ValueError) as excinfo:
stix2.parse(data)
assert "Invalid value for Malware 'labels'" in str(excinfo.value)
2017-04-07 23:34:06 +02:00
def test_parse_malware_kill_chain_phases():
kill_chain = """
"kill_chain_phases": [
{
"kill_chain_name": "lockheed-martin-cyber-kill-chain",
"phase_name": "reconnaissance"
}
]"""
data = EXPECTED_MALWARE.replace('malware"', 'malware",%s' % kill_chain)
mal = stix2.parse(data)
assert mal.kill_chain_phases[0].kill_chain_name == "lockheed-martin-cyber-kill-chain"
assert mal.kill_chain_phases[0].phase_name == "reconnaissance"
assert mal['kill_chain_phases'][0]['kill_chain_name'] == "lockheed-martin-cyber-kill-chain"
assert mal['kill_chain_phases'][0]['phase_name'] == "reconnaissance"
def test_parse_malware_clean_kill_chain_phases():
kill_chain = """
"kill_chain_phases": [
{
"kill_chain_name": "lockheed-martin-cyber-kill-chain",
"phase_name": 1
}
]"""
data = EXPECTED_MALWARE.replace('malware"', 'malware",%s' % kill_chain)
mal = stix2.parse(data)
assert mal['kill_chain_phases'][0]['phase_name'] == "1"