diff --git a/.travis.yml b/.travis.yml index 1f090c23..3bd8e516 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,4 @@ language: python -sudo: false # Since this is an older project, this is not the default. cache: pip dist: xenial python: @@ -8,6 +7,7 @@ python: - "3.5" - "3.6" - "3.7" + - "3.8" install: - pip install -U pip setuptools - pip install tox-travis diff --git a/cybox/__init__.py b/cybox/__init__.py index 087f33ad..1eba31e9 100644 --- a/cybox/__init__.py +++ b/cybox/__init__.py @@ -1,4 +1,4 @@ -# Copyright (c) 2017, The MITRE Corporation. All rights reserved. +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. from mixbox import entities @@ -6,8 +6,125 @@ from .version import __version__ # noqa +#: Mapping of xsi:types to implementation/extension classes +_EXTENSION_MAP = {} -#TODO: Should this get moved to mixbox or not? + +def _lookup_unprefixed(typename): + """Attempts to resolve a class for the input XML type `typename`. + + Args: + typename: The name of an CybOX XML type (e.g., UnixProcessStatusType) + without a namespace prefix. + + Returns: + A stix.Entity implementation class for the `typename`. + + + Raises: + ValueError: If no class has been registered for the input `typename`. + + """ + for xsi_type, klass in six.iteritems(_EXTENSION_MAP): + if typename in xsi_type: + return klass + + error = "Unregistered extension type: %s" % typename + raise ValueError(error) + + +def _lookup_extension(xsi_type): + """Returns a Python class for the `xsi_type` value. + + Args: + xsi_type: An xsi:type value string. + + Returns: + An Entity implementation class for the `xsi_type`. + + Raises: + ValueError: If no class has been registered for the `xsi_type`. + + """ + if xsi_type in _EXTENSION_MAP: + return _EXTENSION_MAP[xsi_type] + + raise ValueError("Unregistered xsi:type %s" % xsi_type) + + +def lookup_extension(typeinfo, default=None): + """Returns an Entity class for that has been registered for the + `typeinfo` value. + + Note: + This is for internal use only. + + Args: + typeinfo: An object or string containing type information. This can be + either an xsi:type attribute value or a stix.bindings object. + default: Return class if typeinfo is None or contains no xml type + information. + + Returns: + An Entity implementation class for the `xsi_type`. + + Raises: + ValueError: If no class has been registered for the `xsi_type`. + + """ + if typeinfo is None and default: + return default + + # If the `typeinfo` was a string, consider it a full xsi:type value. + if isinstance(typeinfo, six.string_types): + return _lookup_extension(typeinfo) + + # Most extension bindings include this attribute. + if not hasattr(typeinfo, 'xml_type'): + if default: + return default + + error = "Input %s is missing xml_type attribute. Cannot lookup class." + raise ValueError(error % type(typeinfo)) + + # Extension binding classes usually (always?) have an `xmlns_prefix` + # class attribute. + if hasattr(typeinfo, 'xmlns_prefix'): + xsi_type = "%s:%s" % (typeinfo.xmlns_prefix, typeinfo.xml_type) + return _lookup_extension(xsi_type) + + # no xmlns_prefix found, try to resolve the class by just the `xml_type` + return _lookup_unprefixed(typeinfo.xml_type) + + +def add_extension(cls): + """Registers an Entity class as an implementation of an xml type. + + Classes must have an ``_XSI_TYPE`` class attributes to be registered. The + value of this attribute must be a valid xsi:type. + + Note: + This was designed for internal use. + + """ + _EXTENSION_MAP[cls._XSI_TYPE] = cls # noqa + + +def register_extension(cls): + """Class decorator for registering a stix.Entity class as an implementation + of an xml type. + + Classes must have an ``_XSI_TYPE`` class attributes to be registered. + + Note: + This was designed for internal use. + + """ + add_extension(cls) + return cls + + +# TODO: Should this get moved to mixbox or not? class Unicode(entities.Entity): """Shim class to allow xs:string's in EntityList""" diff --git a/cybox/bindings/__init__.py b/cybox/bindings/__init__.py index e69de29b..41937b5f 100644 --- a/cybox/bindings/__init__.py +++ b/cybox/bindings/__init__.py @@ -0,0 +1,96 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import collections + +import mixbox.xml + +TypeInfo = collections.namedtuple("TypeInfo", ('ns', 'typename')) + + +def get_type_info(node): + """Returns a ``TypeInfo`` object for `node`. + + This is accomplished by parsing the ``xsi:type`` attribute found on + `node`. + + Args: + node: An lxml.etree element object. + + Raises: + KeyError: If `node` does not have an ``xsi:type`` attribute. + + """ + xsi_type = node.attrib[mixbox.xml.TAG_XSI_TYPE] + typeinfo = xsi_type.split(":") + + if len(typeinfo) == 2: + prefix, typename = typeinfo + else: + typename = typeinfo + prefix = None + + ns = node.nsmap[prefix] + return TypeInfo(ns=ns, typename=typename) + + +#: A mapping of namespace/type information to binding classes. +_BINDING_EXTENSION_MAP = {} + + +def add_extension(cls): + """Adds the binding class `cls` to the ``_EXTENSION_MAP``. + + This enables the lookup and instantiation of classes during parse when + ``xsi:type`` attributes are encountered. + + """ + typeinfo = TypeInfo(ns=cls.xmlns, typename=cls.xml_type) + _BINDING_EXTENSION_MAP[typeinfo] = cls + + +def register_extension(cls): + """Class decorator for registering a binding class as an implementation of + an xml type. + + Classes must have ``xmlns`` and ``xml_type`` class attributes to be + registered. + + """ + add_extension(cls) + return cls + + +def lookup_extension(typeinfo, default=None): + """Looks up the binding class for `typeinfo`, which is a namespace/typename + pairing. + + Args: + typeinfo: An lxml Element node or a stix.bindings.TypeInfo namedtuple. + default: A binding class that will be returned if typeinfo is an + Element without an xsi:type attribute. + + Returns: + A binding class that has been registered for the namespace and typename + found on `typeinfo`. + + """ + if not isinstance(typeinfo, TypeInfo): + if has_xsi_type(typeinfo): + typeinfo = get_type_info(typeinfo) + elif default: + return default + + if typeinfo in _BINDING_EXTENSION_MAP: + return _BINDING_EXTENSION_MAP[typeinfo] + + fmt = "No class implemented or registered for XML type '{%s}%s'" + error = fmt % (typeinfo.ns, typeinfo.typename) + raise NotImplementedError(error) + + +def has_xsi_type(node): + """Returns ``True`` if `node` does not have an xsi:type attribute. + + """ + return mixbox.xml.TAG_XSI_TYPE in node.attrib diff --git a/cybox/bindings/cybox_core.py b/cybox/bindings/cybox_core.py index ee3eacd0..9408823f 100644 --- a/cybox/bindings/cybox_core.py +++ b/cybox/bindings/cybox_core.py @@ -62,6 +62,7 @@ from .uri_object import URIObjectType from .url_history_object import URLHistoryObjectType from .user_account_object import UserAccountObjectType +from .user_session_object import UserSessionObjectType from .volume_object import VolumeObjectType from .whois_object import WhoisObjectType from .win_computer_account_object import WindowsComputerAccountObjectType @@ -230,7 +231,7 @@ class ObservableType(GeneratedsSuper): subclass = None superclass = None - def __init__(self, negate=False, idref=None, id=None, sighting_count=None, Title=None, Description=None, Keywords=None, Observable_Source=None, Object=None, Event=None, Observable_Composition=None, Pattern_Fidelity=None): + def __init__(self, negate=None, idref=None, id=None, sighting_count=None, Title=None, Description=None, Keywords=None, Observable_Source=None, Object=None, Event=None, Observable_Composition=None, Pattern_Fidelity=None): self.negate = _cast(bool, negate) self.idref = _cast(None, idref) self.id = _cast(None, id) @@ -2167,8 +2168,14 @@ class StateChangeEffectType(DefinedEffectType): some state of the object is changed.""" subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "StateChangeEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Old_Object=None, New_Object=None): - super(StateChangeEffectType, self).__init__(effect_type, ) + super(StateChangeEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Old_Object = Old_Object self.New_Object = New_Object def factory(*args_, **kwargs_): @@ -2246,8 +2253,14 @@ class DataReadEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "DataReadEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Data=None): - super(DataReadEffectType, self).__init__(effect_type, ) + super(DataReadEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Data = Data def factory(*args_, **kwargs_): if DataReadEffectType.subclass: @@ -2315,8 +2328,14 @@ class DataWrittenEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "DataWrittenEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Data=None): - super(DataWrittenEffectType, self).__init__(effect_type, ) + super(DataWrittenEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Data = Data def factory(*args_, **kwargs_): if DataWrittenEffectType.subclass: @@ -2384,8 +2403,14 @@ class DataSentEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "DataSentEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Data=None): - super(DataSentEffectType, self).__init__(effect_type, ) + super(DataSentEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Data = Data def factory(*args_, **kwargs_): if DataSentEffectType.subclass: @@ -2453,8 +2478,14 @@ class DataReceivedEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "DataReceivedEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Data=None): - super(DataReceivedEffectType, self).__init__(effect_type, ) + super(DataReceivedEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Data = Data def factory(*args_, **kwargs_): if DataReceivedEffectType.subclass: @@ -2522,8 +2553,14 @@ class PropertyReadEffectType(DefinedEffectType): process.""" subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "PropertyReadEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Name=None, Value=None): - super(PropertyReadEffectType, self).__init__(effect_type, ) + super(PropertyReadEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Name = Name self.Value = Value def factory(*args_, **kwargs_): @@ -2603,8 +2640,14 @@ class PropertiesEnumeratedEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "PropertiesEnumeratedEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Properties=None): - super(PropertiesEnumeratedEffectType, self).__init__(effect_type, ) + super(PropertiesEnumeratedEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Properties = Properties def factory(*args_, **kwargs_): if PropertiesEnumeratedEffectType.subclass: @@ -2659,7 +2702,7 @@ def buildAttributes(self, node, attrs, already_processed): super(PropertiesEnumeratedEffectType, self).buildAttributes(node, attrs, already_processed) def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): if nodeName_ == 'Properties': - obj_ = cybox_common.ObjectPropertiesType.factory() + obj_ = PropertiesType.factory() obj_.build(child_) self.set_Properties(obj_) super(PropertiesEnumeratedEffectType, self).buildChildren(child_, node, nodeName_, True) @@ -2741,8 +2784,14 @@ class ValuesEnumeratedEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "ValuesEnumeratedEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Values=None): - super(ValuesEnumeratedEffectType, self).__init__(effect_type, ) + super(ValuesEnumeratedEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Values = Values def factory(*args_, **kwargs_): if ValuesEnumeratedEffectType.subclass: @@ -2882,8 +2931,14 @@ class SendControlCodeEffectType(DefinedEffectType): subclass = None superclass = DefinedEffectType + + xmlns = "http://cybox.mitre.org/cybox-2" + xmlns_prefix = "cybox" + xml_type = "SendControlCodeEffectType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, effect_type=None, Control_Code=None): - super(SendControlCodeEffectType, self).__init__(effect_type, ) + super(SendControlCodeEffectType, self).__init__(effect_type, extensiontype_=self.xsi_type) self.Control_Code = Control_Code def factory(*args_, **kwargs_): if SendControlCodeEffectType.subclass: diff --git a/cybox/bindings/library_object.py b/cybox/bindings/library_object.py index 7857fcdd..b1085786 100644 --- a/cybox/bindings/library_object.py +++ b/cybox/bindings/library_object.py @@ -10,8 +10,8 @@ class LibraryType(cybox_common.BaseObjectPropertyType): subclass = None superclass = cybox_common.BaseObjectPropertyType - def __init__(self, obfuscation_algorithm_ref=None, refanging_transform_type=None, has_changed=None, delimiter='##comma##', pattern_type=None, datatype='string', refanging_transform=None, is_case_sensitive=True, bit_mask=None, appears_random=None, observed_encoding=None, defanging_algorithm_ref=None, is_obfuscated=None, regex_syntax=None, apply_condition='ANY', trend=None, idref=None, is_defanged=None, id=None, condition=None, valueOf_=None): - super(LibraryType, self).__init__(obfuscation_algorithm_ref, refanging_transform_type, has_changed, delimiter, pattern_type, datatype, refanging_transform, is_case_sensitive, bit_mask, appears_random, observed_encoding, defanging_algorithm_ref, is_obfuscated, regex_syntax, apply_condition, trend, idref, is_defanged, id, condition, valueOf_) + def __init__(self, obfuscation_algorithm_ref=None, refanging_transform_type=None, has_changed=None, delimiter='##comma##', pattern_type=None, datatype='string', refanging_transform=None, is_case_sensitive=True, bit_mask=None, appears_random=None, trend=None, defanging_algorithm_ref=None, is_obfuscated=None, regex_syntax=None, apply_condition='ANY', idref=None, is_defanged=None, id=None, condition=None, valueOf_=None): + super(LibraryType, self).__init__(obfuscation_algorithm_ref, refanging_transform_type, has_changed, delimiter, pattern_type, datatype, refanging_transform, is_case_sensitive, bit_mask, appears_random, trend, defanging_algorithm_ref, is_obfuscated, regex_syntax, apply_condition, idref, is_defanged, id, condition, valueOf_, ) self.datatype = _cast(None, datatype) self.valueOf_ = valueOf_ def factory(*args_, **kwargs_): @@ -197,7 +197,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Size(obj_) elif nodeName_ == 'Type': - obj_ = cybox_common.LibraryType.factory() + obj_ = LibraryType.factory() obj_.build(child_) self.set_Type(obj_) elif nodeName_ == 'Version': diff --git a/cybox/bindings/network_flow_object.py b/cybox/bindings/network_flow_object.py index f4279df7..bd0bded3 100644 --- a/cybox/bindings/network_flow_object.py +++ b/cybox/bindings/network_flow_object.py @@ -2046,7 +2046,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Length(obj_) elif nodeName_ == 'Template_Record': - obj_ = IPFIXTemplateRecordType.factory() + obj_ = NetflowV9TemplateRecordType.factory() obj_.build(child_) self.Template_Record.append(obj_) # end class NetflowV9TemplateFlowSetType @@ -2142,7 +2142,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Template_ID(obj_) elif nodeName_ == 'Field_Count': - obj_ = cybox_common.HexBinaryObjectPropertyType.factory() + obj_ = cybox_common.IntegerObjectPropertyType.factory() obj_.build(child_) self.set_Field_Count(obj_) elif nodeName_ == 'Field_Type': @@ -2150,7 +2150,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Field_Type(obj_) elif nodeName_ == 'Field_Length': - obj_ = cybox_common.StringObjectPropertyType.factory() + obj_ = cybox_common.HexBinaryObjectPropertyType.factory() obj_.build(child_) self.set_Field_Length(obj_) # end class NetflowV9TemplateRecordType @@ -2252,7 +2252,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Length(obj_) elif nodeName_ == 'Options_Template_Record': - obj_ = IPFIXOptionsTemplateRecordType.factory() + obj_ = NetflowV9OptionsTemplateRecordType.factory() obj_.build(child_) self.Options_Template_Record.append(obj_) elif nodeName_ == 'Padding': @@ -2385,7 +2385,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Scope_Field_Type(obj_) elif nodeName_ == 'Scope_Field_Length': - obj_ = cybox_common.IntegerObjectPropertyType.factory() + obj_ = cybox_common.HexBinaryObjectPropertyType.factory() obj_.build(child_) self.set_Scope_Field_Length(obj_) elif nodeName_ == 'Option_Field_Type': @@ -2393,7 +2393,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Option_Field_Type(obj_) elif nodeName_ == 'Option_Field_Length': - obj_ = cybox_common.IntegerObjectPropertyType.factory() + obj_ = cybox_common.HexBinaryObjectPropertyType.factory() obj_.build(child_) self.set_Option_Field_Length(obj_) # end class NetflowV9OptionsTemplateRecordType @@ -2497,7 +2497,7 @@ def buildChildren(self, child_, node, nodeName_, fromsubclass_=False): obj_.build(child_) self.set_Length(obj_) elif nodeName_ == 'Data_Record': - obj_ = IPFIXDataRecordType.factory() + obj_ = NetflowV9DataRecordType.factory() obj_.build(child_) self.Data_Record.append(obj_) elif nodeName_ == 'Padding': @@ -2977,10 +2977,7 @@ class NetflowV5FlowHeaderType(GeneratedsSuper): subclass = None superclass = None def __init__(self, Version=None, Count=None, Sys_Up_Time=None, Unix_Secs=None, Unix_Nsecs=None, Flow_Sequence=None, Engine_Type=None, Engine_ID=None, Sampling_Interval=None): - if Version is None: - self.Version = globals()['cybox_common.HexBinaryObjectPropertyType']('05') - else: - self.Version = Version + self.Version = Version self.Count = Count self.Sys_Up_Time = Sys_Up_Time self.Unix_Secs = Unix_Secs diff --git a/cybox/bindings/unix_file_object.py b/cybox/bindings/unix_file_object.py index ab1fb5c8..baf86a39 100644 --- a/cybox/bindings/unix_file_object.py +++ b/cybox/bindings/unix_file_object.py @@ -615,6 +615,9 @@ def main(): else: usage() +# Register abstract types +setattr(file_object, "UnixFilePermissionsType", UnixFilePermissionsType) + if __name__ == '__main__': #import pdb; pdb.set_trace() main() diff --git a/cybox/bindings/unix_process_object.py b/cybox/bindings/unix_process_object.py index b99db699..1abbaf5b 100644 --- a/cybox/bindings/unix_process_object.py +++ b/cybox/bindings/unix_process_object.py @@ -162,6 +162,12 @@ class UnixProcessStatusType(process_object.ProcessStatusType): subclass = None superclass = process_object.ProcessStatusType + + xmlns = "http://cybox.mitre.org/objects#UnixProcessObject-2" + xmlns_prefix = "UnixProcessObj" + xml_type = "UnixProcessStatusType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, Current_Status=None, Timestamp=None): super(UnixProcessStatusType, self).__init__() self.Current_Status = Current_Status @@ -209,6 +215,9 @@ def export(self, lwrite, level, namespace_='UnixProcessObj:', name_='UnixProcess lwrite('/>%s' % (eol_, )) def exportAttributes(self, lwrite, level, already_processed, namespace_='UnixProcessObj:', name_='UnixProcessStatusType'): super(UnixProcessStatusType, self).exportAttributes(lwrite, level, already_processed, namespace_, name_='UnixProcessStatusType') + if 'xsi:type' not in already_processed: + already_processed.add('xsi:type') + lwrite(" xsi:type='%s'" % self.xsi_type) def exportChildren(self, lwrite, level, namespace_='UnixProcessObj:', name_='UnixProcessStatusType', fromsubclass_=False, pretty_print=True): super(UnixProcessStatusType, self).exportChildren(lwrite, level, 'UnixProcessObj:', name_, True, pretty_print=pretty_print) if pretty_print: @@ -610,6 +619,8 @@ def main(): else: usage() +setattr(process_object, "UnixProcessStatusType", UnixProcessStatusType) + if __name__ == '__main__': #import pdb; pdb.set_trace() main() diff --git a/cybox/bindings/win_executable_file_object.py b/cybox/bindings/win_executable_file_object.py index 88140dc2..d9e4113c 100644 --- a/cybox/bindings/win_executable_file_object.py +++ b/cybox/bindings/win_executable_file_object.py @@ -174,14 +174,14 @@ def exportChildren(self, lwrite, level, namespace_='WinExecutableFileObj:', name self.Name.export(lwrite, level, 'WinExecutableFileObj:', name_='Name', pretty_print=pretty_print) if self.Exported_Functions is not None: self.Exported_Functions.export(lwrite, level, 'WinExecutableFileObj:', name_='Exported_Functions', pretty_print=pretty_print) - if self.Number_Of_Functions is not None: - self.Number_Of_Functions.export(lwrite, level, 'WinExecutableFileObj:', name_='Number_Of_Functions', pretty_print=pretty_print) if self.Exports_Time_Stamp is not None: self.Exports_Time_Stamp.export(lwrite, level, 'WinExecutableFileObj:', name_='Exports_Time_Stamp', pretty_print=pretty_print) if self.Number_Of_Addresses is not None: self.Number_Of_Addresses.export(lwrite, level, 'WinExecutableFileObj:', name_='Number_Of_Addresses', pretty_print=pretty_print) if self.Number_Of_Names is not None: self.Number_Of_Names.export(lwrite, level, 'WinExecutableFileObj:', name_='Number_Of_Names', pretty_print=pretty_print) + if self.Number_Of_Functions is not None: + self.Number_Of_Functions.export(lwrite, level, 'WinExecutableFileObj:', name_='Number_Of_Functions', pretty_print=pretty_print) def build(self, node): self.__sourcenode__ = node already_processed = set() @@ -783,10 +783,6 @@ def export(self, lwrite, level, namespace_='WinExecutableFileObj:', name_='PERes else: lwrite('/>%s' % (eol_, )) def exportAttributes(self, lwrite, level, already_processed, namespace_='WinExecutableFileObj:', name_='PEResourceType'): - if self.extensiontype_ is not None: - - lwrite(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"') - lwrite(' xsi:type="%s"' % self.extensiontype_) pass def exportChildren(self, lwrite, level, namespace_='WinExecutableFileObj:', name_='PEResourceType', fromsubclass_=False, pretty_print=True): if pretty_print: @@ -864,6 +860,12 @@ class PEVersionInfoResourceType(PEResourceType): subclass = None superclass = PEResourceType + + xmlns = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" + xmlns_prefix = "WinExecutableFileObj" + xml_type = "PEVersionInfoResourceType" + xsi_type = "%s:%s" % (xmlns_prefix, xml_type) + def __init__(self, Type=None, Name=None, Hashes=None, Comments=None, CompanyName=None, FileDescription=None, FileVersion=None, InternalName=None, LangID=None, LegalCopyright=None, LegalTrademarks=None, OriginalFilename=None, PrivateBuild=None, ProductName=None, ProductVersion=None, SpecialBuild=None): super(PEVersionInfoResourceType, self).__init__(Type, Name, Hashes, ) self.Comments = Comments @@ -952,6 +954,9 @@ def export(self, lwrite, level, namespace_='WinExecutableFileObj:', name_='PEVer lwrite('/>%s' % (eol_, )) def exportAttributes(self, lwrite, level, already_processed, namespace_='WinExecutableFileObj:', name_='PEVersionInfoResourceType'): super(PEVersionInfoResourceType, self).exportAttributes(lwrite, level, already_processed, namespace_, name_='PEVersionInfoResourceType') + if 'xsi:type' not in already_processed: + already_processed.add('xsi:type') + lwrite(" xsi:type='%s'" % self.xsi_type) def exportChildren(self, lwrite, level, namespace_='WinExecutableFileObj:', name_='PEVersionInfoResourceType', fromsubclass_=False, pretty_print=True): super(PEVersionInfoResourceType, self).exportChildren(lwrite, level, 'WinExecutableFileObj:', name_, True, pretty_print=pretty_print) if pretty_print: diff --git a/cybox/bindings/win_volume_object.py b/cybox/bindings/win_volume_object.py index 4d80f637..80e8809a 100644 --- a/cybox/bindings/win_volume_object.py +++ b/cybox/bindings/win_volume_object.py @@ -164,8 +164,8 @@ class WindowsDriveType(cybox_common.BaseObjectPropertyType): subclass = None superclass = cybox_common.BaseObjectPropertyType - def __init__(self, obfuscation_algorithm_ref=None, refanging_transform_type=None, has_changed=None, pattern_type=None, datatype='string', refanging_transform=None, bit_mask=None, appears_random=None, trend=None, defanging_algorithm_ref=None, is_obfuscated=None, regex_syntax=None, apply_condition='ANY', idref=None, is_defanged=None, id=None, condition=None, valueOf_=None): - super(WindowsDriveType, self).__init__(obfuscation_algorithm_ref, refanging_transform_type, has_changed, pattern_type, datatype, refanging_transform, bit_mask, appears_random, trend, defanging_algorithm_ref, is_obfuscated, regex_syntax, apply_condition, idref, is_defanged, id, condition, valueOf_, ) + def __init__(self, obfuscation_algorithm_ref=None, refanging_transform_type=None, has_changed=None, delimiter='##comma##', pattern_type=None, datatype='string', refanging_transform=None, is_case_sensitive=True, bit_mask=None, appears_random=None, trend=None, defanging_algorithm_ref=None, is_obfuscated=None, regex_syntax=None, apply_condition='ANY', idref=None, is_defanged=None, id=None, condition=None, valueOf_=None): + super(WindowsDriveType, self).__init__(obfuscation_algorithm_ref, refanging_transform_type, has_changed, delimiter, pattern_type, datatype, refanging_transform, is_case_sensitive, bit_mask, appears_random, trend, defanging_algorithm_ref, is_obfuscated, regex_syntax, apply_condition, idref, is_defanged, id, condition, valueOf_, ) self.datatype = _cast(None, datatype) self.valueOf_ = valueOf_ def factory(*args_, **kwargs_): diff --git a/cybox/bindings/x509_certificate_object.py b/cybox/bindings/x509_certificate_object.py index 0e952008..1d32b372 100644 --- a/cybox/bindings/x509_certificate_object.py +++ b/cybox/bindings/x509_certificate_object.py @@ -800,6 +800,8 @@ def factory(*args_, **kwargs_): factory = staticmethod(factory) def get_Certificate(self): return self.Certificate def set_Certificate(self, Certificate): self.Certificate = Certificate + def get_Raw_Certificate(self): return self.Raw_Certificate + def set_Raw_Certificate(self, Raw_Certificate): self.Raw_Certificate = Raw_Certificate def get_Certificate_Signature(self): return self.Certificate_Signature def set_Certificate_Signature(self, Certificate_Signature): self.Certificate_Signature = Certificate_Signature def hasContent_(self): diff --git a/cybox/common/__init__.py b/cybox/common/__init__.py index 07a43612..51c16db2 100644 --- a/cybox/common/__init__.py +++ b/cybox/common/__init__.py @@ -28,13 +28,17 @@ from .properties import * from .vocabs import VocabString +from .compensation_model import CompensationModel from .data_segment import DataSegment, DataSize from .datetimewithprecision import DateTimeWithPrecision, DateWithPrecision from .daterange import DateRange from .digitalsignature import DigitalSignature, DigitalSignatureList from .environment_variable import EnvironmentVariable, EnvironmentVariableList +from .errors import Error, ErrorInstances, Errors +from .execution_environment import ExecutionEnvironment from .hashes import Hash, HashList, HashName from .location import Location +from .metadata import Metadata from .object_properties import ObjectProperties, Property from .structured_text import StructuredText from .time import Time @@ -47,4 +51,3 @@ from .measuresource import InformationSourceType, MeasureSource from .extracted_features import ExtractedFeatures - diff --git a/cybox/common/build.py b/cybox/common/build.py new file mode 100644 index 00000000..1645478b --- /dev/null +++ b/cybox/common/build.py @@ -0,0 +1,47 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding +from cybox.common.compilers import Compilers +from cybox.common.configuration_settings import ConfigurationSettings +from cybox.common.libraries import Libraries +from cybox.common.platform_specification import PlatformSpecification +from cybox.common.time import DateTimeWithPrecision + + +class BuildUtility(entities.Entity): + _binding = common_binding + _binding_class = common_binding.BuildUtilityType + _namespace = 'http://cybox.mitre.org/common-2' + + build_utility_name = fields.TypedField("Build_Utility_Name") + build_utility_platform_specification = fields.TypedField("Build_Utility_Platform_Specification", PlatformSpecification) + + +class BuildConfiguration(entities.Entity): + _binding = common_binding + _binding_class = common_binding.BuildConfigurationType + _namespace = 'http://cybox.mitre.org/common-2' + + configuration_setting_description = fields.TypedField("Configuration_Setting_Description", multiple=True) + configuration_settings = fields.TypedField("Configuration_Settings", ConfigurationSettings) + + +class BuildInformation(entities.Entity): + _binding = common_binding + _binding_class = common_binding.BuildInformationType + _namespace = 'http://cybox.mitre.org/common-2' + + build_id = fields.TypedField("Build_ID") + build_project = fields.TypedField("Build_Project") + build_utility = fields.TypedField("Build_Utility", BuildUtility) + build_version = fields.TypedField("Build_Version") + build_label = fields.TypedField("Build_Label") + compilers = fields.TypedField("Compilers", Compilers) + compilation_date = fields.TypedField("Compilation_Date", DateTimeWithPrecision) + build_configuration = fields.TypedField("Build_Configuration", BuildConfiguration) + build_script = fields.TypedField("Build_Script") + libraries = fields.TypedField("Libraries", Libraries) + build_output_log = fields.TypedField("Build_Output_Log") diff --git a/cybox/common/cipher.py b/cybox/common/cipher.py new file mode 100644 index 00000000..8bcd32fc --- /dev/null +++ b/cybox/common/cipher.py @@ -0,0 +1,22 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import cybox.bindings.cybox_common as common_binding +from cybox.common import BaseProperty + + +class Cipher(BaseProperty): + _binding = common_binding + _binding_class = common_binding.CipherType + _namespace = 'http://cybox.mitre.org/common-2' + + TERM_3DES = "3DES" + TERM_AES = "AES" + TERM_BLOWFISH = "Blowfish" + TERM_CAST128 = "CAST-128" + TERM_CAST256 = "CAST-256" + TERM_DES = "DES" + TERM_IDEA = "IDEA" + TERM_RIJNDAEL = "Rijndael" + TERM_RC5 = "RC5" + TERM_SKIPJACK = "Skipjack" diff --git a/cybox/common/compensation_model.py b/cybox/common/compensation_model.py new file mode 100644 index 00000000..207454bc --- /dev/null +++ b/cybox/common/compensation_model.py @@ -0,0 +1,16 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import cybox.bindings.cybox_common as common_binding +from cybox.common import BaseProperty + + +class CompensationModel(BaseProperty): + _binding = common_binding + _binding_class = common_binding.CompensationModelType + _namespace = 'http://cybox.mitre.org/common-2' + + TERM_FREEWARE = "Freeware" + TERM_SHAREWARE = "Shareware" + TERM_COMMERCIAL = "Commercial" + TERM_ADWARE = "Adware" diff --git a/cybox/common/compilers.py b/cybox/common/compilers.py new file mode 100644 index 00000000..23bc55b1 --- /dev/null +++ b/cybox/common/compilers.py @@ -0,0 +1,33 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding +from cybox.common.platform_specification import PlatformSpecification + + +class CompilerInformalDescription(entities.Entity): + _binding = common_binding + _binding_class = common_binding.CompilerInformalDescriptionType + _namespace = 'http://cybox.mitre.org/common-2' + + compiler_name = fields.TypedField("Compiler_Name") + compiler_version = fields.TypedField("Compiler_Version") + + +class Compiler(entities.Entity): + _binding = common_binding + _binding_class = common_binding.CompilerType + _namespace = 'http://cybox.mitre.org/common-2' + + compiler_informal_description = fields.TypedField("Compiler_Informal_Description", CompilerInformalDescription) + compiler_platform_specification = fields.TypedField("Compiler_Platform_Specification", PlatformSpecification) + + +class Compilers(entities.Entity): + _binding = common_binding + _binding_class = common_binding.CompilersType + _namespace = 'http://cybox.mitre.org/common-2' + + compiler = fields.TypedField("Compiler", Compiler, multiple=True) diff --git a/cybox/common/configuration_settings.py b/cybox/common/configuration_settings.py new file mode 100644 index 00000000..12813e90 --- /dev/null +++ b/cybox/common/configuration_settings.py @@ -0,0 +1,25 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding + + +class ConfigurationSetting(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ConfigurationSettingType + _namespace = 'http://cybox.mitre.org/common-2' + + item_name = fields.TypedField("Item_Name") + item_value = fields.TypedField("Item_Value") + item_type = fields.TypedField("Item_Type") + item_description = fields.TypedField("Item_Description") + + +class ConfigurationSettings(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ConfigurationSettingsType + _namespace = 'http://cybox.mitre.org/common-2' + + configuration_setting = fields.TypedField("Configuration_Setting", ConfigurationSetting, multiple=True) diff --git a/cybox/common/contributor.py b/cybox/common/contributor.py index a1baeae2..bc8c6737 100644 --- a/cybox/common/contributor.py +++ b/cybox/common/contributor.py @@ -25,4 +25,5 @@ class Contributor(entities.Entity): class Personnel(entities.EntityList): _binding_class = common_binding.PersonnelType _namespace = 'http://cybox.mitre.org/common-2' - contributor = fields.TypedField("Contributor", Contributor, multiple=True) \ No newline at end of file + + contributor = fields.TypedField("Contributor", Contributor, multiple=True) diff --git a/cybox/common/datetimewithprecision.py b/cybox/common/datetimewithprecision.py index 9ee9f9e5..fcc5ed0e 100644 --- a/cybox/common/datetimewithprecision.py +++ b/cybox/common/datetimewithprecision.py @@ -35,7 +35,6 @@ def validate_time_precision(instance, value): _validate_precision(value, TIME_PRECISION_VALUES) - class DateTimeWithPrecision(entities.Entity): _binding = common_binding _binding_class = common_binding.DateTimeWithPrecisionType diff --git a/cybox/common/dependencies.py b/cybox/common/dependencies.py new file mode 100644 index 00000000..5ea4f829 --- /dev/null +++ b/cybox/common/dependencies.py @@ -0,0 +1,24 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding +from cybox.common.structured_text import StructuredText + + +class Dependency(entities.Entity): + _binding = common_binding + _binding_class = common_binding.DependencyType + _namespace = 'http://cybox.mitre.org/common-2' + + dependency_type = fields.TypedField("Dependency_Type") + dependency_description = fields.TypedField("Dependency_Description", StructuredText) + + +class Dependencies(entities.Entity): + _binding = common_binding + _binding_class = common_binding.DependenciesType + _namespace = 'http://cybox.mitre.org/common-2' + + dependency = fields.TypedField("Dependency", Dependency, multiple=True) diff --git a/cybox/common/errors.py b/cybox/common/errors.py new file mode 100644 index 00000000..5c7c50b5 --- /dev/null +++ b/cybox/common/errors.py @@ -0,0 +1,32 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding + + +class ErrorInstances(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ErrorInstancesType + _namespace = 'http://cybox.mitre.org/common-2' + + error_instance = fields.TypedField("Error_Instance", multiple=True) + + +class Error(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ErrorType + _namespace = 'http://cybox.mitre.org/common-2' + + error_type = fields.TypedField("Error_Type") + error_count = fields.TypedField("Error_Count") + error_instances = fields.TypedField("Error_Instances", ErrorInstances) + + +class Errors(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ErrorsType + _namespace = 'http://cybox.mitre.org/common-2' + + error = fields.TypedField("Error", Error, multiple=True) diff --git a/cybox/common/execution_environment.py b/cybox/common/execution_environment.py new file mode 100644 index 00000000..3a272445 --- /dev/null +++ b/cybox/common/execution_environment.py @@ -0,0 +1,19 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding +from cybox.common.object_properties import ObjectPropertiesFactory, ObjectProperties +from cybox.common.time import DateTimeWithPrecision + + +class ExecutionEnvironment(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ExecutionEnvironmentType + _namespace = 'http://cybox.mitre.org/common-2' + + system = fields.TypedField("System", ObjectProperties, factory=ObjectPropertiesFactory) + user_account_info = fields.TypedField("User_Account_Info", ObjectProperties, factory=ObjectPropertiesFactory) + command_line = fields.TypedField("Command_Line") + start_time = fields.TypedField("Start_Time", DateTimeWithPrecision) diff --git a/cybox/common/extracted_string.py b/cybox/common/extracted_string.py index a41116ad..eda4ee05 100644 --- a/cybox/common/extracted_string.py +++ b/cybox/common/extracted_string.py @@ -33,4 +33,4 @@ def __init__(self, string_value=None): class ExtractedStrings(entities.EntityList): _binding_class = common_binding.ExtractedStringsType _namespace = 'http://cybox.mitre.org/common-2' - extracted_string = fields.TypedField("String", ExtractedString, multiple=True) \ No newline at end of file + extracted_string = fields.TypedField("String", ExtractedString, multiple=True) diff --git a/cybox/common/hashes.py b/cybox/common/hashes.py index 91487d8b..6f0512f9 100644 --- a/cybox/common/hashes.py +++ b/cybox/common/hashes.py @@ -1,9 +1,7 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields -from mixbox.vendor import six +from mixbox import entities, fields from mixbox.vendor.six import u import cybox.bindings.cybox_common as common_binding diff --git a/cybox/common/internationalization_settings.py b/cybox/common/internationalization_settings.py new file mode 100644 index 00000000..26be298f --- /dev/null +++ b/cybox/common/internationalization_settings.py @@ -0,0 +1,23 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding + + +class InternalStrings(entities.Entity): + _binding = common_binding + _binding_class = common_binding.InternalStringsType + _namespace = 'http://cybox.mitre.org/common-2' + + key = fields.TypedField("Key") + content = fields.TypedField("Content") + + +class InternationalizationSettings(entities.Entity): + _binding = common_binding + _binding_class = common_binding.InternationalizationSettingsType + _namespace = 'http://cybox.mitre.org/common-2' + + internal_strings = fields.TypedField("Internal_Strings", InternalStrings, multiple=True) diff --git a/cybox/common/libraries.py b/cybox/common/libraries.py new file mode 100644 index 00000000..3ffab18f --- /dev/null +++ b/cybox/common/libraries.py @@ -0,0 +1,23 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding + + +class Library(entities.Entity): + _binding = common_binding + _binding_class = common_binding.LibraryType + _namespace = 'http://cybox.mitre.org/common-2' + + version = fields.TypedField("version") + name = fields.TypedField("name") + + +class Libraries(entities.Entity): + _binding = common_binding + _binding_class = common_binding.LibrariesType + _namespace = 'http://cybox.mitre.org/common-2' + + library = fields.TypedField("Library", Library) diff --git a/cybox/common/location.py b/cybox/common/location.py index e6db8d09..0a3a46f5 100644 --- a/cybox/common/location.py +++ b/cybox/common/location.py @@ -3,9 +3,16 @@ from mixbox import entities, fields +import cybox import cybox.bindings.cybox_common as common_binding +class LocationFactory(entities.EntityFactory): + @classmethod + def entity_class(cls, key): + return cybox.lookup_extension(key, default=Location) + + class Location(entities.Entity): _binding = common_binding _binding_class = common_binding.LocationType @@ -23,3 +30,7 @@ def to_dict(self): d["xsi:type"] = self._XSI_TYPE return d + + @staticmethod + def lookup_class(xsi_type): + return cybox.lookup_extension(xsi_type, default=Location) diff --git a/cybox/common/metadata.py b/cybox/common/metadata.py new file mode 100644 index 00000000..b8ea2be5 --- /dev/null +++ b/cybox/common/metadata.py @@ -0,0 +1,16 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding + + +class Metadata(entities.Entity): + _binding = common_binding + _binding_class = common_binding.MetadataType + _namespace = 'http://cybox.mitre.org/common-2' + + type_ = fields.TypedField("type_", key_name="type") + value = fields.TypedField("Value") + subdatum = fields.TypedField("SubDatum", type_="cybox.common.metadata.Metadata", multiple=True) diff --git a/cybox/common/object_properties.py b/cybox/common/object_properties.py index 71bad0f9..1a85cd8d 100644 --- a/cybox/common/object_properties.py +++ b/cybox/common/object_properties.py @@ -30,6 +30,7 @@ class CustomProperties(entities.EntityList): _binding = common_binding _binding_class = common_binding.CustomPropertiesType _namespace = 'http://cybox.mitre.org/common-2' + property_ = fields.TypedField("Property", Property, multiple=True) @@ -53,7 +54,7 @@ def entity_class(cls, key): class ObjectProperties(entities.Entity): """The Cybox ObjectProperties base class.""" _XSI_TYPE = None - _XSI_NS = None + _XSI_NS = None _binding = common_binding _binding_class = _binding.ObjectPropertiesType diff --git a/cybox/common/platform_specification.py b/cybox/common/platform_specification.py index c9a1cf5f..2608fcc2 100644 --- a/cybox/common/platform_specification.py +++ b/cybox/common/platform_specification.py @@ -14,7 +14,7 @@ class PlatformIdentifier(String): _namespace = 'http://cybox.mitre.org/common-2' system = fields.TypedField("system") - system_ref = fields.TypedField("system_ref") + system_ref = fields.TypedField("system_ref", key_name="system-ref") class PlatformSpecification(entities.Entity): @@ -24,4 +24,4 @@ class PlatformSpecification(entities.Entity): _binding_class = _binding.PlatformSpecificationType description = fields.TypedField("Description", StructuredText) - identifiers = fields.TypedField("Identifier", PlatformIdentifier, multiple=True) + identifier = fields.TypedField("Identifier", PlatformIdentifier, multiple=True) diff --git a/cybox/common/time.py b/cybox/common/time.py index 412cff17..dc79c8ab 100644 --- a/cybox/common/time.py +++ b/cybox/common/time.py @@ -24,4 +24,3 @@ def __init__(self, start_time=None, end_time=None, produced_time=None, received_ self.end_time = end_time self.produced_time = produced_time self.received_time = received_time - diff --git a/cybox/common/tools.py b/cybox/common/tools.py index 6c7fa3ce..d234ea0d 100644 --- a/cybox/common/tools.py +++ b/cybox/common/tools.py @@ -1,13 +1,77 @@ -# Copyright (c) 2017, The MITRE Corporation. All rights reserved. +# Copyright (c) 2010, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields +from mixbox import entities, fields + +import cybox import cybox.bindings.cybox_common as common_binding -from cybox.common import HashList, StructuredText +from cybox.common import ( + CompensationModel, Errors, ExecutionEnvironment, HashList, Metadata, + StructuredText +) from cybox.common.vocabs import VocabField, ToolType +class ToolSpecificDataFactory(entities.EntityFactory): + @classmethod + def entity_class(cls, key): + return cybox.lookup_extension(key, default=ToolSpecificData) + + +class ToolSpecificData(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ToolSpecificDataType + _namespace = 'http://cybox.mitre.org/common-2' + _XSI_TYPE = None # overridden by subclasses + + def to_dict(self): + d = super(ToolSpecificData, self).to_dict() + + if self._XSI_TYPE: + d["xsi:type"] = self._XSI_TYPE + + return d + + @staticmethod + def lookup_class(xsi_type): + return cybox.lookup_extension(xsi_type, default=ToolSpecificData) + + +class ToolReference(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ToolReferenceType + _namespace = 'http://cybox.mitre.org/common-2' + + TERM_DOCUMENTATION = "Documentation" + TERM_SOURCE = "Source" + TERM_DOWNLOAD = "Download" + TERM_EXECUTE = "Execute" + TERM_OTHER = "Other" + + reference_type = fields.TypedField("reference_type") + value = fields.TypedField("valueOf_", key_name="value") + + +class ToolReferences(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ToolReferencesType + _namespace = 'http://cybox.mitre.org/common-2' + + reference = fields.TypedField("Reference", ToolReference, multiple=True) + + +class ToolConfiguration(entities.Entity): + _binding = common_binding + _binding_class = common_binding.ToolConfigurationType + _namespace = 'http://cybox.mitre.org/common-2' + + configuration_settings = fields.TypedField("Configuration_Settings") + dependencies = fields.TypedField("Dependencies") + usage_context_assumptions = fields.TypedField("Usage_Context_Assumptions") + internationalization_settings = fields.TypedField("Internationalization_Settings") + build_information = fields.TypedField("Build_Information") + + class ToolInformation(entities.Entity): _binding = common_binding _binding_class = common_binding.ToolInformationType @@ -18,29 +82,26 @@ class ToolInformation(entities.Entity): name = fields.TypedField("Name") type_ = VocabField("Type", ToolType, multiple=True) description = fields.TypedField("Description", StructuredText) + references = fields.TypedField("References", ToolReferences) vendor = fields.TypedField("Vendor") version = fields.TypedField("Version") service_pack = fields.TypedField("Service_Pack") + tool_specific_data = fields.TypedField("Tool_Specific_Data", ToolSpecificData, factory=ToolSpecificDataFactory) tool_hashes = fields.TypedField("Tool_Hashes", HashList) + tool_configuration = fields.TypedField("Tool_Configuration", ToolConfiguration) + execution_environment = fields.TypedField("Execution_Environment", ExecutionEnvironment) + errors = fields.TypedField("Errors", Errors) + metadata = fields.TypedField("Metadata", Metadata, multiple=True) + compensation_model = fields.TypedField("Compensation_Model", CompensationModel) def __init__(self, tool_name=None, tool_vendor=None): super(ToolInformation, self).__init__() - # TODO: Implement items commented out below. self.name = tool_name - self.description = None - #self.references = None self.vendor = tool_vendor - self.version = None - self.service_pack = None - #self.tool_specific_data = None - self.tool_hashes = None - #self.tool_configuration = None - #self.execution_environment = None - #self.errors = None - #self.metadata = [] class ToolInformationList(entities.EntityList): _binding_class = common_binding.ToolsInformationType _namespace = 'http://cybox.mitre.org/common-2' - tool = fields.TypedField("Tool", ToolInformation, multiple=True) \ No newline at end of file + + tool = fields.TypedField("Tool", ToolInformation, multiple=True) diff --git a/cybox/common/usage_context.py b/cybox/common/usage_context.py new file mode 100644 index 00000000..364a366b --- /dev/null +++ b/cybox/common/usage_context.py @@ -0,0 +1,15 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.cybox_common as common_binding +from cybox.common.structured_text import StructuredText + + +class UsageContextAssumptions(entities.Entity): + _binding = common_binding + _binding_class = common_binding.UsageContextAssumptionsType + _namespace = 'http://cybox.mitre.org/common-2' + + usage_context_assumption = fields.TypedField("Usage_Context_Assumption", StructuredText, multiple=True) diff --git a/cybox/common/vocabs.py b/cybox/common/vocabs.py index 7507e304..b8c7a6f0 100644 --- a/cybox/common/vocabs.py +++ b/cybox/common/vocabs.py @@ -858,3 +858,21 @@ class InformationSourceType(VocabString): TERM_TPM = 'TPM' TERM_VM_HYPERVISOR = 'VM Hypervisor' TERM_WEB_LOGS = 'Web Logs' + + +@register_vocab +class ObjectState(VocabString): + _namespace = 'http://cybox.mitre.org/default_vocabularies-2' + _XSI_TYPE = 'cyboxVocabs:ObjectStateVocab-1.0' + _VOCAB_VERSION = '1.0' + + TERM_EXISTS = 'Exists' + TERM_DOES_NOT_EXIST = 'Does Not Exist' + TERM_OPEN = 'Open' + TERM_CLOSED = 'Closed' + TERM_ACTIVE = 'Active' + TERM_INACTIVE = 'Inactive' + TERM_LOCKED = 'Locked' + TERM_UNLOCKED = 'Unlocked' + TERM_STARTED = 'Started' + TERM_STOPPED = 'Stopped' diff --git a/cybox/core/action.py b/cybox/core/action.py index 7810dcd8..cc6a4e1f 100644 --- a/cybox/core/action.py +++ b/cybox/core/action.py @@ -84,6 +84,8 @@ class Action(entities.Entity): class Actions(entities.EntityList): + _binding = core_binding _binding_class = core_binding.ActionsType _namespace = 'http://cybox.mitre.org/cybox-2' + action = fields.TypedField("Action", Action, multiple=True) diff --git a/cybox/core/effect.py b/cybox/core/effect.py new file mode 100644 index 00000000..cca207a3 --- /dev/null +++ b/cybox/core/effect.py @@ -0,0 +1,152 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox +import cybox.bindings.cybox_core as core_binding +from cybox.common import DataSegment + + +class DefinedEffectFactory(entities.EntityFactory): + @classmethod + def entity_class(cls, key): + return cybox.lookup_extension(key, default=DefinedEffect) + + +class DefinedEffect(entities.Entity): + _binding = core_binding + _binding_class = core_binding.DefinedEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = None # overridden by subclasses + + TERM_STATE_CHANGED = 'State_Changed' + TERM_DATA_READ = 'Data_Read' + TERM_DATA_WRITTEN = 'Data_Written' + TERM_DATA_RECEIVED = 'Data_Received' + TERM_PROPERTIES_READ = 'Properties_Read' + TERM_PROPERTIES_ENUMERATED = 'Properties_Enumerated' + TERM_VALUES_ENUMERATED = 'Values_Enumerated' + TERM_CONTROLCODE_SENT = 'ControlCode_Sent' + + effect_type = fields.TypedField("effect_type") + + def to_dict(self): + d = super(DefinedEffect, self).to_dict() + + if self._XSI_TYPE: + d["xsi:type"] = self._XSI_TYPE + + return d + + @staticmethod + def lookup_class(xsi_type): + return cybox.lookup_extension(xsi_type, default=DefinedEffect) + + +@cybox.register_extension +class StateChangeEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.StateChangeEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:StateChangeEffectType" + + old_object = fields.TypedField("Old_Object", type_="cybox.core.object.Object") + new_object = fields.TypedField("New_Object", type_="cybox.core.object.Object") + + +@cybox.register_extension +class DataReadEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.DataReadEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:DataReadEffectType" + + data = fields.TypedField("Data", DataSegment) + + +@cybox.register_extension +class DataWrittenEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.DataWrittenEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:DataWrittenEffectType" + + data = fields.TypedField("Data", DataSegment) + + +@cybox.register_extension +class DataSentEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.DataSentEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:DataSentEffectType" + + data = fields.TypedField("Data", DataSegment) + + +@cybox.register_extension +class DataReceivedEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.DataReceivedEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:DataReceivedEffectType" + + data = fields.TypedField("Data", DataSegment) + + +@cybox.register_extension +class PropertyReadEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.PropertyReadEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:PropertyReadEffectType" + + name = fields.TypedField("Name") + value = fields.TypedField("Value") + + +class Properties(entities.Entity): + _binding = core_binding + _binding_class = core_binding.PropertiesType + _namespace = 'http://cybox.mitre.org/cybox-2' + + property_ = fields.TypedField("Property", multiple=True) + + +@cybox.register_extension +class PropertiesEnumeratedEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.PropertiesEnumeratedEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:PropertiesEnumeratedEffectType" + + properties = fields.TypedField("Properties", Properties) + + +class Values(entities.Entity): + _binding = core_binding + _binding_class = core_binding.ValuesType + _namespace = 'http://cybox.mitre.org/cybox-2' + + value = fields.TypedField("Value", multiple=True) + + +@cybox.register_extension +class ValuesEnumeratedEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.ValuesEnumeratedEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:ValuesEnumeratedEffectType" + + values = fields.TypedField("Values", Values) + + +@cybox.register_extension +class SendControlCodeEffect(DefinedEffect): + _binding = core_binding + _binding_class = core_binding.SendControlCodeEffectType + _namespace = 'http://cybox.mitre.org/cybox-2' + _XSI_TYPE = "cybox:SendControlCodeEffectType" + + control_code = fields.TypedField("Control_Code") diff --git a/cybox/core/event.py b/cybox/core/event.py index a7941d9d..f92c2897 100644 --- a/cybox/core/event.py +++ b/cybox/core/event.py @@ -24,7 +24,4 @@ class Event(entities.Entity): actions = fields.TypedField("Actions", Actions) frequency = fields.TypedField("Frequency", Frequency) location = fields.TypedField("Location", Location) - event = fields.TypedField("Event", multiple=True) - -# Allow recursive definition of events -Event.event.type_ = Event + event = fields.TypedField("Event", type_="cybox.core.event.Event", multiple=True) diff --git a/cybox/core/object.py b/cybox/core/object.py index 061d2791..5f76a418 100644 --- a/cybox/core/object.py +++ b/cybox/core/object.py @@ -1,17 +1,17 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields -from mixbox import idgen + +from mixbox import entities, fields, idgen import cybox import cybox.utils import cybox.bindings.cybox_core as core_binding -from cybox.common import StructuredText +from cybox.common import MeasureSource, StructuredText +from cybox.common.location import Location, LocationFactory from cybox.common.object_properties import ObjectPropertiesFactory, ObjectProperties from cybox.common.vocabs import VocabField from cybox.common.vocabs import ObjectRelationship as Relationship - +from cybox.core.effect import DefinedEffectFactory _EXTERNAL_CLASSES = {} # Maps xsi:type values to binding @@ -53,7 +53,7 @@ class Object(entities.Entity): process). Currently only supports the following data members: - - id\_ + - id - idref - has_changed - description @@ -80,8 +80,11 @@ class Object(entities.Entity): state = VocabField("State") description = fields.TypedField("Description", StructuredText) properties = fields.TypedField("Properties", ObjectProperties, factory=ObjectPropertiesFactory, postset_hook=_modify_properties_parent) - domain_specific_object_properties = fields.TypedField("Domain_Specific_Object_Properties", "cybox.core.object.DomainSpecificObjectProperties", factory=ExternalTypeFactory) - related_objects = fields.TypedField("Related_Objects", "cybox.core.object.RelatedObjects") + domain_specific_object_properties = fields.TypedField("Domain_Specific_Object_Properties", type_="cybox.core.object.DomainSpecificObjectProperties", factory=ExternalTypeFactory) + location = fields.TypedField("Location", Location, factory=LocationFactory) + related_objects = fields.TypedField("Related_Objects", type_="cybox.core.object.RelatedObjects") + defined_effect = fields.TypedField("Defined_Effect", "cybox.core.effect.DefinedEffect", factory=DefinedEffectFactory) + discovery_method = fields.TypedField("Discovery_Method", MeasureSource) def __init__(self, properties=None, id_=None, idref=None): super(Object, self).__init__() diff --git a/cybox/core/observable.py b/cybox/core/observable.py index 4a2b0c4d..a58424be 100644 --- a/cybox/core/observable.py +++ b/cybox/core/observable.py @@ -69,14 +69,15 @@ class Observable(entities.Entity): id_ = fields.IdField("id") idref = fields.IdrefField("idref") + negate = fields.TypedField("negate") + sighting_count = fields.TypedField("sighting_count") title = fields.TypedField("Title") description = fields.TypedField("Description", StructuredText) + keywords = fields.TypedField("Keywords", Keywords) + observable_source = fields.TypedField("Observable_Source", MeasureSource, multiple=True) object_ = fields.TypedField("Object", Object, preset_hook=validate_object) # TODO: Add preset hook event = fields.TypedField("Event", Event, preset_hook=validate_event) observable_composition = fields.TypedField("Observable_Composition", type_="cybox.core.ObservableComposition", preset_hook=validate_observable_composition) - sighting_count = fields.TypedField("sighting_count") - observable_source = fields.TypedField("Observable_Source", MeasureSource, multiple=True) - keywords = fields.TypedField("Keywords", Keywords) pattern_fidelity = fields.TypedField("Pattern_Fidelity", type_="cybox.core.PatternFidelity") def __init__(self, item=None, id_=None, idref=None, title=None, description=None): @@ -129,16 +130,19 @@ class Observables(entities.EntityList): _binding_class = _binding.ObservablesType _namespace = 'http://cybox.mitre.org/cybox-2' + cybox_major_version = fields.TypedField("cybox_major_version") + cybox_minor_version = fields.TypedField("cybox_minor_version") + cybox_update_version = fields.TypedField("cybox_update_version") observable_package_source = fields.TypedField("Observable_Package_Source", MeasureSource) observables = fields.TypedField("Observable", Observable, multiple=True, key_name="observables") pools = fields.TypedField("Pools", type_="cybox.core.pool.Pools") def __init__(self, observables=None): super(Observables, self).__init__(observables) - # Assume major_verion and minor_version are immutable for now - self._major_version = 2 - self._minor_version = 1 - self._update_version = 0 + # Assume major_version and minor_version are immutable for now + self.cybox_major_version = "2" + self.cybox_minor_version = "1" + self.cybox_update_version = "0" def add(self, object_): from cybox.core.pool import Pools @@ -154,20 +158,6 @@ def add(self, object_): object_ = Observable(object_) self.observables.append(object_) - def to_obj(self, ns_info=None): - observables_obj = super(Observables, self).to_obj(ns_info=ns_info) - observables_obj.cybox_major_version = self._major_version - observables_obj.cybox_minor_version = self._minor_version - observables_obj.cybox_update_version = self._update_version - return observables_obj - - def to_dict(self): - observables_dict = super(Observables, self).to_dict() - observables_dict['major_version'] = self._major_version - observables_dict['minor_version'] = self._minor_version - observables_dict['update_version'] = self._update_version - return observables_dict - class ObservableComposition(entities.EntityList): """The ObservableCompositionType entity defines a logical compositions of diff --git a/cybox/objects/__init__.py b/cybox/objects/__init__.py index a0306609..2eeb6f83 100644 --- a/cybox/objects/__init__.py +++ b/cybox/objects/__init__.py @@ -81,6 +81,8 @@ def get_class_for_object_type(self, object_type): # May raise AttributeError return getattr(mod, class_name) + + # A list of (object_name, api_class, binding, namespace, dependencies) tuples # This is loaded by the ObjectMetadata class and should not be accessed # directly. @@ -116,7 +118,7 @@ def get_class_for_object_type(self, object_type): ('MutexObjectType', 'cybox.objects.mutex_object.Mutex', 'mutex_object', 'http://cybox.mitre.org/objects#MutexObject-2', []), ('NetRouteObjectType', 'cybox.objects.network_route_object.NetRoute', 'network_route_object', 'http://cybox.mitre.org/objects#NetworkRouteObject-2', ['NetworkRouteEntryObjectType', 'AddressObjectType']), ('NetworkConnectionObjectType', 'cybox.objects.network_connection_object.NetworkConnection', 'network_connection_object', 'http://cybox.mitre.org/objects#NetworkConnectionObject-2', ['SocketAddressObjectType', 'HTTPSessionObjectType', 'DNSQueryObjectType', 'DNSRecordObjectType', 'URIObjectType']), - ('NetworkFlowObjectType', None, 'network_flow_object', 'http://cybox.mitre.org/objects#NetworkFlowObject-2', ['NetworkPacketType', 'AddressObjectType', 'SocketAddressObjectType']), + ('NetworkFlowObjectType', 'cybox.objects.network_flow_object.NetworkFlow', 'network_flow_object', 'http://cybox.mitre.org/objects#NetworkFlowObject-2', ['NetworkPacketType', 'AddressObjectType', 'SocketAddressObjectType']), ('NetworkPacketObjectType', 'cybox.objects.network_packet_object.NetworkPacket', 'network_packet_object', 'http://cybox.mitre.org/objects#PacketObject-2', ['AddressObjectType', 'PortObjectType']), ('NetworkRouteEntryObjectType', 'cybox.objects.network_route_entry_object.NetworkRouteEntry', 'network_route_entry_object', 'http://cybox.mitre.org/objects#NetworkRouteEntryObject-2', ['AddressObjectType']), ('NetworkSocketObjectType', 'cybox.objects.network_socket_object.NetworkSocket', 'network_socket_object', 'http://cybox.mitre.org/objects#NetworkSocketObject-2', ['SocketAddressObjectType']), @@ -130,15 +132,16 @@ def get_class_for_object_type(self, object_type): ('SMSMessageObjectType', 'cybox.objects.sms_message_object.SMSMessage', 'sms_message_object', 'http://cybox.mitre.org/objects#SMSMessageObject-1', []), ('SocketAddressObjectType', 'cybox.objects.socket_address_object.SocketAddress', 'socket_address_object', 'http://cybox.mitre.org/objects#SocketAddressObject-1', ['AddressObjectType', 'PortObjectType']), ('SystemObjectType', 'cybox.objects.system_object.System', 'system_object', 'http://cybox.mitre.org/objects#SystemObject-2', ['AddressObjectType']), - ('UnixFileObjectType', None, 'unix_file_object', 'http://cybox.mitre.org/objects#UnixFileObject-2', ['FileObjectType']), - ('UnixNetworkRouteEntryObjectType', None, 'unix_network_route_entry_object', 'http://cybox.mitre.org/objects#UnixNetworkRouteEntryObject-2', ['NetworkRouteEntryObjectType', 'AddressObjectType']), - ('UnixPipeObjectType', None, 'unix_pipe_object', 'http://cybox.mitre.org/objects#UnixPipeObject', ['PipeObjectType']), - ('UnixProcessObjectType', None, 'unix_process_object', 'http://cybox.mitre.org/objects#UnixProcessObject-2', ['ProcessObjectType', 'AddressObjectType', 'PortObjectType']), + ('UnixFileObjectType', 'cybox.objects.unix_file_object.UnixFile', 'unix_file_object', 'http://cybox.mitre.org/objects#UnixFileObject-2', ['FileObjectType']), + ('UnixNetworkRouteEntryObjectType', 'cybox.objects.unix_network_route_entry_object.UnixNetworkRouteEntry', 'unix_network_route_entry_object', 'http://cybox.mitre.org/objects#UnixNetworkRouteEntryObject-2', ['NetworkRouteEntryObjectType', 'AddressObjectType']), + ('UnixPipeObjectType', 'cybox.objects.unix_pipe_object.UnixPipe', 'unix_pipe_object', 'http://cybox.mitre.org/objects#UnixPipeObject-2', ['PipeObjectType']), + ('UnixProcessObjectType', 'cybox.objects.unix_process_object.UnixProcess', 'unix_process_object', 'http://cybox.mitre.org/objects#UnixProcessObject-2', ['ProcessObjectType', 'AddressObjectType', 'PortObjectType']), ('UnixUserAccountObjectType', 'cybox.objects.unix_user_account_object.UnixUserAccount', 'unix_user_account_object', 'http://cybox.mitre.org/objects#UnixUserAccountObject-2', ['UserAccountObjectType', 'AccountObjectType']), - ('UnixVolumeObjectType', None, 'unix_volume_object', 'http://cybox.mitre.org/objects#UnixVolumeObject-2', ['VolumeObjectType']), + ('UnixVolumeObjectType', 'cybox.objects.unix_volume_object.UnixVolume', 'unix_volume_object', 'http://cybox.mitre.org/objects#UnixVolumeObject-2', ['VolumeObjectType']), ('URIObjectType', 'cybox.objects.uri_object.URI', 'uri_object', 'http://cybox.mitre.org/objects#URIObject-2', []), - ('URLHistoryObjectType', None, 'url_history_object', 'http://cybox.mitre.org/objects#URLHistoryObject-1', ['URIObjectType','HostnameObjectType']), + ('URLHistoryObjectType', 'cybox.objects.url_history_object.URLHistory', 'url_history_object', 'http://cybox.mitre.org/objects#URLHistoryObject-1', ['URIObjectType', 'HostnameObjectType']), ('UserAccountObjectType', 'cybox.objects.user_account_object.UserAccount', 'user_account_object', 'http://cybox.mitre.org/objects#UserAccountObject-2', ['AccountObjectType']), + ('UserSessionObjectType', 'cybox.objects.user_session_object.UserSession', 'user_session_object', 'http://cybox.mitre.org/objects#UserSessionObject-2', []), ('VolumeObjectType', 'cybox.objects.volume_object.Volume', 'volume_object', 'http://cybox.mitre.org/objects#VolumeObject-2', []), ('WhoisObjectType', 'cybox.objects.whois_object.WhoisEntry', 'whois_object', 'http://cybox.mitre.org/objects#WhoisObject-2', ['URIObjectType', 'AddressObjectType']), ('WindowsComputerAccountObjectType', 'cybox.objects.win_computer_account_object.WinComputerAccount', 'win_computer_account_object', 'http://cybox.mitre.org/objects#WinComputerAccountObject-2', ['AccountObjectType', 'PortObjectType']), @@ -168,7 +171,7 @@ def get_class_for_object_type(self, object_type): ('WindowsSystemRestoreObjectType', 'cybox.objects.win_system_restore_object.WinSystemRestore', 'win_system_restore_object', 'http://cybox.mitre.org/objects#WinSystemRestoreObject-2', []), ('WindowsTaskObjectType', 'cybox.objects.win_task_object.WinTask', 'win_task_object', 'http://cybox.mitre.org/objects#WinTaskObject-2', ['EmailMessageObjectType', 'FileObjectType', 'AddressObjectType', 'URIObjectType']), ('WindowsThreadObjectType', 'cybox.objects.win_thread_object.WinThread', 'win_thread_object', 'http://cybox.mitre.org/objects#WinThreadObject-2', ['WindowsHandleObjectType']), - ('WindowsUserAccountObjectType', 'cybox.objects.win_user_object.WinUser', 'win_user_account_object', 'http://cybox.mitre.org/objects#WinUserAccountObject-2', ['UserAccountObjectType', 'AccountObjectType']), + ('WindowsUserAccountObjectType', 'cybox.objects.win_user_account_object.WinUser', 'win_user_account_object', 'http://cybox.mitre.org/objects#WinUserAccountObject-2', ['UserAccountObjectType', 'AccountObjectType']), ('WindowsVolumeObjectType', 'cybox.objects.win_volume_object.WinVolume', 'win_volume_object', 'http://cybox.mitre.org/objects#WinVolumeObject-2', ['VolumeObjectType']), ('WindowsWaitableTimerObjectType', 'cybox.objects.win_waitable_timer_object.WinWaitableTimer', 'win_waitable_timer_object', 'http://cybox.mitre.org/objects#WinWaitableTimerObject-2', ['WindowsHandleObjectType']), ('X509CertificateObjectType', 'cybox.objects.x509_certificate_object.X509Certificate', 'x509_certificate_object', 'http://cybox.mitre.org/objects#X509CertificateObject-2', []), diff --git a/cybox/objects/archive_file_object.py b/cybox/objects/archive_file_object.py index 345e043b..5ccafc51 100644 --- a/cybox/objects/archive_file_object.py +++ b/cybox/objects/archive_file_object.py @@ -4,10 +4,27 @@ from mixbox import fields import cybox.bindings.archive_file_object as archive_binding -from cybox.common import Integer, String +from cybox.common import BaseProperty, Integer, String +from cybox.common.cipher import Cipher from cybox.objects.file_object import File +class ArchiveFileFormat(BaseProperty): + _binding = archive_binding + _binding_class = archive_binding.ArchiveFileFormatType + _namespace = 'http://cybox.mitre.org/objects#ArchiveFileObject-1' + + TERM_7ZIP = "7-ZIP" + TERM_APK = "APK" + TERM_CAB = "CAB" + TERM_DMG = "DMG" + TERM_JAR = "JAR" + TERM_RAR = "RAR" + TERM_SIT = "SIT" + TERM_TGZ = "TGZ" + TERM_ZIP = "ZIP" + + class ArchiveFile(File): _binding = archive_binding _binding_class = archive_binding.ArchiveFileObjectType @@ -15,10 +32,10 @@ class ArchiveFile(File): _XSI_NS = "ArchiveFileObj" _XSI_TYPE = "ArchiveFileObjectType" - archive_format = fields.TypedField("Archive_Format", String) + archive_format = fields.TypedField("Archive_Format", ArchiveFileFormat) version = fields.TypedField("Version", String) file_count = fields.TypedField("File_Count", Integer) - encryption_algorithm = fields.TypedField("Encryption_Algorithm", String) # TODO: Cipher may need its own class + encryption_algorithm = fields.TypedField("Encryption_Algorithm", Cipher) decryption_key = fields.TypedField("Decryption_Key", String) comment = fields.TypedField("Comment", String) archived_file = fields.TypedField("Archived_File", File, multiple=True) diff --git a/cybox/objects/arp_cache_object.py b/cybox/objects/arp_cache_object.py index 4c8d3fb1..88b3925c 100644 --- a/cybox/objects/arp_cache_object.py +++ b/cybox/objects/arp_cache_object.py @@ -7,7 +7,16 @@ import cybox.bindings.arp_cache_object as arp_binding from cybox.objects.address_object import Address from cybox.objects.system_object import NetworkInterface -from cybox.common import ObjectProperties, String +from cybox.common import BaseProperty, ObjectProperties, String + + +class ARPCacheEntryType(BaseProperty): + _binding = arp_binding + _binding_class = arp_binding.ARPCacheEntryTypeType + _namespace = "http://cybox.mitre.org/objects#ARPCacheObject-1" + + TERM_STATIC = "static" + TERM_DYNAMIC = "dynamic" class ARPCacheEntry(entities.Entity): @@ -17,7 +26,7 @@ class ARPCacheEntry(entities.Entity): ip_address = fields.TypedField("IP_Address", Address) physical_address = fields.TypedField("Physical_Address", String) - type_ = fields.TypedField("Type", String) + type_ = fields.TypedField("Type", ARPCacheEntryType) network_interface = fields.TypedField("Network_Interface", NetworkInterface) diff --git a/cybox/objects/artifact_object.py b/cybox/objects/artifact_object.py index 92561b67..25c25a22 100644 --- a/cybox/objects/artifact_object.py +++ b/cybox/objects/artifact_object.py @@ -12,10 +12,6 @@ import cybox.bindings.artifact_object as artifact_binding from cybox.common import ObjectProperties, String, HashList -_COMPRESSION_EXT_MAP = {} # Maps compression_mechanism property to implementation/extension classes -_ENCRYPTION_EXT_MAP = {} # Maps encryption_mechanism property to implementation/extension classes -_ENCODING_EXT_MAP = {} # Maps algorithm property to implementation/extension classes - def validate_artifact_type(instance, value): if value is None: @@ -139,9 +135,11 @@ def unpack(self, packed_data): class EncryptionFactory(entities.EntityFactory): + _ENCRYPTION_EXT_MAP = {} + @classmethod def entity_class(cls, key): - return _ENCRYPTION_EXT_MAP.get(key, Encryption) + return cls._ENCRYPTION_EXT_MAP.get(key, Encryption) @classmethod def dictkey(cls, mapping): @@ -151,16 +149,18 @@ def dictkey(cls, mapping): def objkey(cls, obj): return obj.encryption_mechanism - @staticmethod - def register_extension(cls): - _ENCRYPTION_EXT_MAP[cls._ENCRYPTION_TYPE] = cls - return cls + @classmethod + def register_extension(cls, new_cls): + cls._ENCRYPTION_EXT_MAP[new_cls._ENCRYPTION_TYPE] = new_cls + return new_cls class CompressionFactory(entities.EntityFactory): + _COMPRESSION_EXT_MAP = {} + @classmethod def entity_class(cls, key): - return _COMPRESSION_EXT_MAP.get(key, Compression) + return cls._COMPRESSION_EXT_MAP.get(key, Compression) @classmethod def dictkey(cls, mapping): @@ -170,16 +170,18 @@ def dictkey(cls, mapping): def objkey(cls, obj): return obj.compression_mechanism - @staticmethod - def register_extension(cls): - _COMPRESSION_EXT_MAP[cls._COMPRESSION_TYPE] = cls - return cls + @classmethod + def register_extension(cls, new_cls): + cls._COMPRESSION_EXT_MAP[new_cls._COMPRESSION_TYPE] = new_cls + return new_cls class EncodingFactory(entities.EntityFactory): + _ENCODING_EXT_MAP = {} + @classmethod def entity_class(cls, key): - return _ENCODING_EXT_MAP.get(key, Encoding) + return cls._ENCODING_EXT_MAP.get(key, Encoding) @classmethod def dictkey(cls, mapping): @@ -189,10 +191,10 @@ def dictkey(cls, mapping): def objkey(cls, obj): return getattr(obj, "algorithm", "Base64") # default is Base64 - @staticmethod - def register_extension(cls): - _ENCODING_EXT_MAP[cls._ENCODING_TYPE] = cls - return cls + @classmethod + def register_extension(cls, new_cls): + cls._ENCODING_EXT_MAP[new_cls._ENCODING_TYPE] = new_cls + return new_cls @CompressionFactory.register_extension diff --git a/cybox/objects/custom_object.py b/cybox/objects/custom_object.py index 0832caf8..1c6cc1c5 100644 --- a/cybox/objects/custom_object.py +++ b/cybox/objects/custom_object.py @@ -1,7 +1,6 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities from mixbox import fields import cybox.bindings.custom_object as custom_binding @@ -15,5 +14,5 @@ class Custom(ObjectProperties): _XSI_NS = "CustomObj" _XSI_TYPE = "CustomObjectType" - custom_name = fields.TypedField('custom_name') + custom_name = fields.TypedField("custom_name") description = fields.TypedField("Description", StructuredText) diff --git a/cybox/objects/device_object.py b/cybox/objects/device_object.py index 07d27d8e..34489e94 100644 --- a/cybox/objects/device_object.py +++ b/cybox/objects/device_object.py @@ -4,7 +4,8 @@ from mixbox import fields import cybox.bindings.device_object as device_binding -from cybox.common import ObjectProperties, String, StructuredText +from cybox.common import String, StructuredText +from cybox.common.object_properties import ObjectProperties, ObjectPropertiesFactory class Device(ObjectProperties): @@ -20,4 +21,4 @@ class Device(ObjectProperties): model = fields.TypedField("Model", String) serial_number = fields.TypedField("Serial_Number", String) firmware_version = fields.TypedField("Firmware_Version", String) - # system_details TODO: add PlatformSpecificationType + system_details = fields.TypedField("System_Details", ObjectProperties, factory=ObjectPropertiesFactory) diff --git a/cybox/objects/disk_object.py b/cybox/objects/disk_object.py index 337eebc1..e824a6e9 100644 --- a/cybox/objects/disk_object.py +++ b/cybox/objects/disk_object.py @@ -6,7 +6,7 @@ import cybox.bindings.disk_object as disk_binding from cybox.objects.disk_partition_object import DiskPartition -from cybox.common import ObjectProperties, String, UnsignedLong +from cybox.common import BaseProperty, ObjectProperties, String, UnsignedLong class PartitionList(entities.EntityList): @@ -17,6 +17,18 @@ class PartitionList(entities.EntityList): partition = fields.TypedField("Partition", DiskPartition, multiple=True) +class DiskType(BaseProperty): + _binding = disk_binding + _binding_class = disk_binding.DiskType + _namespace = "http://cybox.mitre.org/objects#DiskObject-2" + + TERM_REMOVABLE = "Removable" + TERM_FIXED = "Fixed" + TERM_REMOTE = "Remote" + TERM_CDROM = "CDRom" + TERM_RAMDISK = "RAMDisk" + + class Disk(ObjectProperties): _binding = disk_binding _binding_class = disk_binding.DiskObjectType @@ -28,4 +40,4 @@ class Disk(ObjectProperties): disk_size = fields.TypedField('Disk_Size', UnsignedLong) free_space = fields.TypedField('Free_Space', UnsignedLong) partition_list = fields.TypedField('Partition_List', PartitionList) - type_ = fields.TypedField('Type', String) + type_ = fields.TypedField('Type', DiskType) diff --git a/cybox/objects/dns_record_object.py b/cybox/objects/dns_record_object.py index 79f1b4fb..94f73013 100644 --- a/cybox/objects/dns_record_object.py +++ b/cybox/objects/dns_record_object.py @@ -1,12 +1,11 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities from mixbox import fields import cybox.bindings.dns_record_object as dns_record_binding from cybox.common import (Integer, HexBinary, ObjectProperties, String, - StructuredText, DateTime) + StructuredText, DateTime) from cybox.objects.address_object import Address from cybox.objects.uri_object import URI diff --git a/cybox/objects/library_object.py b/cybox/objects/library_object.py index c8f75412..9ab544d6 100644 --- a/cybox/objects/library_object.py +++ b/cybox/objects/library_object.py @@ -5,7 +5,20 @@ import cybox.bindings.library_object as library_binding from cybox.common.extracted_features import ExtractedFeatures -from cybox.common import ObjectProperties, String, UnsignedLong, HexBinary +from cybox.common import BaseProperty, ObjectProperties, String, UnsignedLong, HexBinary + + +class LibraryType(BaseProperty): + _binding = library_binding + _binding_class = library_binding.LibraryType + _namespace = "http://cybox.mitre.org/objects#LibraryObject-2" + default_datatype = "string" + + TYPE_DYNAMIC = "Dynamic" + TYPE_STATIC = "Static" + TYPE_REMOTE = "Remote" + TYPE_SHARED = "Shared" + TYPE_OTHER = "Other" class Library(ObjectProperties): @@ -18,7 +31,7 @@ class Library(ObjectProperties): name = fields.TypedField("Name", String) path = fields.TypedField("Path", String) size = fields.TypedField("Size", UnsignedLong) - type_ = fields.TypedField("Type", String) + type_ = fields.TypedField("Type", LibraryType) version = fields.TypedField("Version", String) base_address = fields.TypedField("Base_Address", HexBinary) extracted_features = fields.TypedField("Extracted_Features", ExtractedFeatures) diff --git a/cybox/objects/network_flow_object.py b/cybox/objects/network_flow_object.py new file mode 100644 index 00000000..1d00df40 --- /dev/null +++ b/cybox/objects/network_flow_object.py @@ -0,0 +1,564 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.network_flow_object as network_flow_binding +from cybox.common import ( + BaseProperty, HexBinary, Integer, ObjectProperties, PlatformSpecification, + PositiveInteger, String +) +from cybox.objects.address_object import Address +from cybox.objects.network_packet_object import TCPFlags +from cybox.objects.socket_address_object import SocketAddress + + +class NetflowV5FlowRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV5FlowRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + nexthop_ipv4_addr = fields.TypedField("Nexthop_IPv4_Addr", Address) + packet_count = fields.TypedField("Packet_Count", Integer) + byte_count = fields.TypedField("Byte_Count", Integer) + sysuptime_start = fields.TypedField("SysUpTime_Start", Integer) + sysuptime_end = fields.TypedField("SysUpTime_End", Integer) + padding1 = fields.TypedField("Padding1", HexBinary) + tcp_flags = fields.TypedField("TCP_Flags", HexBinary) + src_autonomous_system = fields.TypedField("Src_Autonomous_System", Integer) + dest_autonomous_system = fields.TypedField("Dest_Autonomous_System", Integer) + src_ip_mask_bit_count = fields.TypedField("Src_IP_Mask_Bit_Count", String) + dest_ip_mask_bit_count = fields.TypedField("Dest_IP_Mask_Bit_Count", String) + padding2 = fields.TypedField("Padding2", HexBinary) + + +class NetflowV5FlowHeader(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV5FlowHeaderType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + version = fields.TypedField("Version", HexBinary) + count = fields.TypedField("Count", Integer) + sys_up_time = fields.TypedField("Sys_Up_Time", Integer) + unix_secs = fields.TypedField("Unix_Secs", Integer) + unix_nsecs = fields.TypedField("Unix_Nsecs", Integer) + flow_sequence = fields.TypedField("Flow_Sequence", Integer) + engine_type = fields.TypedField("Engine_Type", String) + engine_id = fields.TypedField("Engine_ID", Integer) + sampling_interval = fields.TypedField("Sampling_Interval", HexBinary) + + def __init__(self): + super(NetflowV5FlowHeader, self).__init__() + self.version = "05" + + +class NetflowV5Packet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV5PacketType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_header = fields.TypedField("Flow_Header", NetflowV5FlowHeader) + flow_record = fields.TypedField("Flow_Record", NetflowV5FlowRecord, multiple=True) + + +class NetflowV9PacketHeader(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9PacketHeaderType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + version = fields.TypedField("Version", HexBinary) + record_count = fields.TypedField("Record_Count", Integer) + sys_up_time = fields.TypedField("Sys_Up_Time", Integer) + unix_secs = fields.TypedField("Unix_Secs", Integer) + sequence_number = fields.TypedField("Sequence_Number", Integer) + source_id = fields.TypedField("Source_ID", HexBinary) + + def __init__(self, version=None): + super(NetflowV9PacketHeader, self).__init__() + self.version = version or "09" + + +class NetflowV9ScopeField(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9ScopeFieldType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + TERM_SYSTEM = "System(1)" + TERM_INTERFACE = "Interface(2)" + TERM_LINE_CARD = "LineCard(3)" + TERM_CACHE = "Cache(4)" + TERM_TEMPLATE = "Template(5)" + + +class NetflowV9Field(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9FieldType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + TERM_IN_BYTES = "IN_BYTES(1)" + TERM_IN_PKTS = "IN_PKTS(2)" + TERM_FLOWS = "FLOWS(3)" + TERM_PROTOCOL = "PROTOCOL(4)" + TERM_TOS = "SRC_TOS(5)" + TERM_TCP_FLAGS = "TCP_FLAGS(6)" + TERM_L4_SRC_PORT = "L4_SRC_PORT(7)" + TERM_IPV4_SRC_ADDR = "IPV4_SRC_ADDR(8)" + TERM_SRC_MASK = "SRC_MASK(9)" + TERM_INPUT_SNMP = "INPUT_SNMP(10)" + TERM_L4_DST_PORT= "L4_DST_PORT(11)" + TERM_IPV4_DST_ADDR = "IPV4_DST_ADDR(12)" + TERM_DST_MASK= "DST_MASK(13)" + TERM_OUTPUT_SNMP = "OUTPUT_SNMP(14)" + TERM_IPV4_NEXT_HOP = "IPV4_NEXT_HOP(15)" + TERM_SRC_AS = "SRC_AS(16)" + TERM_DST_AS = "DST_AS(17)" + TERM_BGP_IPV4_NEXT_HOP = "BGP_IPV4_NEXT_HOP(18)" + TERM_MUL_DST_PKTS = "MUL_DST_PKTS(19)" + TERM_MUL_DST_BYTES = "MUL_DST_BYTES(20)" + + +class NetflowV9TemplateRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9TemplateRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_id = fields.TypedField("Template_ID", Integer) + field_count = fields.TypedField("Field_Count", Integer) + field_type = fields.TypedField("Field_Type", NetflowV9Field) + field_length = fields.TypedField("Field_Length", HexBinary) + + +class NetflowV9TemplateFlowSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9TemplateFlowSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_set_id = fields.TypedField("Flow_Set_ID", HexBinary) + length = fields.TypedField("Length", Integer) + template_record = fields.TypedField("Template_Record", NetflowV9TemplateRecord, multiple=True) + + def __init__(self): + super(NetflowV9TemplateFlowSet, self).__init__() + self.flow_set_id = "00" + + +class NetflowV9OptionsTemplateRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9OptionsTemplateRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_id = fields.TypedField("Template_ID", Integer) + option_scope_length = fields.TypedField("Option_Scope_Length", HexBinary) + option_length = fields.TypedField("Option_Length", HexBinary) + scope_field_type = fields.TypedField("Scope_Field_Type", NetflowV9ScopeField) + scope_field_length = fields.TypedField("Scope_Field_Length", HexBinary) + option_field_type = fields.TypedField("Option_Field_Type", NetflowV9Field) + option_field_length = fields.TypedField("Option_Field_Length", HexBinary) + + +class NetflowV9OptionsTemplateFlowSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9OptionsTemplateFlowSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_set_id = fields.TypedField("Flow_Set_ID", HexBinary) + length = fields.TypedField("Length", Integer) + options_template_record = fields.TypedField("Options_Template_Record", NetflowV9OptionsTemplateRecord, multiple=True) + padding = fields.TypedField("Padding", HexBinary) + + def __init__(self): + super(NetflowV9OptionsTemplateFlowSet, self).__init__() + self.flow_set_id = "01" + + +class FlowCollectionElement(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.FlowCollectionElementType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_record_field_value = fields.TypedField("Flow_Record_Field_Value", String, multiple=True) + + +class FlowDataRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.FlowDataRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_record_collection_element = fields.TypedField("Flow_Record_Collection_Element", FlowCollectionElement, multiple=True) + + +class OptionCollectionElement(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.OptionCollectionElementType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + option_record_field_value = fields.TypedField("Option_Record_Field_Value", String, multiple=True) + + +class OptionsDataRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.OptionsDataRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + scope_field_value = fields.TypedField("Scope_Field_Value", String) + option_record_collection_element = fields.TypedField("Option_Record_Collection_Element", OptionCollectionElement, multiple=True) + + +class NetflowV9DataRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9DataRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_data_record = fields.TypedField("Flow_Data_Record", FlowDataRecord, multiple=True) + options_data_record = fields.TypedField("Options_Data_Record", OptionsDataRecord, multiple=True) + + +class NetflowV9DataFlowSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9DataFlowSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_set_id_template_id = fields.TypedField("Flow_Set_ID_Template_ID", Integer) + length = fields.TypedField("Length", Integer) + data_record = fields.TypedField("Data_Record", NetflowV9DataRecord, multiple=True) + padding = fields.TypedField("Padding", HexBinary) + + +class NetflowV9FlowSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9FlowSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_flow_set = fields.TypedField("Template_Flow_Set", NetflowV9TemplateFlowSet) + options_template_flow_set = fields.TypedField("Options_Template_Flow_Set", NetflowV9OptionsTemplateFlowSet) + data_flow_set = fields.TypedField("Data_Flow_Set", NetflowV9DataFlowSet) + + +class NetflowV9ExportPacket(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetflowV9ExportPacketType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_header = fields.TypedField("Packet_Header", NetflowV9PacketHeader) + flow_set = fields.TypedField("Flow_Set", NetflowV9FlowSet, multiple=True) + + +class SiLKSensorDirection(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKDirectionType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + TERM_IN = "in" + TERM_IN_WEB = "inweb" + TERM_IN_NULL = "innull" + TERM_OUT = "out" + TERM_OUT_WEB = "outweb" + TERM_OUT_NULL = "outnull" + + +class SiLKSensorClass(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKSensorClassType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + TERM_ALL = "all" + + +class SiLKCountryCode(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKCountryCodeType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + +class SiLKAddress(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKAddressType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + TERM_NON_ROUTABLE = "non-routable (0)" + TERM_INTERNAL = "internal(1)" + TERM_EXTERNAL = "routable_external(2)" + + +class SiLKFlowAttributes(BaseProperty): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKAddressType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + TERM_F = "F (FIN flag)" + TERM_T = "T (Timeout)" + TERM_C = "C (Continuation)" + + +class SiLKSensorInfo(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKSensorInfoType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + sensor_id = fields.TypedField("Sensor_ID", String) + class_ = fields.TypedField("Class", SiLKSensorClass) + type_ = fields.TypedField("Type", SiLKSensorDirection) + + +class SiLKRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.SiLKRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + packet_count = fields.TypedField("Packet_Count", Integer) + byte_count = fields.TypedField("Byte_Count", Integer) + tcp_flags = fields.TypedField("TCP_Flags", HexBinary) + start_time = fields.TypedField("Start_Time", Integer) + duration = fields.TypedField("Duration", Integer) + end_time = fields.TypedField("End_Time", Integer) + sensor_info = fields.TypedField("Sensor_Info", SiLKSensorInfo) + icmp_type = fields.TypedField("ICMP_Type", Integer) + icmp_code = fields.TypedField("ICMP_Code", Integer) + router_next_hop_ip = fields.TypedField("Router_Next_Hop_IP", Address) + initial_tcp_flags = fields.TypedField("Initial_TCP_Flags", TCPFlags) + session_tcp_flags = fields.TypedField("Session_TCP_Flags", HexBinary) + flow_attributes = fields.TypedField("Flow_Attributes", SiLKFlowAttributes) + flow_application = fields.TypedField("Flow_Application", String) + src_ip_type = fields.TypedField("Src_IP_Type", SiLKAddress) + dest_ip_type = fields.TypedField("Dest_IP_Type", SiLKAddress) + src_country_code = fields.TypedField("Src_Country_Code", SiLKCountryCode) + dest_country_code = fields.TypedField("Dest_Country_Code", SiLKCountryCode) + src_mapname = fields.TypedField("Src_MAPNAME", String) + dest_mapname = fields.TypedField("Dest_MAPNAME", String) + + +class IPFIXMessageHeader(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXMessageHeaderType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + version = fields.TypedField("Version", HexBinary) + byte_length = fields.TypedField("Byte_Length", HexBinary) + export_timestamp = fields.TypedField("Export_Timestamp", Integer) + sequence_number = fields.TypedField("Sequence_Number", Integer) + observation_domain_id = fields.TypedField("Observation_Domain_ID", Integer) + + def __init__(self): + super(IPFIXMessageHeader, self).__init__() + self.version = "0a" + + +class IPFIXSetHeader(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXSetHeaderType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + set_id = fields.TypedField("Set_ID", Integer) + length = fields.TypedField("Length", Integer) + + +class IPFIXTemplateRecordHeader(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXTemplateRecordHeaderType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_id = fields.TypedField("Template_ID", Integer) + field_count = fields.TypedField("Field_Count", HexBinary) + + +class IPFIXTemplateRecordFieldSpecifiers(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXTemplateRecordFieldSpecifiersType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + enterprise_bit = fields.TypedField("Enterprise_Bit") + information_element_id = fields.TypedField("Information_Element_ID", String) + field_length = fields.TypedField("Field_Length", String) + enterprise_number = fields.TypedField("Enterprise_Number", String) + + +class IPFIXTemplateRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXTemplateRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_record_header = fields.TypedField("Template_Record_Header", IPFIXTemplateRecordHeader) + field_specifier = fields.TypedField("Field_Specifier", IPFIXTemplateRecordFieldSpecifiers, multiple=True) + + +class IPFIXTemplateSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXTemplateSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + set_header = fields.TypedField("Set_Header", IPFIXSetHeader) + template_record = fields.TypedField("Template_Record", IPFIXTemplateRecord, multiple=True) + padding = fields.TypedField("Padding", HexBinary) + + +class IPFIXOptionsTemplateRecordHeader(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXOptionsTemplateRecordHeaderType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_id = fields.TypedField("Template_ID", Integer) + field_count = fields.TypedField("Field_Count", HexBinary) + scope_field_count = fields.TypedField("Scope_Field_Count", PositiveInteger) + + +class IPFIXOptionsTemplateRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXOptionsTemplateRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + options_template_record_header = fields.TypedField("Options_Template_Record_Header", IPFIXOptionsTemplateRecordHeader) + field_specifier = fields.TypedField("Field_Specifier", IPFIXTemplateRecordFieldSpecifiers, multiple=True) + + +class IPFIXOptionsTemplateSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXOptionsTemplateSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + set_header = fields.TypedField("Set_Header", IPFIXSetHeader) + options_template_record = fields.TypedField("Options_Template_Record", IPFIXOptionsTemplateRecord, multiple=True) + padding = fields.TypedField("Padding", HexBinary) + + +class IPFIXDataRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXDataRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + field_value = fields.TypedField("Field_Value", String, multiple=True) + + +class IPFIXDataSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXDataSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + set_header = fields.TypedField("Set_Header", IPFIXSetHeader) + data_record = fields.TypedField("Data_Record", IPFIXDataRecord, multiple=True) + padding = fields.TypedField("Padding", HexBinary) + + +class IPFIXSet(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXSetType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + template_set = fields.TypedField("Template_Set", IPFIXTemplateSet) + options_template_set = fields.TypedField("Options_Template_Set", IPFIXOptionsTemplateSet) + data_set = fields.TypedField("Data_Set", IPFIXDataSet) + + +class IPFIXMessage(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.IPFIXMessageType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + message_header = fields.TypedField("Message_Header", IPFIXMessageHeader) + set_ = fields.TypedField("Set", IPFIXSet, multiple=True) + + +class UnidirectionalRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.UnidirectionalRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + ipfix_message = fields.TypedField("IPFIX_Message", IPFIXMessage) + netflowv9_export_packet = fields.TypedField("NetflowV9_Export_Packet", NetflowV9ExportPacket) + netflowv5_packet = fields.TypedField("NetflowV5_Packet", NetflowV5Packet) + silk_record = fields.TypedField("SiLK_Record", SiLKRecord) + + +class NetworkLayerInfo(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetworkLayerInfoType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + src_socket_address = fields.TypedField("Src_Socket_Address", SocketAddress) + dest_socket_address = fields.TypedField("Dest_Socket_Address", SocketAddress) + ip_protocol = fields.TypedField("IP_Protocol", String) + + +class NetworkFlowLabel(NetworkLayerInfo): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetworkFlowLabelType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + ingress_interface_index = fields.TypedField("Ingress_Interface_Index", Integer) + egress_interface_index = fields.TypedField("Egress_Interface_Index", Integer) + ip_type_of_service = fields.TypedField("IP_Type_Of_Service", HexBinary) + + +class YAFTCPFlow(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.YAFTCPFlowType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + tcp_sequence_number = fields.TypedField("TCP_Sequence_Number", Integer) + initial_tcp_flags = fields.TypedField("Initial_TCP_Flags", TCPFlags) + union_tcp_flags = fields.TypedField("Union_TCP_Flags", HexBinary) + + +class YAFFlow(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.YAFFlowType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow_start_milliseconds = fields.TypedField("Flow_Start_Milliseconds", Integer) + flow_end_milliseconds = fields.TypedField("Flow_End_Milliseconds", Integer) + octet_total_count = fields.TypedField("Octet_Total_Count", Integer) + packet_total_count = fields.TypedField("Packet_Total_Count", Integer) + flow_end_reason = fields.TypedField("Flow_End_Reason", HexBinary) + silk_app_label = fields.TypedField("SiLK_App_Label", Integer) + payload_entropy = fields.TypedField("Payload_Entropy", Integer) + ml_app_label = fields.TypedField("ML_App_Label", HexBinary) + tcp_flow = fields.TypedField("TCP_Flow", YAFTCPFlow) + vlan_id_mac_addr = fields.TypedField("Vlan_ID_MAC_Addr", Address) + passive_os_fingerprinting = fields.TypedField("Passive_OS_Fingerprinting", PlatformSpecification) + first_packet_banner = fields.TypedField("First_Packet_Banner", HexBinary) + second_packet_banner = fields.TypedField("Second_Packet_Banner", HexBinary) + n_bytes_payload = fields.TypedField("N_Bytes_Payload", HexBinary) + + +class YAFReverseFlow(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.YAFReverseFlowType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + reverse_octet_total_count = fields.TypedField("Reverse_Octet_Total_Count", Integer) + reverse_packet_total_count = fields.TypedField("Reverse_Packet_Total_Count", Integer) + reverse_payload_entropy = fields.TypedField("Reverse_Payload_Entropy", Integer) + reverse_flow_delta_milliseconds = fields.TypedField("Reverse_Flow_Delta_Milliseconds", Integer) + tcp_reverse_flow = fields.TypedField("TCP_Reverse_Flow", YAFTCPFlow) + reverse_vlan_id_mac_addr = fields.TypedField("Reverse_Vlan_ID_MAC_Addr", Address) + reverse_passive_os_fingerprinting = fields.TypedField("Reverse_Passive_OS_Fingerprinting", PlatformSpecification) + reverse_first_packet = fields.TypedField("Reverse_First_Packet", HexBinary) + reverse_n_bytes_payload = fields.TypedField("Reverse_N_Bytes_Payload", HexBinary) + + +class YAFRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.YAFRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + flow = fields.TypedField("Flow", YAFFlow) + reverse_flow = fields.TypedField("Reverse_Flow", YAFReverseFlow) + + +class BidirectionalRecord(entities.Entity): + _binding = network_flow_binding + _binding_class = network_flow_binding.BidirectionalRecordType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + + yaf_record = fields.TypedField("YAF_Record", YAFRecord) + + +class NetworkFlow(ObjectProperties): + _binding = network_flow_binding + _binding_class = network_flow_binding.NetworkFlowObjectType + _namespace = "http://cybox.mitre.org/objects#NetworkFlowObject-2" + _XSI_NS = "NetFlowObj" + _XSI_TYPE = "NetworkFlowObjectType" + + network_flow_label = fields.TypedField("Network_Flow_Label", NetworkFlowLabel) + unidirectional_flow_record = fields.TypedField("Unidirectional_Flow_Record", UnidirectionalRecord) + bidirectional_flow_record = fields.TypedField("Bidirectional_Flow_Record", BidirectionalRecord) diff --git a/cybox/objects/process_object.py b/cybox/objects/process_object.py index 0a64339b..ccf6117e 100644 --- a/cybox/objects/process_object.py +++ b/cybox/objects/process_object.py @@ -1,19 +1,46 @@ -# Copyright (c) 2017, The MITRE Corporation. All rights reserved. +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields +from mixbox import entities, fields +import cybox import cybox.bindings.process_object as process_binding from cybox.common import ObjectProperties, String, DateTime, UnsignedInteger, Duration, EnvironmentVariableList, ExtractedFeatures from cybox.objects.network_connection_object import NetworkConnection from cybox.objects.port_object import Port +class ProcessStatusFactory(entities.EntityFactory): + @classmethod + def entity_class(cls, key): + import cybox.objects.unix_process_object # noqa + return cybox.lookup_extension(key, default=ProcessStatus) + + +class ProcessStatus(entities.Entity): + _binding = process_binding + _binding_class = process_binding.ProcessStatusType + _namespace = "http://cybox.mitre.org/objects#ProcessObject-2" + _XSI_TYPE = None # overridden by subclasses + + def to_dict(self): + d = super(ProcessStatus, self).to_dict() + + if self._XSI_TYPE: + d["xsi:type"] = self._XSI_TYPE + + return d + + @staticmethod + def lookup_class(xsi_type): + return cybox.lookup_extension(xsi_type, default=ProcessStatus) + + class PortList(entities.EntityList): _binding = process_binding _binding_class = process_binding.PortListType _namespace = "http://cybox.mitre.org/objects#ProcessObject-2" + port = fields.TypedField("Port", Port, multiple=True) @@ -21,6 +48,7 @@ class NetworkConnectionList(entities.EntityList): _binding = process_binding _binding_class = process_binding.NetworkConnectionListType _namespace = "http://cybox.mitre.org/objects#ProcessObject-2" + network_connection = fields.TypedField("Network_Connection", NetworkConnection, multiple=True) @@ -28,6 +56,7 @@ class ChildPIDList(entities.EntityList): _binding = process_binding _binding_class = process_binding.ChildPIDListType _namespace = "http://cybox.mitre.org/objects#ProcessObject-2" + child_pid = fields.TypedField("Child_PID", UnsignedInteger, multiple=True) @@ -35,6 +64,7 @@ class ArgumentList(entities.EntityList): _binding = process_binding _binding_class = process_binding.ArgumentListType _namespace = "http://cybox.mitre.org/objects#ProcessObject-2" + argument = fields.TypedField("Argument", String, multiple=True) @@ -68,10 +98,8 @@ class Process(ObjectProperties): port_list = fields.TypedField("Port_List", PortList) network_connection_list = fields.TypedField("Network_Connection_List", NetworkConnectionList) start_time = fields.TypedField("Start_Time", DateTime) - #status TODO: Add support + status = fields.TypedField("Status", ProcessStatus, factory=ProcessStatusFactory) username = fields.TypedField("Username", String) user_time = fields.TypedField("User_Time", Duration) extracted_features = fields.TypedField("Extracted_Features", ExtractedFeatures) is_hidden = fields.TypedField("is_hidden") - - diff --git a/cybox/objects/system_object.py b/cybox/objects/system_object.py index 4a609128..0822a056 100644 --- a/cybox/objects/system_object.py +++ b/cybox/objects/system_object.py @@ -11,6 +11,7 @@ class DHCPServerList(entities.EntityList): + _binding = system_binding _binding_class = system_binding.DHCPServerListType _namespace = "http://cybox.mitre.org/objects#SystemObject-2" @@ -18,6 +19,7 @@ class DHCPServerList(entities.EntityList): class IPGatewayList(entities.EntityList): + _binding = system_binding _binding_class = system_binding.IPGatewayListType _namespace = "http://cybox.mitre.org/objects#SystemObject-2" @@ -34,13 +36,14 @@ class IPInfo(entities.Entity): class IPInfoList(entities.EntityList): + _binding = system_binding _binding_class = system_binding.IPInfoListType _namespace = "http://cybox.mitre.org/objects#SystemObject-2" - ip_info_list = fields.TypedField("IP_Info_List", IPInfo, multiple=True) + ip_info = fields.TypedField("IP_Info", IPInfo, multiple=True) -class OS(entities.Entity): +class OS(PlatformSpecification): _namespace = "http://cybox.mitre.org/objects#SystemObject-2" _binding = system_binding _binding_class = system_binding.OSType @@ -81,6 +84,7 @@ class NetworkInterface(entities.Entity): class NetworkInterfaceList(entities.EntityList): + _binding = system_binding _binding_class = system_binding.NetworkInterfaceListType _namespace = "http://cybox.mitre.org/objects#SystemObject-2" @@ -102,8 +106,7 @@ class System(ObjectProperties): network_interface_list = fields.TypedField("Network_Interface_List", NetworkInterfaceList) os = fields.TypedField("OS", OS) processor = fields.TypedField("Processor", String) - # TODO - # processor_architecture = fields.TypedField("Processor_Architecture", ProcessorArch) + processor_architecture = fields.TypedField("Processor_Architecture", String) system_time = fields.TypedField("System_Time", Time) timezone_dst = fields.TypedField("Timezone_DST", String) timezone_standard = fields.TypedField("Timezone_Standard", String) diff --git a/cybox/objects/unix_file_object.py b/cybox/objects/unix_file_object.py new file mode 100644 index 00000000..4f99f390 --- /dev/null +++ b/cybox/objects/unix_file_object.py @@ -0,0 +1,79 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import fields + +import cybox.bindings.unix_file_object as unix_file_binding +from cybox.common import String, UnsignedLong +from cybox.objects.file_object import File, FilePermissions + + +def _validate_unix_type(instance, value): + allowed = instance._ALLOWED_VALUES + if not value: + return + elif not allowed: + return + elif value in allowed: + return + else: + error = "Value must be one of {allowed}. Received '{value}'" + error = error.format(**locals()) + raise ValueError(error) + + +class UnixFilePermissions(FilePermissions): + _binding = unix_file_binding + _binding_class = unix_file_binding.UnixFilePermissionsType + _namespace = "http://cybox.mitre.org/objects#UnixFileObject-2" + + suid = fields.BooleanField("suid") + sgid = fields.BooleanField("sgid") + uread = fields.BooleanField("uread") + uwrite = fields.BooleanField("uwrite") + uexec = fields.BooleanField("uexec") + gread = fields.BooleanField("gread") + gwrite = fields.BooleanField("gwrite") + gexec = fields.BooleanField("gexec") + oread = fields.BooleanField("oread") + owrite = fields.BooleanField("owrite") + oexec = fields.BooleanField("oexec") + + +class UnixFile(File): + _binding = unix_file_binding + _binding_class = unix_file_binding.UnixFileObjectType + _namespace = "http://cybox.mitre.org/objects#UnixFileObject-2" + _XSI_NS = "UnixFileObj" + _XSI_TYPE = "UnixFileObjectType" + + TYPE_REGULAR_FILE = "regularfile" + TYPE_DIRECTORY = "directory" + TYPE_SOCKET = "socket" + TYPE_SYMBOLIC_LINK = "symboliclink" + TYPE_BLOCK_SPECIAL_FILE = "blockspecialfile" + TYPE_CHARACTER_SPECIAL_FILE = "characterspecialfile" + + _ALLOWED_VALUES = ( + TYPE_REGULAR_FILE, + TYPE_DIRECTORY, + TYPE_SOCKET, + TYPE_SYMBOLIC_LINK, + TYPE_BLOCK_SPECIAL_FILE, + TYPE_CHARACTER_SPECIAL_FILE + ) + + group_owner = fields.TypedField("Group_Owner", String) + inode = fields.TypedField("INode", UnsignedLong) + type_ = fields.TypedField("Type", String, preset_hook=_validate_unix_type) + + # Override abstract types + permissions = fields.TypedField('Permissions', UnixFilePermissions) + + @property + def privilege_list(self): + return self.permissions + + @privilege_list.setter + def privilege_list(self, value): + self.permissions = value diff --git a/cybox/objects/unix_network_route_entry_object.py b/cybox/objects/unix_network_route_entry_object.py new file mode 100644 index 00000000..4dd0a5a2 --- /dev/null +++ b/cybox/objects/unix_network_route_entry_object.py @@ -0,0 +1,22 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import fields + +import cybox.bindings.unix_network_route_entry_object as unix_network_route_entry_binding +from cybox.common import String, UnsignedInteger, UnsignedLong +from cybox.objects.network_route_entry_object import NetworkRouteEntry + + +class UnixNetworkRouteEntry(NetworkRouteEntry): + _binding = unix_network_route_entry_binding + _binding_class = unix_network_route_entry_binding.UnixNetworkRouteEntryObjectType + _namespace = "http://cybox.mitre.org/objects#UnixNetworkRouteEntryObject-2" + _XSI_NS = "UnixNetworkRouteEntryObj" + _XSI_TYPE = "UnixNetworkRouteEntryObjectType" + + flags = fields.TypedField("Flags", String) + mss = fields.TypedField("MSS", UnsignedInteger) + ref = fields.TypedField("Ref", UnsignedLong) + use = fields.TypedField("Use", UnsignedLong) + window = fields.TypedField("Window", UnsignedInteger) diff --git a/cybox/objects/unix_pipe_object.py b/cybox/objects/unix_pipe_object.py new file mode 100644 index 00000000..77e5ce15 --- /dev/null +++ b/cybox/objects/unix_pipe_object.py @@ -0,0 +1,18 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import fields + +import cybox.bindings.unix_pipe_object as unix_pipe_binding +from cybox.common import String +from cybox.objects.pipe_object import Pipe + + +class UnixPipe(Pipe): + _binding = unix_pipe_binding + _binding_class = unix_pipe_binding.UnixPipeObjectType + _namespace = "http://cybox.mitre.org/objects#UnixPipeObject-2" + _XSI_NS = "UnixPipeObj" + _XSI_TYPE = "UnixPipeObjectType" + + permission_mode = fields.TypedField("Permission_Mode", String) diff --git a/cybox/objects/unix_process_object.py b/cybox/objects/unix_process_object.py new file mode 100644 index 00000000..0e02c7aa --- /dev/null +++ b/cybox/objects/unix_process_object.py @@ -0,0 +1,55 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox +import cybox.bindings.unix_process_object as unix_process_binding +from cybox.common import BaseProperty, DateTime, NonNegativeInteger, UnsignedInteger +from cybox.objects.process_object import Process, ProcessStatus + + +class FileDescriptorList(entities.EntityList): + _binding = unix_process_binding + _binding_class = unix_process_binding.FileDescriptorListType + _namespace = "http://cybox.mitre.org/objects#UnixProcessObject-2" + + file_descriptor = fields.TypedField("File_Descriptor", UnsignedInteger, multiple=True) + + +class UnixProcessState(BaseProperty): + _binding = unix_process_binding + _binding_class = unix_process_binding.UnixProcessStateType + _namespace = "http://cybox.mitre.org/objects#UnixProcessObject-2" + + STATE_RUNNING = "Running" + STATE_UNINTERRUPTIBLE_SLEEP = "UninterruptibleSleep" + STATE_INTERRUPTIBLE_SLEEP = "InterruptibleSleep" + STATE_STOPPED = "Stopped" + STATE_PAGING = "Paging" + STATE_DEAD = "Dead" + STATE_ZOMBIE = "Zombie" + + +@cybox.register_extension +class UnixProcessStatus(ProcessStatus): + _binding = unix_process_binding + _binding_class = unix_process_binding.UnixProcessStatusType + _namespace = "http://cybox.mitre.org/objects#UnixProcessObject-2" + _XSI_TYPE = "UnixProcessObj:UnixProcessStatusType" + + current_status = fields.TypedField("Current_Status", UnixProcessState) + timestamp = fields.TypedField("Timestamp", DateTime) + + +class UnixProcess(Process): + _binding = unix_process_binding + _binding_class = unix_process_binding.UnixProcessObjectType + _namespace = "http://cybox.mitre.org/objects#UnixProcessObject-2" + _XSI_NS = "UnixProcessObj" + _XSI_TYPE = "UnixProcessObjectType" + + open_file_descriptor_list = fields.TypedField("Open_File_Descriptor_List", FileDescriptorList) + priority = fields.TypedField("Priority", NonNegativeInteger) + ruid = fields.TypedField("RUID", NonNegativeInteger) + session_id = fields.TypedField("Session_ID", NonNegativeInteger) diff --git a/cybox/objects/unix_volume_object.py b/cybox/objects/unix_volume_object.py new file mode 100644 index 00000000..833538e9 --- /dev/null +++ b/cybox/objects/unix_volume_object.py @@ -0,0 +1,19 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import fields + +import cybox.bindings.unix_volume_object as unix_volume_binding +from cybox.objects.volume_object import Volume +from cybox.common import String + + +class UnixVolume(Volume): + _binding = unix_volume_binding + _binding_class = unix_volume_binding.UnixVolumeObjectType + _namespace = "http://cybox.mitre.org/objects#UnixVolumeObject-2" + _XSI_NS = "UnixVolumeObj" + _XSI_TYPE = "UnixVolumeObjectType" + + mount_point = fields.TypedField("Mount_Point", String) + options = fields.TypedField("Options", String) diff --git a/cybox/objects/url_history_object.py b/cybox/objects/url_history_object.py new file mode 100644 index 00000000..9907009a --- /dev/null +++ b/cybox/objects/url_history_object.py @@ -0,0 +1,40 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import entities, fields + +import cybox.bindings.url_history_object as url_binding +from cybox.common import ( + DateTime, NonNegativeInteger, ObjectProperties, String, ToolInformation +) +from cybox.objects.hostname_object import Hostname +from cybox.objects.uri_object import URI + + +class URLHistoryEntry(entities.Entity): + _binding = url_binding + _binding_class = url_binding.URLHistoryEntryType + _namespace = "http://cybox.mitre.org/objects#URLHistoryObject-1" + + url = fields.TypedField("URL", URI) + hostname = fields.TypedField("Hostname", Hostname) + referrer_url = fields.TypedField("Referrer_URL", URI) + page_title = fields.TypedField("Page_Title", String) + user_profile_name = fields.TypedField("User_Profile_Name", String) + visit_count = fields.TypedField("Visit_Count", NonNegativeInteger) + manually_entered_count = fields.TypedField("Manually_Entered_Count", NonNegativeInteger) + modification_datetime = fields.TypedField("Modification_DateTime", DateTime) + expiration_datetime = fields.TypedField("Expiration_DateTime", DateTime) + first_visit_datetime = fields.TypedField("First_Visit_DateTime", DateTime) + last_visit_datetime = fields.TypedField("Last_Visit_DateTime", DateTime) + + +class URLHistory(ObjectProperties): + _binding = url_binding + _binding_class = url_binding.URLHistoryObjectType + _namespace = "http://cybox.mitre.org/objects#URLHistoryObject-1" + _XSI_NS = "URLHistoryObj" + _XSI_TYPE = "URLHistoryObjectType" + + browser_information = fields.TypedField("Browser_Information", ToolInformation) + url_history_entry = fields.TypedField("URL_History_Entry", URLHistoryEntry, multiple=True) diff --git a/cybox/objects/user_session_object.py b/cybox/objects/user_session_object.py new file mode 100644 index 00000000..c6cb3298 --- /dev/null +++ b/cybox/objects/user_session_object.py @@ -0,0 +1,22 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +from mixbox import fields + +import cybox.bindings.user_session_object as user_session_binding +from cybox.common import DateTime, String, ObjectProperties + + +class UserSession(ObjectProperties): + _binding = user_session_binding + _binding_class = user_session_binding.UserSessionObjectType + _namespace = "http://cybox.mitre.org/objects#UserSessionObject-2" + _XSI_NS = "UserSessionObj" + _XSI_TYPE = "UserSessionObjectType" + + effective_group = fields.TypedField("Effective_Group", String) + effective_group_id = fields.TypedField("Effective_Group_ID", String) + effective_user = fields.TypedField("Effective_User", String) + effective_user_id = fields.TypedField("Effective_User_ID", String) + login_time = fields.TypedField("Login_Time", DateTime) + logout_time = fields.TypedField("Logout_Time", DateTime) diff --git a/cybox/objects/volume_object.py b/cybox/objects/volume_object.py index e1a7ba3b..8c5996d4 100644 --- a/cybox/objects/volume_object.py +++ b/cybox/objects/volume_object.py @@ -1,11 +1,16 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields +from mixbox import entities, fields import cybox.bindings.volume_object as volume_binding -from cybox.common import ObjectProperties, String, DateTime, UnsignedLong, PositiveInteger, UnsignedInteger +from cybox.common import BaseProperty, ObjectProperties, String, DateTime, UnsignedLong, PositiveInteger, UnsignedInteger + + +class VolumeFileSystemFlag(BaseProperty): + _binding = volume_binding + _binding_class = volume_binding.VolumeFileSystemFlagType + _namespace = "http://cybox.mitre.org/objects#VolumeObject-2" class FileSystemFlagList(entities.EntityList): @@ -13,7 +18,7 @@ class FileSystemFlagList(entities.EntityList): _binding_class = volume_binding.FileSystemFlagListType _namespace = "http://cybox.mitre.org/objects#VolumeObject-2" - file_system_flag = fields.TypedField("File_System_Flag", String, multiple=True) + file_system_flag = fields.TypedField("File_System_Flag", VolumeFileSystemFlag, multiple=True) class Volume(ObjectProperties): diff --git a/cybox/objects/win_executable_file_object.py b/cybox/objects/win_executable_file_object.py index 0ac1e675..a53af87d 100644 --- a/cybox/objects/win_executable_file_object.py +++ b/cybox/objects/win_executable_file_object.py @@ -1,12 +1,14 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields +from mixbox import entities, fields +import cybox import cybox.bindings.win_executable_file_object as win_executable_file_binding -from cybox.common import (DateTime, DigitalSignature, Float, HashList, - HexBinary, Integer, Long, NonNegativeInteger, String, UnsignedLong, PositiveInteger) +from cybox.common import ( + DateTime, DigitalSignature, Float, HashList, HexBinary, Integer, Long, + NonNegativeInteger, String, PositiveInteger +) from cybox.objects.win_file_object import WinFile @@ -42,6 +44,7 @@ class PEExportedFunction(entities.Entity): class PEExportedFunctions(entities.EntityList): + _binding = win_executable_file_binding _binding_class = win_executable_file_binding.PEExportedFunctionsType _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" @@ -85,7 +88,7 @@ class DOSHeader(entities.Entity): reserved2 = fields.TypedField("reserved2", HexBinary) e_lfanew = fields.TypedField("e_lfanew", HexBinary) hashes = fields.TypedField("Hashes", HashList) - #reserved1 = [] unsupported for now + reserved1 = fields.TypedField("reserved1", HexBinary, multiple=True) class PEFileHeader(entities.Entity): @@ -126,7 +129,7 @@ class DataDirectory(entities.Entity): debug = fields.TypedField("Debug", PEDataDirectoryStruct) architecture = fields.TypedField("Architecture", PEDataDirectoryStruct) global_ptr = fields.TypedField("Global_Ptr", PEDataDirectoryStruct) - tls_table = fields.TypedField("Tls_Table", PEDataDirectoryStruct) + tls_table = fields.TypedField("TLS_Table", PEDataDirectoryStruct) load_config_table = fields.TypedField("Load_Config_Table", PEDataDirectoryStruct) bound_import = fields.TypedField("Bound_Import", PEDataDirectoryStruct) import_address_table = fields.TypedField("Import_Address_Table", PEDataDirectoryStruct) @@ -200,6 +203,7 @@ class PEImportedFunction(entities.Entity): class PEImportedFunctions(entities.EntityList): + _binding = win_executable_file_binding _binding_class = win_executable_file_binding.PEImportedFunctionsType _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" @@ -219,6 +223,7 @@ class PEImport(entities.Entity): class PEImportList(entities.EntityList): + _binding = win_executable_file_binding _binding_class = win_executable_file_binding.PEImportListType _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" @@ -235,10 +240,17 @@ class PEChecksum(entities.Entity): pe_file_raw = fields.TypedField("PE_File_Raw", Long) +class PEResourceFactory(entities.EntityFactory): + @classmethod + def entity_class(cls, key): + return cybox.lookup_extension(key, default=PEResource) + + class PEResource(entities.Entity): _binding = win_executable_file_binding _binding_class = win_executable_file_binding.PEResourceType _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" + _XSI_TYPE = None # overridden by subclasses type_ = fields.TypedField("Type", String) name = fields.TypedField("Name", String) @@ -249,29 +261,47 @@ class PEResource(entities.Entity): hashes = fields.TypedField("Hashes", HashList) data = fields.TypedField("Data", String) + def to_dict(self): + d = super(PEResource, self).to_dict() -class PEResourceList(entities.EntityList): - _binding_class = win_executable_file_binding.PEResourceListType + if self._XSI_TYPE: + d["xsi:type"] = self._XSI_TYPE + + return d + + @staticmethod + def lookup_class(xsi_type): + return cybox.lookup_extension(xsi_type, default=PEResource) + + +@cybox.register_extension +class PEVersionInfoResource(PEResource): + _binding = win_executable_file_binding + _binding_class = win_executable_file_binding.PEVersionInfoResourceType _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" + _XSI_TYPE = "WinExecutableFileObj:PEVersionInfoResourceType" - resource = fields.TypedField("Resource", PEResource, multiple=True) + comments = fields.TypedField("Comments", String) + companyname = fields.TypedField("CompanyName", String) + filedescription = fields.TypedField("FileDescription", String) + fileversion = fields.TypedField("FileVersion", String) + internalname = fields.TypedField("InternalName", String) + langid = fields.TypedField("LangID", String) + legalcopyright = fields.TypedField("LegalCopyright", String) + legaltrademarks = fields.TypedField("LegalTrademarks", String) + originalfilename = fields.TypedField("OriginalFilename", String) + privatebuild = fields.TypedField("PrivateBuild", String) + productname = fields.TypedField("ProductName", String) + productversion = fields.TypedField("ProductVersion", String) + specialbuild = fields.TypedField("SpecialBuild", String) - #VersionInfoResource temporary fix - @classmethod - def from_list(cls, seq): - if not seq: - return None - # TODO (bworrell): Should this just call cls(). Does this class need - # an EntityFactory? - pe_resource_list_ = super(PEResourceList, cls).from_list(seq) +class PEResourceList(entities.EntityList): + _binding = win_executable_file_binding + _binding_class = win_executable_file_binding.PEResourceListType + _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" - for pe_resource_dict in seq: - if PEVersionInfoResource.keyword_test(pe_resource_dict): - pe_resource_list_.append(PEVersionInfoResource.from_dict(pe_resource_dict)) - else: - pe_resource_list_.append(PEResource.from_dict(pe_resource_dict)) - return pe_resource_list_ + resource = fields.TypedField("Resource", PEResource, multiple=True, factory=PEResourceFactory) class PESectionHeaderStruct(entities.Entity): @@ -303,49 +333,13 @@ class PESection(entities.Entity): class PESectionList(entities.EntityList): + _binding = win_executable_file_binding _binding_class = win_executable_file_binding.PESectionListType _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" section = fields.TypedField("Section", PESection, multiple=True) -class PEVersionInfoResource(PEResource): - _binding = win_executable_file_binding - _binding_class = win_executable_file_binding.PEVersionInfoResourceType - _namespace = "http://cybox.mitre.org/objects#WinExecutableFileObject-2" - - comments = fields.TypedField("Comments", String) - companyname = fields.TypedField("CompanyName", String) - filedescription = fields.TypedField("FileDescription", String) - fileversion = fields.TypedField("FileVersion", String) - internalname = fields.TypedField("InternalName", String) - langid = fields.TypedField("LangID", String) - legalcopyright = fields.TypedField("LegalCopyright", String) - legaltrademarks = fields.TypedField("LegalTrademarks", String) - originalfilename = fields.TypedField("OriginalFilename", String) - privatebuild = fields.TypedField("PrivateBuild", String) - productname = fields.TypedField("ProductName", String) - productversion = fields.TypedField("ProductVersion", String) - specialbuild = fields.TypedField("SpecialBuild", String) - - @staticmethod - def keyword_test(pe_resource_dict): - keywords_list = ['comments', - 'companyname', - 'filedescription', - 'fileversion', - 'internalname', - 'langid', - 'legalcopyright', - 'originalfilename', - 'privatebuild', - 'productname', - 'productversion', - 'specialbuild'] - - return any(key in keywords_list for key in pe_resource_dict) - - class WinExecutableFile(WinFile): _binding = win_executable_file_binding _binding_class = win_executable_file_binding.WindowsExecutableFileObjectType diff --git a/cybox/objects/win_file_object.py b/cybox/objects/win_file_object.py index bfc596c1..cba50e9c 100644 --- a/cybox/objects/win_file_object.py +++ b/cybox/objects/win_file_object.py @@ -60,19 +60,16 @@ class WinFile(File): _XSI_NS = "WinFileObj" _XSI_TYPE = "WindowsFileObjectType" - filename_accessed_time = fields.TypedField("Filename_Accessed_Time", - DateTime) + filename_accessed_time = fields.TypedField("Filename_Accessed_Time", DateTime) filename_created_time = fields.TypedField("Filename_Created_Time", DateTime) - filename_modified_time = fields.TypedField("Filename_Modified_Time", - DateTime) + filename_modified_time = fields.TypedField("Filename_Modified_Time", DateTime) drive = fields.TypedField("Drive", String) security_id = fields.TypedField("Security_ID", String) security_type = fields.TypedField("Security_Type", String) stream_list = fields.TypedField("Stream_List", StreamList) - #Override abstract types - file_attributes_list = fields.TypedField('File_Attributes_List', - WindowsFileAttributes) + # Override abstract types + file_attributes_list = fields.TypedField('File_Attributes_List', WindowsFileAttributes) permissions = fields.TypedField('Permissions', WindowsFilePermissions) @property diff --git a/cybox/objects/win_process_object.py b/cybox/objects/win_process_object.py index cb7c64dc..4d63dd29 100644 --- a/cybox/objects/win_process_object.py +++ b/cybox/objects/win_process_object.py @@ -1,8 +1,7 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields +from mixbox import entities, fields import cybox.bindings.win_process_object as win_process_binding from cybox.common import String, Integer, PositiveInteger diff --git a/cybox/objects/win_user_object.py b/cybox/objects/win_user_account_object.py similarity index 100% rename from cybox/objects/win_user_object.py rename to cybox/objects/win_user_account_object.py diff --git a/cybox/objects/win_volume_object.py b/cybox/objects/win_volume_object.py index 97583917..ecbe88f4 100644 --- a/cybox/objects/win_volume_object.py +++ b/cybox/objects/win_volume_object.py @@ -1,12 +1,36 @@ # Copyright (c) 2017, The MITRE Corporation. All rights reserved. # See LICENSE.txt for complete terms. -from mixbox import entities -from mixbox import fields +from mixbox import entities, fields import cybox.bindings.win_volume_object as win_volume_binding from cybox.objects.volume_object import Volume -from cybox.common import String +from cybox.common import BaseProperty, String + + +class WindowsDrive(BaseProperty): + _binding = win_volume_binding + _binding_class = win_volume_binding.WindowsDriveType + _namespace = "http://cybox.mitre.org/objects#WinVolumeObject-2" + + TYPE_DRIVE_UNKNOWN = "DRIVE_UNKNOWN" + TYPE_DRIVE_NO_ROOT_DIR = "DRIVE_NO_ROOT_DIR" + TYPE_DRIVE_REMOVABLE = "DRIVE_REMOVABLE" + TYPE_DRIVE_FIXED = "DRIVE_FIXED" + TYPE_DRIVE_REMOTE = "DRIVE_REMOTE" + TYPE_DRIVE_CDROM = "DRIVE_CDROM" + TYPE_DRIVE_RAMDISK = "DRIVE_RAMDISK" + + +class WindowsVolumeAttribute(BaseProperty): + _binding = win_volume_binding + _binding_class = win_volume_binding.WindowsVolumeAttributeType + _namespace = "http://cybox.mitre.org/objects#WinVolumeObject-2" + + TYPE_READ_ONLY = "ReadOnly" + TYPE_HIDDEN = "Hidden" + TYPE_NO_DEFAULT_DRIVE_LETTER = "NoDefaultDriveLetter" + TYPE_SHADOW_COPY = "ShadowCopy" class WindowsVolumeAttributesList(entities.EntityList): @@ -14,7 +38,7 @@ class WindowsVolumeAttributesList(entities.EntityList): _binding_class = win_volume_binding.WindowsVolumeAttributesListType _namespace = "http://cybox.mitre.org/objects#WinVolumeObject-2" - attribute = fields.TypedField("Attribute", String, multiple=True) + attribute = fields.TypedField("Attribute", WindowsVolumeAttribute, multiple=True) class WinVolume(Volume): @@ -26,4 +50,4 @@ class WinVolume(Volume): attributes_list = fields.TypedField("Attributes_List", WindowsVolumeAttributesList) drive_letter = fields.TypedField("Drive_Letter", String) - drive_type = fields.TypedField("Drive_Type", String) + drive_type = fields.TypedField("Drive_Type", WindowsDrive) diff --git a/cybox/test/common/extracted_features_test.py b/cybox/test/common/extracted_features_test.py index e49bf2bb..0cb1fb67 100644 --- a/cybox/test/common/extracted_features_test.py +++ b/cybox/test/common/extracted_features_test.py @@ -14,6 +14,7 @@ from cybox.bindings.address_object import AddressObjectType setattr(cybox.bindings.cybox_common, "AddressObjectType", AddressObjectType) + class TestExtractedFeatures(EntityTestCase, unittest.TestCase): klass = ExtractedFeatures diff --git a/cybox/test/common/tools_test.py b/cybox/test/common/tools_test.py index 1e043e83..1b9ec33b 100644 --- a/cybox/test/common/tools_test.py +++ b/cybox/test/common/tools_test.py @@ -28,15 +28,33 @@ class TestToolInformation(EntityTestCase, unittest.TestCase): 'xsi:type': 'cyboxVocabs:ToolTypeVocab-1.1' } ], - 'description': {'structuring_format': 'HTML', - 'value': '

An awesome tool!

'}, - + 'description': { + 'structuring_format': 'HTML', + 'value': '

An awesome tool!

' + }, 'vendor': "Awesome Co.", 'version': "1.0.0", 'service_pack': 'N/A', - - 'tool_hashes': [{'simple_hash_value': EMPTY_MD5, - 'type': Hash.TYPE_MD5}], + 'references': { + 'reference': [ + { + 'reference_type': 'Other', + 'value': 'some-ref-value' + } + ], + }, + 'tool_hashes': [ + { + 'simple_hash_value': EMPTY_MD5, + 'type': Hash.TYPE_MD5 + } + ], + 'metadata': [ + { + 'type': 'uri', + 'value': 'tool metadata' + } + ] } diff --git a/cybox/test/core/observable_test.py b/cybox/test/core/observable_test.py index d9ce9a0a..29ace97e 100644 --- a/cybox/test/core/observable_test.py +++ b/cybox/test/core/observable_test.py @@ -22,23 +22,36 @@ class TestObservable(EntityTestCase, unittest.TestCase): 'id': "example:Observable-1", 'title': "An Observable", 'description': "A longer description of the observable", + 'negate': True, 'keywords': [ - "DANGER!", - "External", + u("DANGER!"), + u("External"), ], 'object': { + 'defined_effect': { + 'effect_type': 'Data_Read', + 'data': { + 'id': 'segment-1', + 'offset': 10, + }, + 'xsi:type': "cybox:DataReadEffectType", + }, 'properties': { 'file_name': u("example.txt"), 'xsi:type': "FileObjectType" }, }, 'sighting_count': 2, - 'observable_source': [{ - 'name': "ObservingTool", - }], - 'pattern_fidelity': - {'evasion_techniques': - [{'description':'XOR'}]} + 'observable_source': [ + { + 'name': "ObservingTool", + } + ], + 'pattern_fidelity': { + 'evasion_techniques': [ + {'description': 'XOR'} + ] + } } def test_keywords(self): @@ -202,9 +215,9 @@ def _set_event(observable, event): class TestObservables(EntityTestCase, unittest.TestCase): klass = Observables _full_dict = { - 'major_version': 2, - 'minor_version': 1, - 'update_version': 0, + 'cybox_major_version': '2', + 'cybox_minor_version': '1', + 'cybox_update_version': '0', 'observables': [ { 'id': "example:Observable-1", @@ -261,7 +274,7 @@ class TestObservables(EntityTestCase, unittest.TestCase): 'name': u("Modify File"), 'description': {'value': "An action!", 'structuring_format': "Text"}, - 'action_aliases': ['an alias', 'another_alias'], + 'action_aliases': [u('an alias'), u('another_alias')], 'action_arguments': [ { 'argument_name': u("infile"), diff --git a/cybox/test/objects/address_test.py b/cybox/test/objects/address_test.py index 3f1e721b..8564f824 100644 --- a/cybox/test/objects/address_test.py +++ b/cybox/test/objects/address_test.py @@ -20,7 +20,7 @@ class TestAddress(ObjectTestCase, unittest.TestCase): 'category': Address.CAT_IPV4, 'is_destination': True, 'is_source': False, - 'is_spoofed' : True, + 'is_spoofed': True, 'vlan_name': u("VLAN0"), 'vlan_num': 0, 'xsi:type': object_type, diff --git a/cybox/test/objects/archive_file_test.py b/cybox/test/objects/archive_file_test.py index a7581815..89ce8993 100644 --- a/cybox/test/objects/archive_file_test.py +++ b/cybox/test/objects/archive_file_test.py @@ -7,11 +7,11 @@ from cybox.objects.archive_file_object import ArchiveFile -from cybox.common import Hash, String +from cybox.common import Hash from cybox.compat import long -import cybox.test -from cybox.test import EntityTestCase from cybox.test.objects import ObjectTestCase +from cybox.test.objects.file_test import TestFile + class TestArchiveFile(ObjectTestCase, unittest.TestCase): object_type = "ArchiveFileObjectType" @@ -24,8 +24,10 @@ class TestArchiveFile(ObjectTestCase, unittest.TestCase): 'encryption_algorithm': u("some algorithm"), 'decryption_key': u("abc123key"), 'comment': u("This is a test"), - #'archived_file': [], - + 'archived_file': [ + TestFile._full_dict, + TestFile._full_dict, + ], 'is_packed': False, 'is_masqueraded': True, 'file_name': u("example.txt"), diff --git a/cybox/test/objects/disk_test.py b/cybox/test/objects/disk_test.py index 79820aad..fb2f3821 100644 --- a/cybox/test/objects/disk_test.py +++ b/cybox/test/objects/disk_test.py @@ -3,6 +3,8 @@ import unittest +from mixbox.vendor.six import u + from cybox.objects.disk_object import Disk from cybox.test.objects import ObjectTestCase @@ -12,7 +14,7 @@ class TestDisk(ObjectTestCase, unittest.TestCase): klass = Disk _full_dict = { - 'disk_name': u"A disk", + 'disk_name': u("A disk"), 'disk_size': 12345678, 'free_space': 1234567, 'partition_list': [ diff --git a/cybox/test/objects/dns_record_test.py b/cybox/test/objects/dns_record_test.py new file mode 100644 index 00000000..6eb6c93a --- /dev/null +++ b/cybox/test/objects/dns_record_test.py @@ -0,0 +1,36 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.dns_record_object import DNSRecord +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.address_test import TestAddress +from cybox.test.objects.uri_test import TestURI + + +class TestDNSRecord(ObjectTestCase, unittest.TestCase): + object_type = "DNSRecordObjectType" + klass = DNSRecord + + _full_dict = { + 'description': 'A description of this object', + 'domain_name': TestURI._full_dict, + 'queried_date': '2001-01-01T06:56:50+04:00', + 'ip_address': TestAddress._full_dict, + 'address_class': 'IPv4', + 'entry_type': 'SRV', + 'record_name': u('vc.example.com'), + 'record_type': 'DNS', + 'ttl': 14400, + 'flags': u('10'), + 'data_length': 13200, + 'record_data': u('Some Record Data'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/gui_dialogbox_test.py b/cybox/test/objects/gui_dialogbox_test.py new file mode 100644 index 00000000..7b319506 --- /dev/null +++ b/cybox/test/objects/gui_dialogbox_test.py @@ -0,0 +1,24 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.gui_dialogbox_object import GUIDialogbox +from cybox.test.objects import ObjectTestCase + + +class TestGUIDialogbox(ObjectTestCase, unittest.TestCase): + object_type = "GUIDialogboxObjectType" + klass = GUIDialogbox + + _full_dict = { + 'box_caption': u('Sample caption'), + 'box_text': u('Sample text'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/gui_test.py b/cybox/test/objects/gui_test.py new file mode 100644 index 00000000..e1bbff05 --- /dev/null +++ b/cybox/test/objects/gui_test.py @@ -0,0 +1,22 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from cybox.objects.gui_object import GUI +from cybox.test.objects import ObjectTestCase + + +class TestGUI(ObjectTestCase, unittest.TestCase): + object_type = "GUIObjectType" + klass = GUI + + _full_dict = { + 'height': 1024, + 'width': 768, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/gui_window_test.py b/cybox/test/objects/gui_window_test.py new file mode 100644 index 00000000..27d714a4 --- /dev/null +++ b/cybox/test/objects/gui_window_test.py @@ -0,0 +1,25 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.gui_window_object import GUIWindow +from cybox.test.objects import ObjectTestCase + + +class TestGUIWindow(ObjectTestCase, unittest.TestCase): + object_type = "GUIWindowObjectType" + klass = GUIWindow + + _full_dict = { + 'owner_window': u('owner window'), + 'parent_window': u('parent window'), + 'window_display_name': u('Tilte window'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/library_test.py b/cybox/test/objects/library_test.py new file mode 100644 index 00000000..db1b3777 --- /dev/null +++ b/cybox/test/objects/library_test.py @@ -0,0 +1,29 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.library_object import Library +from cybox.test.objects import ObjectTestCase + + +class TestLibrary(ObjectTestCase, unittest.TestCase): + object_type = "LibraryObjectType" + klass = Library + + _full_dict = { + 'name': u('libc'), + 'path': u('/lib/x86_64-linux-gnu/'), + 'size': 28000, + 'type': u('Dynamic'), + 'version': u('2.19'), + 'base_address': u('0x7ffff7bcf000'), + # 'extracted_features': '', + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/memory_test.py b/cybox/test/objects/memory_test.py index 8f1a824e..b1a957b0 100644 --- a/cybox/test/objects/memory_test.py +++ b/cybox/test/objects/memory_test.py @@ -25,7 +25,9 @@ class TestMemory(ObjectTestCase, unittest.TestCase): 'is_mapped': False, 'is_protected': True, 'is_volatile': False, - 'hashes': [{'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}], + 'hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5} + ], 'name': u("A memory region"), 'region_size': long(65536), 'memory_source': u(".data"), diff --git a/cybox/test/objects/network_flow_test.py b/cybox/test/objects/network_flow_test.py new file mode 100644 index 00000000..8332958c --- /dev/null +++ b/cybox/test/objects/network_flow_test.py @@ -0,0 +1,526 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.network_flow_object import ( + BidirectionalRecord, IPFIXDataSet, IPFIXTemplateRecord, IPFIXDataRecord, + IPFIXMessage, IPFIXSet, IPFIXMessageHeader, FlowDataRecord, + FlowCollectionElement, OptionsDataRecord, OptionCollectionElement, + IPFIXSetHeader, IPFIXOptionsTemplateRecord, + IPFIXOptionsTemplateRecordHeader, IPFIXOptionsTemplateSet, + IPFIXTemplateRecordFieldSpecifiers, IPFIXTemplateRecordHeader, + IPFIXTemplateSet, NetflowV5Packet, NetflowV5FlowHeader, + NetflowV5FlowRecord, NetflowV9DataFlowSet, NetflowV9PacketHeader, + NetflowV9ExportPacket, NetflowV9OptionsTemplateFlowSet, NetflowV9Field, + NetflowV9FlowSet, NetflowV9DataRecord, NetflowV9TemplateFlowSet, + NetflowV9TemplateRecord, NetflowV9OptionsTemplateRecord, NetworkFlow, + NetworkFlowLabel, NetworkLayerInfo, UnidirectionalRecord, SiLKRecord, + SiLKSensorInfo, SiLKFlowAttributes, SiLKAddress, SiLKSensorClass, + SiLKSensorDirection, YAFReverseFlow, YAFRecord, YAFFlow, YAFTCPFlow +) +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.address_test import TestAddress +from cybox.test.objects.network_packet_test import TestTCPFlags +from cybox.test.objects.socket_address_test import TestSocketAddress + + +class TestNetworkFlowLabel(EntityTestCase, unittest.TestCase): + klass = NetworkFlowLabel + + _full_dict = { + 'ingress_interface_index': 2, + 'egress_interface_index': 3, + 'src_socket_address': TestSocketAddress._full_dict, + 'dest_socket_address': TestSocketAddress._full_dict, + 'ip_protocol': 'TCP', + } + + +class TestNetworkLayerInfo(EntityTestCase, unittest.TestCase): + klass = NetworkLayerInfo + + _full_dict = { + 'src_socket_address': TestSocketAddress._full_dict, + 'dest_socket_address': TestSocketAddress._full_dict, + 'ip_protocol': 'TCP', + } + + +class TestYAFTCPFlow(EntityTestCase, unittest.TestCase): + klass = YAFTCPFlow + + _full_dict = { + 'tcp_sequence_number': 5, + 'initial_tcp_flags': TestTCPFlags._full_dict, + 'union_tcp_flags': u('0C'), + } + + +class TestYAFFlow(EntityTestCase, unittest.TestCase): + klass = YAFFlow + + _full_dict = { + 'flow_start_milliseconds': 1582060813, + 'flow_end_milliseconds': 1582060900, + 'octet_total_count': 144, + 'packet_total_count': 100, + 'flow_end_reason': u('0C'), + 'silk_app_label': 53, + 'payload_entropy': 34, + 'ml_app_label': u('0C'), + 'tcp_flow': TestYAFTCPFlow._full_dict, + 'vlan_id_mac_addr': TestAddress._full_dict, + 'passive_os_fingerprinting': { + 'description': u("The best platform"), + 'identifier': [ + u("value1") + ] + }, + 'first_packet_banner': u('00'), + 'second_packet_banner': u('0A'), + 'n_bytes_payload': u('EC'), + } + + +class TestYAFReverseFlow(EntityTestCase, unittest.TestCase): + klass = YAFReverseFlow + + _full_dict = { + 'reverse_octet_total_count': 144, + 'reverse_packet_total_count': 100, + 'reverse_payload_entropy': 25, + 'reverse_flow_delta_milliseconds': 1356, + 'tcp_reverse_flow': TestYAFTCPFlow._full_dict, + 'reverse_vlan_id_mac_addr': TestAddress._full_dict, + 'reverse_passive_os_fingerprinting': { + 'description': u("The best platform"), + 'identifier': [ + u("value1") + ] + }, + 'reverse_first_packet': u('00'), + 'reverse_n_bytes_payload': u('EC'), + } + + +class TestYAFRecord(EntityTestCase, unittest.TestCase): + klass = YAFRecord + + _full_dict = { + 'flow': TestYAFFlow._full_dict, + 'reverse_flow': TestYAFReverseFlow._full_dict, + } + + +class TestIPFIXSetHeader(EntityTestCase, unittest.TestCase): + klass = IPFIXSetHeader + + _full_dict = { + 'set_id': 35, + 'length': 100, + } + + +class TestIPFIXDataRecord(EntityTestCase, unittest.TestCase): + klass = IPFIXDataRecord + + _full_dict = { + 'field_value': [ + u('value1'), + u('value2'), + ] + } + + +class TestIPFIXMessageHeader(EntityTestCase, unittest.TestCase): + klass = IPFIXMessageHeader + + _full_dict = { + 'version': u('A0'), + 'byte_length': u('FEAC'), + 'export_timestamp': 1582060823, + 'sequence_number': 19382, + 'observation_domain_id': 245, + } + + +class TestIPFIXTemplateRecordFieldSpecifiers(EntityTestCase, unittest.TestCase): + klass = IPFIXTemplateRecordFieldSpecifiers + + _full_dict = { + 'enterprise_bit': True, + 'information_element_id': 'Something', + 'field_length': '128395', + 'enterprise_number': '1.3.6.1.4.1', + } + + +class TestIPFIXTemplateRecordHeader(EntityTestCase, unittest.TestCase): + klass = IPFIXTemplateRecordHeader + + _full_dict = { + 'template_id': 556, + 'field_count': 'FF452' + } + + +class TestIPFIXOptionsTemplateRecordHeader(EntityTestCase, unittest.TestCase): + klass = IPFIXOptionsTemplateRecordHeader + + _full_dict = { + 'template_id': 160, + 'field_count': 'BF45', + 'scope_field_count': 15, + } + + +class TestIPFIXDataSet(EntityTestCase, unittest.TestCase): + klass = IPFIXDataSet + + _full_dict = { + 'set_header': TestIPFIXSetHeader._full_dict, + 'data_record': [ + TestIPFIXDataRecord._full_dict + ], + 'padding': u('0C'), + } + + +class TestIPFIXOptionsTemplateRecord(EntityTestCase, unittest.TestCase): + klass = IPFIXOptionsTemplateRecord + + _full_dict = { + 'options_template_record_header': TestIPFIXOptionsTemplateRecordHeader._full_dict, + 'field_specifier': [ + TestIPFIXTemplateRecordFieldSpecifiers._full_dict + ] + } + + +class TestIPFIXOptionsTemplateSet(EntityTestCase, unittest.TestCase): + klass = IPFIXOptionsTemplateSet + + _full_dict = { + 'set_header': TestIPFIXSetHeader._full_dict, + 'options_template_record': [ + TestIPFIXOptionsTemplateRecord._full_dict + ], + 'padding': u('C0') + } + + +class TestIPFIXTemplateRecord(EntityTestCase, unittest.TestCase): + klass = IPFIXTemplateRecord + + _full_dict = { + 'template_record_header': TestIPFIXTemplateRecordHeader._full_dict, + 'field_specifier': [ + TestIPFIXTemplateRecordFieldSpecifiers._full_dict + ] + } + + +class TestIPFIXTemplateSet(EntityTestCase, unittest.TestCase): + klass = IPFIXTemplateSet + + _full_dict = { + 'set_header': TestIPFIXSetHeader._full_dict, + 'template_record': [ + TestIPFIXTemplateRecord._full_dict + ], + 'padding': u('FE') + } + + +class TestIPFIXSet(EntityTestCase, unittest.TestCase): + klass = IPFIXSet + + _full_dict = { + 'template_set': TestIPFIXTemplateSet._full_dict, + 'options_template_set': TestIPFIXOptionsTemplateSet._full_dict, + 'data_set': TestIPFIXDataSet._full_dict, + } + + +class TestIPFIXMessage(EntityTestCase, unittest.TestCase): + klass = IPFIXMessage + + _full_dict = { + 'message_header': TestIPFIXMessageHeader._full_dict, + 'set': [ + TestIPFIXSet._full_dict + ] + } + + +class TestNetflowV5FlowRecord(EntityTestCase, unittest.TestCase): + klass = NetflowV5FlowRecord + + _full_dict = { + 'nexthop_ipv4_addr': TestAddress._full_dict, + 'packet_count': 50, + 'byte_count': 123448, + 'sysuptime_start': 1582060823, + 'sysuptime_end': 1582060824, + 'padding1': u('0'), + 'tcp_flags': u('02'), + 'src_autonomous_system': 2, + 'dest_autonomous_system': 1, + 'src_ip_mask_bit_count': u('0'), + 'dest_ip_mask_bit_count': u('0'), + 'padding2': u('0'), + } + + +class TestNetflowV5FlowHeader(EntityTestCase, unittest.TestCase): + klass = NetflowV5FlowHeader + + _full_dict = { + 'version': u('05'), + 'count': 2, + 'sys_up_time': 1582060823, + 'unix_secs': 345, + 'unix_nsecs': 348, + 'flow_sequence': 55, + 'engine_type': u('Some Engine'), + 'engine_id': 4523, + 'sampling_interval': u('CE'), + } + + +class TestNetflowV5Packet(EntityTestCase, unittest.TestCase): + klass = NetflowV5Packet + + _full_dict = { + 'flow_header': TestNetflowV5FlowHeader._full_dict, + 'flow_record': [ + TestNetflowV5FlowRecord._full_dict + ] + } + + +class TestOptionCollectionElement(EntityTestCase, unittest.TestCase): + klass = OptionCollectionElement + + _full_dict = { + 'option_record_field_value': [ + u('Some Value2') + ] + } + + +class TestFlowCollectionElement(EntityTestCase, unittest.TestCase): + klass = FlowCollectionElement + + _full_dict = { + 'flow_record_field_value': [ + u('Some String') + ] + } + + +class TestFlowDataRecord(EntityTestCase, unittest.TestCase): + klass = FlowDataRecord + + _full_dict = { + 'flow_record_collection_element': [ + TestFlowCollectionElement._full_dict + ] + } + + +class TestOptionsDataRecord(EntityTestCase, unittest.TestCase): + klass = OptionsDataRecord + + _full_dict = { + 'scope_field_value': u('Some Value'), + 'option_record_collection_element': [ + TestOptionCollectionElement._full_dict + ] + } + + +class TestNetflowV9PacketHeader(EntityTestCase, unittest.TestCase): + klass = NetflowV9PacketHeader + + _full_dict = { + 'version': u('09'), + 'record_count': 20, + 'sys_up_time': 1582060823, + 'unix_secs': 34, + 'sequence_number': 553242, + 'source_id': u('312E'), + } + + +class TestNetflowV9DataRecord(EntityTestCase, unittest.TestCase): + klass = NetflowV9DataRecord + + _full_dict = { + 'flow_data_record': [ + TestFlowDataRecord._full_dict + ], + 'options_data_record': [ + TestOptionsDataRecord._full_dict + ], + } + + +class TestNetflowV9DataFlowSet(EntityTestCase, unittest.TestCase): + klass = NetflowV9DataFlowSet + + _full_dict = { + 'flow_set_id_template_id': 2, + 'length': 10, + 'data_record': [ + TestNetflowV9DataRecord._full_dict + ], + 'padding': u('DE'), + } + + +class TestNetflowV9TemplateRecord(EntityTestCase, unittest.TestCase): + klass = NetflowV9TemplateRecord + + _full_dict = { + 'template_id': 2345, + 'field_count': 110, + 'field_type': u(NetflowV9Field.TERM_IN_BYTES), + 'field_length': u('FF'), + } + + +class TestNetflowV9TemplateFlowSet(EntityTestCase, unittest.TestCase): + klass = NetflowV9TemplateFlowSet + + _full_dict = { + 'flow_set_id': u('AA'), + 'length': 100, + 'template_record': [ + TestNetflowV9TemplateRecord._full_dict + ], + } + + +class TestNetflowV9OptionsTemplateRecord(EntityTestCase, unittest.TestCase): + klass = NetflowV9OptionsTemplateRecord + + _full_dict = { + 'template_id': 341, + 'option_scope_length': u('A4'), + 'option_length': u('2'), + 'scope_field_type': u('Scope Type'), + 'scope_field_length': u('E0'), + 'option_field_type': u('IN_BYTES(1)'), + 'option_field_length': u('B0'), + } + + +class TestNetflowV9OptionsTemplateFlowSet(EntityTestCase, unittest.TestCase): + klass = NetflowV9OptionsTemplateFlowSet + + _full_dict = { + 'flow_set_id': u('01'), + 'length': 10, + 'options_template_record': [ + TestNetflowV9OptionsTemplateRecord._full_dict + ], + 'padding': u('AB'), + } + + +class TestNetflowV9FlowSet(EntityTestCase, unittest.TestCase): + klass = NetflowV9FlowSet + + _full_dict = { + 'template_flow_set': TestNetflowV9TemplateFlowSet._full_dict, + 'options_template_flow_set': TestNetflowV9OptionsTemplateFlowSet._full_dict, + 'data_flow_set': TestNetflowV9DataFlowSet._full_dict, + } + + +class TestNetflowV9ExportPacket(EntityTestCase, unittest.TestCase): + klass = NetflowV9ExportPacket + + _full_dict = { + 'packet_header': TestNetflowV9PacketHeader._full_dict, + 'flow_set': [ + TestNetflowV9FlowSet._full_dict + ] + } + + +class TestSiLKSensorInfo(EntityTestCase, unittest.TestCase): + klass = SiLKSensorInfo + + _full_dict = { + 'sensor_id': u('2349'), + 'class': u(SiLKSensorClass.TERM_ALL), + 'type': u(SiLKSensorDirection.TERM_IN), + } + + +class TestSiLKRecord(EntityTestCase, unittest.TestCase): + klass = SiLKRecord + + _full_dict = { + 'packet_count': 55, + 'byte_count': 12800, + 'tcp_flags': u('B9'), + 'start_time': 1582060823, + 'duration': 100, + 'end_time': 1582060923, + 'sensor_info': TestSiLKSensorInfo._full_dict, + 'icmp_type': 6, + 'icmp_code': 2, + 'router_next_hop_ip': TestAddress._full_dict, + 'initial_tcp_flags': TestTCPFlags._full_dict, + 'session_tcp_flags': u('3'), + 'flow_attributes': u(SiLKFlowAttributes.TERM_F), + 'flow_application': u('My Flow Application'), + 'src_ip_type': u(SiLKAddress.TERM_INTERNAL), + 'dest_ip_type': u(SiLKAddress.TERM_EXTERNAL), + 'src_country_code': u('US'), + 'dest_country_code': u('US'), + 'src_mapname': u('some value1'), + 'dest_mapname': u('some value2'), + } + + +class TestUnidirectionalRecord(EntityTestCase, unittest.TestCase): + klass = UnidirectionalRecord + + _full_dict = { + 'ipfix_message': TestIPFIXMessage._full_dict, + 'netflowv9_export_packet': TestNetflowV9ExportPacket._full_dict, + 'netflowv5_packet': TestNetflowV5Packet._full_dict, + 'silk_record': TestSiLKRecord._full_dict, + } + + +class TestBidirectionalRecord(EntityTestCase, unittest.TestCase): + klass = BidirectionalRecord + + _full_dict = { + 'yaf_record': TestYAFRecord._full_dict + } + + +class TestNetworkFlow(ObjectTestCase, unittest.TestCase): + object_type = "NetworkFlowObjectType" + klass = NetworkFlow + + _full_dict = { + 'network_flow_label': TestNetworkFlowLabel._full_dict, + 'unidirectional_flow_record': TestUnidirectionalRecord._full_dict, + 'bidirectional_flow_record': TestBidirectionalRecord._full_dict, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/network_packet_test.py b/cybox/test/objects/network_packet_test.py index 01df400b..b1a9c735 100644 --- a/cybox/test/objects/network_packet_test.py +++ b/cybox/test/objects/network_packet_test.py @@ -8,9 +8,9 @@ from cybox.bindings.cybox_core import parseString from cybox.core import Observables from cybox.objects.address_object import Address -from cybox.objects.network_packet_object import (ARP, EthernetInterface, - ICMPv4Packet, ICMPv6Packet, IPv4Packet, IPv6Packet, NDP, NDPPrefixInfo, - NDPLinkAddr, NetworkPacket, TCP, UDP) +from cybox.objects.network_packet_object import ( + ARP, EthernetInterface, ICMPv4Packet, ICMPv6Packet, IPv4Packet, + IPv6Packet, NDP, NDPPrefixInfo, NDPLinkAddr, NetworkPacket, TCP, TCPFlags, UDP) from cybox.test import EntityTestCase from cybox.test.objects import ObjectTestCase @@ -485,6 +485,22 @@ class TestICMPv6(EntityTestCase, unittest.TestCase): } +class TestTCPFlags(EntityTestCase, unittest.TestCase): + klass = TCPFlags + + _full_dict = { + 'ns': True, + 'cwr': True, + 'ece': True, + 'urg': True, + 'ack': True, + 'psh': True, + 'rst': True, + 'syn': True, + 'fin': True, + } + + class TestTCP(EntityTestCase, unittest.TestCase): klass = TCP @@ -500,17 +516,7 @@ class TestTCP(EntityTestCase, unittest.TestCase): 'ack_num': u("664d012a"), 'data_offset': u("20"), 'reserved': 1, - 'tcp_flags': { - 'ns': True, - 'cwr': True, - 'ece': True, - 'urg': True, - 'ack': True, - 'psh': True, - 'rst': True, - 'syn': True, - 'fin': True, - }, + 'tcp_flags': TestTCPFlags._full_dict, 'window': u("1460"), 'checksum': u("1fc1"), 'urg_ptr': u("0001") diff --git a/cybox/test/objects/network_route_test.py b/cybox/test/objects/network_route_test.py index 3630a215..e472565a 100644 --- a/cybox/test/objects/network_route_test.py +++ b/cybox/test/objects/network_route_test.py @@ -7,8 +7,8 @@ from cybox.objects.network_route_object import NetRoute -from cybox.test import EntityTestCase, round_trip from cybox.test.objects import ObjectTestCase +from cybox.test.objects.network_route_entry_test import TestNetworkRouteEntry class TestNetworkRoute(ObjectTestCase, unittest.TestCase): @@ -25,9 +25,13 @@ class TestNetworkRoute(ObjectTestCase, unittest.TestCase): 'preferred_lifetime': u("P10D"), 'valid_lifetime': u("P5D"), 'route_age': u("P1D"), - #'network_route_entries': [], + 'network_route_entries': [ + TestNetworkRouteEntry._full_dict, + TestNetworkRouteEntry._full_dict, + ], 'xsi:type': object_type, } + if __name__ == "__main__": unittest.main() diff --git a/cybox/test/objects/process_test.py b/cybox/test/objects/process_test.py new file mode 100644 index 00000000..17f3d79c --- /dev/null +++ b/cybox/test/objects/process_test.py @@ -0,0 +1,92 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.process_object import (ArgumentList, ChildPIDList, + ImageInfo, NetworkConnectionList, + PortList, Process) +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.network_connection_test import TestNetworkConnection +from cybox.test.objects.port_test import TestPort + + +class TestChildPIDList(EntityTestCase, unittest.TestCase): + klass = ChildPIDList + + _full_dict = [ + 22500, + 915, + ] + + +class TestPortList(EntityTestCase, unittest.TestCase): + klass = PortList + + _full_dict = [ + TestPort._full_dict, + TestPort._full_dict, + ] + + +class TestNetworkConnectionList(EntityTestCase, unittest.TestCase): + klass = NetworkConnectionList + + _full_dict = [ + TestNetworkConnection._full_dict, + TestNetworkConnection._full_dict, + ] + + +class TestArgumentList(EntityTestCase, unittest.TestCase): + klass = ArgumentList + + _full_dict = [ + u('-p'), + u('-d') + ] + + +class TestImageInfo(EntityTestCase, unittest.TestCase): + klass = ImageInfo + + _full_dict = { + 'file_name': 'testproc.bin', + 'command_line': 'testproc.bin -p -d', + 'current_directory': '/test', + 'path': '/home/some_path', + } + + +class TestProcess(ObjectTestCase, unittest.TestCase): + object_type = "ProcessObjectType" + klass = Process + + _full_dict = { + 'pid': 512, + 'name': u('testproc'), + 'creation_time': '2001-01-01T06:56:50+04:00', + 'parent_pid': 1024, + 'child_pid_list': TestChildPIDList._full_dict, + 'image_info': TestImageInfo._full_dict, + 'argument_list': TestArgumentList._full_dict, + 'environment_variable_list': [ + {'name': 'TEMP', 'value': 'C:/TEMP'}, + ], + 'kernel_time': u('293457969'), + 'port_list': TestPortList._full_dict, + 'network_connection_list': TestNetworkConnectionList._full_dict, + 'start_time': '2001-01-01T06:56:50+04:00', + 'username': u('jondoe'), + 'user_time': u('120'), + # 'extracted_features': '', + 'is_hidden': True, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/system_test.py b/cybox/test/objects/system_test.py new file mode 100644 index 00000000..de447a7c --- /dev/null +++ b/cybox/test/objects/system_test.py @@ -0,0 +1,131 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.system_object import (BIOSInfo, DHCPServerList, + IPGatewayList, IPInfo, + IPInfoList, NetworkInterface, + NetworkInterfaceList, OS, System) +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.address_test import TestAddress + + +class TestDHCPServerList(EntityTestCase, unittest.TestCase): + klass = DHCPServerList + + _full_dict = [ + TestAddress._full_dict, + ] + + +class TestIPGatewayList(EntityTestCase, unittest.TestCase): + klass = IPGatewayList + + _full_dict = [ + TestAddress._full_dict, + ] + + +class TestIPInfo(EntityTestCase, unittest.TestCase): + klass = IPInfo + + _full_dict = { + 'ip_address': TestAddress._full_dict, + 'subnet_mask': TestAddress._full_dict, + } + + +class TestIPInfoList(EntityTestCase, unittest.TestCase): + klass = IPInfoList + + _full_dict = [ + TestIPInfo._full_dict, + ] + + +class TestOS(EntityTestCase, unittest.TestCase): + klass = OS + + _full_dict = { + 'bitness': '64-bit', + 'build_number': '14393.693', + 'environment_variable_list': [ + {'name': 'TEMP', 'value': 'C:/TEMP'}, + ], + 'install_date': '2001-01-01', + 'patch_level': '10', + 'platform': { + 'description': u('A Windows platform'), + 'identifier': [ + u('Windows') + ], + }, + } + + +class TestBIOSInfo(EntityTestCase, unittest.TestCase): + klass = BIOSInfo + + _full_dict = { + 'bios_date': '2001-01-01', + 'bios_version': u('A19'), + 'bios_manufacturer': u('Fabrikam'), + 'bios_release_date': '2001-01-01', + 'bios_serial_number': u('7GHX44'), + } + + +class TestNetworkInterface(EntityTestCase, unittest.TestCase): + klass = NetworkInterface + + _full_dict = { + 'adapter': u('I350-T2V2'), + 'description': u('Test Network Interface'), + 'dhcp_lease_expires': '2001-01-01T06:56:50+04:00', + 'dhcp_lease_obtained': '2001-01-01T06:56:50+04:00', + 'dhcp_server_list': TestDHCPServerList._full_dict, + 'ip_gateway_list': TestIPGatewayList._full_dict, + 'ip_list': TestIPInfoList._full_dict, + 'mac': u('30:65:EC:6F:C4:58'), + } + + +class TestNetworkInterfaceList(EntityTestCase, unittest.TestCase): + klass = NetworkInterfaceList + + _full_dict = [ + TestNetworkInterface._full_dict, + TestNetworkInterface._full_dict, + ] + + +class TestSystem(ObjectTestCase, unittest.TestCase): + object_type = "SystemObjectType" + klass = System + + _full_dict = { + 'available_physical_memory': 3814697265600, + 'bios_info': TestBIOSInfo._full_dict, + 'date': '2001-01-01', + 'hostname': u('johndoe.frabikam.org'), + 'local_time': '06:56:50+04:00', + 'network_interface_list': TestNetworkInterfaceList._full_dict, + 'os': TestOS._full_dict, + 'processor': u('Intel Pentium II'), + 'processor_architecture': u('32-bit'), + 'system_time': '06:56:50+04:00', + 'timezone_dst': u('EDT'), + 'timezone_standard': u('GMT'), + 'total_physical_memory': 4000787030016, + 'uptime': u('3600'), + 'username': u('johndoe'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/unix_file_test.py b/cybox/test/objects/unix_file_test.py new file mode 100644 index 00000000..21b34252 --- /dev/null +++ b/cybox/test/objects/unix_file_test.py @@ -0,0 +1,44 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.unix_file_object import UnixFile, UnixFilePermissions +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestUnixFilePermissions(EntityTestCase, unittest.TestCase): + klass = UnixFilePermissions + _full_dict = { + 'suid': True, + 'sgid': False, + 'uread': True, + 'uwrite': True, + 'uexec': True, + 'gread': True, + 'gwrite': False, + 'gexec': False, + 'oread': True, + 'owrite': False, + 'oexec': False, + } + + +class TestUnixFile(ObjectTestCase, unittest.TestCase): + object_type = "UnixFileObjectType" + klass = UnixFile + + _full_dict = { + 'group_owner': u('samplegroup'), + 'inode': 6755399441071048, + 'type': u('regularfile'), + 'permissions': TestUnixFilePermissions._full_dict, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/unix_network_route_entry_test.py b/cybox/test/objects/unix_network_route_entry_test.py new file mode 100644 index 00000000..9847a534 --- /dev/null +++ b/cybox/test/objects/unix_network_route_entry_test.py @@ -0,0 +1,27 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.unix_network_route_entry_object import UnixNetworkRouteEntry +from cybox.test.objects import ObjectTestCase + + +class TestUnixNetworkRouteEntry(ObjectTestCase, unittest.TestCase): + object_type = "UnixNetworkRouteEntryObjectType" + klass = UnixNetworkRouteEntry + + _full_dict = { + 'flags': u('UG'), + 'mss': 0, + 'ref': 345, + 'use': 1642, + 'window': 518, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/unix_pipe_test.py b/cybox/test/objects/unix_pipe_test.py new file mode 100644 index 00000000..15b80b2f --- /dev/null +++ b/cybox/test/objects/unix_pipe_test.py @@ -0,0 +1,24 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.unix_pipe_object import UnixPipe +from cybox.test.objects import ObjectTestCase + + +class TestUnixPipe(ObjectTestCase, unittest.TestCase): + object_type = "UnixPipeObjectType" + klass = UnixPipe + + _full_dict = { + 'name': u("unix-pipe1"), + 'permission_mode': "0000ccff", + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/unix_process_test.py b/cybox/test/objects/unix_process_test.py new file mode 100644 index 00000000..7ebf6905 --- /dev/null +++ b/cybox/test/objects/unix_process_test.py @@ -0,0 +1,46 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.unix_process_object import FileDescriptorList, UnixProcess, UnixProcessStatus +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestFileDescriptorList(EntityTestCase, unittest.TestCase): + klass = FileDescriptorList + + _full_dict = [ + [345, 1345], + ] + + +class TestUnixProcessStatus(EntityTestCase, unittest.TestCase): + klass = UnixProcessStatus + + _full_dict = { + 'current_status': u('Running'), + 'timestamp': '2001-01-01T06:56:50+04:00', + 'xsi:type': 'UnixProcessObj:UnixProcessStatusType', + } + + +class TestUnixProcess(ObjectTestCase, unittest.TestCase): + object_type = "UnixProcessObjectType" + klass = UnixProcess + + _full_dict = { + 'open_file_descriptor_list': TestFileDescriptorList._full_dict, + 'status': TestUnixProcessStatus._full_dict, + 'ruid': 3485, + 'priority': 20, + 'session_id': 2345, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/unix_volume_test.py b/cybox/test/objects/unix_volume_test.py new file mode 100644 index 00000000..33faa4ec --- /dev/null +++ b/cybox/test/objects/unix_volume_test.py @@ -0,0 +1,25 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.unix_volume_object import UnixVolume +from cybox.test.objects import ObjectTestCase + + +class TestUnixVolume(ObjectTestCase, unittest.TestCase): + object_type = "UnixVolumeObjectType" + klass = UnixVolume + + _full_dict = { + 'is_mounted': True, + 'name': u('sda'), + 'mount_point': u('/boot/efi'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/url_history_test.py b/cybox/test/objects/url_history_test.py new file mode 100644 index 00000000..ce06b850 --- /dev/null +++ b/cybox/test/objects/url_history_test.py @@ -0,0 +1,60 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.url_history_object import URLHistory, URLHistoryEntry +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestUrlHistoryEntry(EntityTestCase, unittest.TestCase): + klass = URLHistoryEntry + + _full_dict = { + 'url': { + 'value': u('http://www.example.com/index.html'), + 'type': 'URL', + 'xsi:type': 'URIObjectType', + }, + 'hostname': { + 'hostname_value': u('www.example.com'), + 'xsi:type': 'HostnameObjectType', + }, + 'referrer_url': { + 'value': u('http://www.example2.com/index.html'), + 'type': 'URL', + 'xsi:type': 'URIObjectType', + }, + 'page_title': u('An example on URLHistoryEntry'), + 'user_profile_name': u('Default'), + 'visit_count': 5, + 'manually_entered_count': 1, + 'modification_datetime': '2001-01-01T06:56:50+04:00', + 'expiration_datetime': '2001-01-01T06:56:50+04:00', + 'first_visit_datetime': '2001-01-01T06:56:50+04:00', + 'last_visit_datetime': '2001-01-05T06:56:50+04:00', + } + + +class TestUrlHistory(ObjectTestCase, unittest.TestCase): + object_type = "URLHistoryObjectType" + klass = URLHistory + + _full_dict = { + 'browser_information': { + 'name': 'Google Chrome (64-bit)', + 'vendor': 'Google', + 'version': '80.0.3987.106' + }, + 'url_history_entry': [ + TestUrlHistoryEntry._full_dict + ], + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/user_session_test.py b/cybox/test/objects/user_session_test.py new file mode 100644 index 00000000..295cd29c --- /dev/null +++ b/cybox/test/objects/user_session_test.py @@ -0,0 +1,26 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from cybox.objects.user_session_object import UserSession +from cybox.test.objects import ObjectTestCase + + +class TestUserSession(ObjectTestCase, unittest.TestCase): + object_type = "UserSessionObjectType" + klass = UserSession + + _full_dict = { + 'effective_group': 'dev', + 'effective_group_id': '500', + 'effective_user': 'user-1', + 'effective_user_id': '25', + 'login_time': "2001-01-01T06:56:50+04:00", + 'logout_time': "2001-01-02T06:56:50+04:00", + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/volume_test.py b/cybox/test/objects/volume_test.py new file mode 100644 index 00000000..6a0f1751 --- /dev/null +++ b/cybox/test/objects/volume_test.py @@ -0,0 +1,43 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.volume_object import FileSystemFlagList, Volume +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestFileSystemFlagList(EntityTestCase, unittest.TestCase): + klass = FileSystemFlagList + + _full_dict = [ + u('FILE_UNICODE_ON_DISK'), + u('FILE_CASE_SENSITIVE_SEARCH'), + ] + + +class TestVolume(ObjectTestCase, unittest.TestCase): + object_type = "VolumeObjectType" + klass = Volume + + _full_dict = { + 'is_mounted': True, + 'name': u('sda'), + 'device_path': u('/dev/sda'), + 'file_system_type': u('ext4'), + 'total_allocation_units': 4000787030016, + 'sectors_per_allocation_unit': 976754646, + 'bytes_per_sector': 512, + 'actual_available_allocation_units': 3814697265600, + 'creation_time': '2001-01-01T06:56:50+04:00', + 'file_system_flag_list': TestFileSystemFlagList._full_dict, + 'serial_number': u('WD-WCC4E4LA4965'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_executable_file_test.py b/cybox/test/objects/win_executable_file_test.py new file mode 100644 index 00000000..ae05365c --- /dev/null +++ b/cybox/test/objects/win_executable_file_test.py @@ -0,0 +1,380 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_executable_file_object import ( + DataDirectory, DOSHeader, Entropy, PEBuildInformation, PEChecksum, + PEDataDirectoryStruct, PEExportedFunction, PEExportedFunctions, + PEExports, PEFileHeader, PEHeaders, PEImport, PEImportedFunction, + PEImportedFunctions, PEImportList, PEOptionalHeader, PEResource, + PEResourceList, PESection, PESectionHeaderStruct, PESectionList, + PEVersionInfoResource, WinExecutableFile +) +from cybox.test import EntityTestCase +from cybox.test.common.hash_test import EMPTY_MD5 +from cybox.test.common.digital_signature_test import TestDigitalSignature +from cybox.test.objects import ObjectTestCase + + +class TestPEDataDirectoryStruct(EntityTestCase, unittest.TestCase): + klass = PEDataDirectoryStruct + + _full_dict = { + 'virtual_address': u('0xFBCE'), + 'size': 23040, + } + + +class TestDataDirectory(EntityTestCase, unittest.TestCase): + klass = DataDirectory + + _full_dict = { + 'export_table': TestPEDataDirectoryStruct._full_dict, + 'import_table': TestPEDataDirectoryStruct._full_dict, + 'resource_table': TestPEDataDirectoryStruct._full_dict, + 'exception_table': TestPEDataDirectoryStruct._full_dict, + 'certificate_table': TestPEDataDirectoryStruct._full_dict, + 'base_relocation_table': TestPEDataDirectoryStruct._full_dict, + 'debug': TestPEDataDirectoryStruct._full_dict, + 'architecture': TestPEDataDirectoryStruct._full_dict, + 'global_ptr': TestPEDataDirectoryStruct._full_dict, + 'tls_table': TestPEDataDirectoryStruct._full_dict, + 'load_config_table': TestPEDataDirectoryStruct._full_dict, + 'bound_import': TestPEDataDirectoryStruct._full_dict, + 'import_address_table': TestPEDataDirectoryStruct._full_dict, + 'delay_import_descriptor': TestPEDataDirectoryStruct._full_dict, + 'clr_runtime_header': TestPEDataDirectoryStruct._full_dict, + 'reserved': TestPEDataDirectoryStruct._full_dict, + } + + +class TestDOSHeader(EntityTestCase, unittest.TestCase): + klass = DOSHeader + + _full_dict = { + 'e_magic': u('0x1'), + 'e_cblp': u('0x2'), + 'e_cp': u('0x3'), + 'e_crlc': u('0x4'), + 'e_cparhdr': u('0x5'), + 'e_minalloc': u('0x6'), + 'e_maxalloc': u('0x7'), + 'e_ss': u('0x8'), + 'e_sp': u('0x9'), + 'e_csum': u('0x10'), + 'e_ip': u('0x11'), + 'e_cs': u('0x12'), + 'e_lfarlc': u('0x13'), + 'e_ovro': u('0x14'), + 'e_oemid': u('0x15'), + 'e_oeminfo': u('0x16'), + 'reserved2': u('0x17'), + 'e_lfanew': u('0x18'), + 'hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}, + ], + 'reserved1': [u('0x20'), u('0x21'), u('0x22')], + } + + +class TestEntropy(EntityTestCase, unittest.TestCase): + klass = Entropy + + _full_dict = { + 'value': 3.45673, + 'min': 2.23467, + 'max': 4.42346, + } + + +class TestPEBuildInformation(EntityTestCase, unittest.TestCase): + klass = PEBuildInformation + + _full_dict = { + 'linker_name': u('lld'), + 'linker_version': u('11'), + 'compiler_name': u('GNU GCC'), + 'compiler_version': u('7.8.4'), + } + + +class TestPEChecksum(EntityTestCase, unittest.TestCase): + klass = PEChecksum + + _full_dict = { + 'pe_computed_api': 120, + 'pe_file_api': 12800, + 'pe_file_raw': 22500, + } + + +class TestPEExportedFunction(EntityTestCase, unittest.TestCase): + klass = PEExportedFunction + + _full_dict = { + 'function_name': u('important_calculation'), + 'entry_point': u('0x000ECB99'), + 'ordinal': 1, + } + + +class TestPEExportedFunctions(EntityTestCase, unittest.TestCase): + klass = PEExportedFunctions + + _full_dict = [ + TestPEExportedFunction._full_dict, + TestPEExportedFunction._full_dict, + ] + + +class TestPEExports(EntityTestCase, unittest.TestCase): + klass = PEExports + + _full_dict = { + 'name': u('PE Export Name'), + 'exported_functions': TestPEExportedFunctions._full_dict, + 'number_of_functions': 250, + 'exports_time_stamp': '2013-08-08T15:15:15-04:00', + 'number_of_addresses': 55000, + 'number_of_names': 10, + } + + +class TestPEFileHeader(EntityTestCase, unittest.TestCase): + klass = PEFileHeader + + _full_dict = { + 'machine': u('0xAA'), + 'number_of_sections': 3500, + 'time_date_stamp': u('0x000000005E619BF6'), + 'pointer_to_symbol_table': u('0x00023FEBB'), + 'number_of_symbols': 300, + 'size_of_optional_header': u('0x000CE'), + 'characteristics': u('0x4C'), + 'hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}, + ], + } + + +class TestPEImportedFunction(EntityTestCase, unittest.TestCase): + klass = PEImportedFunction + + _full_dict = { + 'function_name': u('important_calculation_2'), + 'hint': u('0xEEFB'), + 'ordinal': 2, + 'bound': u('0x213EFB'), + 'virtual_address': u('0x000AB12'), + } + + +class TestPEImportedFunctions(EntityTestCase, unittest.TestCase): + klass = PEImportedFunctions + + _full_dict = [ + TestPEImportedFunction._full_dict, + TestPEImportedFunction._full_dict, + ] + + +class TestPEImport(EntityTestCase, unittest.TestCase): + klass = PEImport + + _full_dict = { + 'delay_load': True, + 'initially_visible': True, + 'file_name': u('KERNEL32.GetModuleHandle'), + 'imported_functions': TestPEImportedFunctions._full_dict, + 'virtual_address': u('0x000000007B0D0000'), + } + + +class TestPEOptionalHeader(EntityTestCase, unittest.TestCase): + klass = PEOptionalHeader + + _full_dict = { + 'magic': u('0xECBA'), + 'major_linker_version': u('0x11'), + 'minor_linker_version': u('0x0'), + 'size_of_code': u('0x57E4'), + 'size_of_initialized_data': u('0x8CBA'), + 'size_of_uninitialized_data': u('0xEECB'), + 'address_of_entry_point': u('0x2345'), + 'base_of_code': u('0x0B35'), + 'base_of_data': u('0x0234'), + 'image_base': u('0xFFEE'), + 'section_alignment': u('0x00BC'), + 'file_alignment': u('0xBBEE'), + 'major_os_version': u('0x0011'), + 'minor_os_version': u('0x1001'), + 'major_image_version': u('0xEFD2'), + 'minor_image_version': u('0x328F'), + 'major_subsystem_version': u('0x5544'), + 'minor_subsystem_version': u('0x40FB'), + 'win32_version_value': u('0xAB0E'), + 'size_of_image': u('0xDE55'), + 'size_of_headers': u('0x34FF'), + 'checksum': u('0xABCDEF123456'), + 'subsystem': u('0xBC39012'), + 'dll_characteristics': u('0xDB45E'), + 'size_of_stack_reserve': u('0xAABB'), + 'size_of_stack_commit': u('0xEFFC'), + 'size_of_heap_reserve': u('0x2345'), + 'size_of_heap_commit': u('0xDEED'), + 'loader_flags': u('0xBEAD'), + 'number_of_rva_and_sizes': u('0x9823'), + 'data_directory': TestDataDirectory._full_dict, + 'hashes': [ + { + 'type': u("MD5"), + 'simple_hash_value': EMPTY_MD5, + } + ], + } + + +class TestPEHeaders(EntityTestCase, unittest.TestCase): + klass = PEHeaders + + _full_dict = { + 'dos_header': TestDOSHeader._full_dict, + 'signature': u('0x00000000ABAB045D'), + 'file_header': TestPEFileHeader._full_dict, + 'optional_header': TestPEOptionalHeader._full_dict, + 'entropy': TestEntropy._full_dict, + 'hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}, + ], + } + + +class TestPEImportList(EntityTestCase, unittest.TestCase): + klass = PEImportList + + _full_dict = [ + TestPEImport._full_dict, + TestPEImport._full_dict, + ] + + +class TestPEResource(EntityTestCase, unittest.TestCase): + klass = PEResource + + _full_dict = { + 'type': u('TypeLib'), + 'name': u('Some type lib'), + 'size': 12800, + 'virtual_address': u('0xDEADBEEF'), + 'language': u('en'), + 'sub_language': u('en_us'), + 'hashes': [ + { + 'type': u("MD5"), + 'simple_hash_value': EMPTY_MD5, + } + ], + 'data': u('Z2xlA2NvbQAADwABwAwADwABAAACKAAKACgFc210cDTADMAMAA8AAQAAAigACgAK'), + } + + +class TestPEVersionInfoResource(EntityTestCase, unittest.TestCase): + klass = PEVersionInfoResource + + _full_dict = { + 'comments': u('Some PE Comments'), + 'companyname': u('Fabrikam Corp'), + 'filedescription': u('Some File Description'), + 'fileversion': u('V1.0.0.1'), + 'internalname': u('Frabik'), + 'langid': u('0x0409'), + 'legalcopyright': u('(C)2011 Fabrikam Corp'), + 'legaltrademarks': u('Frabrik is a trademark of Fabrikam'), + 'originalfilename': u('testfile.sys'), + 'privatebuild': u('4352.54'), + 'productname': u('Fabrikam Driver'), + 'productversion': u('V1.0.0.1'), + 'specialbuild': u('V1.0.0.1a54'), + 'xsi:type': 'WinExecutableFileObj:PEVersionInfoResourceType', + } + + +class TestPEResourceList(EntityTestCase, unittest.TestCase): + klass = PEResourceList + + mixed_dict = TestPEVersionInfoResource._full_dict + mixed_dict.update(TestPEResource._full_dict) + + _full_dict = [ + TestPEResource._full_dict, + TestPEVersionInfoResource._full_dict, + mixed_dict, + ] + + +class TestPESectionHeaderStruct(EntityTestCase, unittest.TestCase): + klass = PESectionHeaderStruct + + _full_dict = { + 'name': u('Section Header Name'), + 'virtual_size': u('0xECBA5'), + 'virtual_address': u('0x00000002EF599'), + 'size_of_raw_data': u('0xFEB5503'), + 'pointer_to_raw_data': u('0x00FB'), + 'pointer_to_relocations': u('0xEEBC'), + 'pointer_to_linenumbers': u('0x00000635D'), + 'number_of_relocations': 5, + 'number_of_linenumbers': 200, + 'characteristics': u('0xABCD'), + } + + +class TestPESection(EntityTestCase, unittest.TestCase): + klass = PESection + + _full_dict = { + 'section_header': TestPESectionHeaderStruct._full_dict, + 'data_hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}, + ], + 'entropy': TestEntropy._full_dict, + 'header_hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}, + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5}, + ], + } + + +class TestPESectionList(EntityTestCase, unittest.TestCase): + klass = PESectionList + + _full_dict = [ + TestPESection._full_dict, + TestPESection._full_dict, + ] + + +class TestWinExecutableFile(ObjectTestCase, unittest.TestCase): + object_type = "WindowsExecutableFileObjectType" + klass = WinExecutableFile + + _full_dict = { + 'build_information': TestPEBuildInformation._full_dict, + 'digital_signature': TestDigitalSignature._full_dict, + 'exports': TestPEExports._full_dict, + 'extraneous_bytes': 345, + 'headers': TestPEHeaders._full_dict, + 'imports': TestPEImportList._full_dict, + 'pe_checksum': TestPEChecksum._full_dict, + 'resources': TestPEResourceList._full_dict, + 'sections': TestPESectionList._full_dict, + 'type': u('Executable'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_file_test.py b/cybox/test/objects/win_file_test.py index 3275d4f0..4f140650 100644 --- a/cybox/test/objects/win_file_test.py +++ b/cybox/test/objects/win_file_test.py @@ -6,7 +6,7 @@ from mixbox.vendor.six import u from cybox.compat import long -from cybox.objects.win_file_object import WinFile, Stream +from cybox.objects.win_file_object import WinFile, WindowsFilePermissions, Stream from cybox.test.common.hash_test import EMPTY_MD5 from cybox.test import EntityTestCase from cybox.test.objects import ObjectTestCase @@ -14,10 +14,29 @@ class TestStream(EntityTestCase, unittest.TestCase): klass = Stream - _full_dict = {'hashes': [{'type': u("MD5"), - 'simple_hash_value': EMPTY_MD5}], - 'name': u("StreamB"), - 'size_in_bytes': 204} + + _full_dict = { + 'hashes': [ + { + 'type': u("MD5"), + 'simple_hash_value': EMPTY_MD5, + } + ], + 'name': u("StreamB"), + 'size_in_bytes': 204, + } + + +class TestWindowsFilePermissions(EntityTestCase, unittest.TestCase): + klass = WindowsFilePermissions + + _full_dict = { + 'full_control': False, + 'modify': True, + 'read': True, + 'read_and_execute': False, + 'write': False, + } class TestWinFile(ObjectTestCase, unittest.TestCase): @@ -39,21 +58,13 @@ class TestWinFile(ObjectTestCase, unittest.TestCase): 'drive': u("C:"), 'security_id': u("S-1-5-21-3623958015-3361044348-30300820-1013"), 'security_type': u("SidTypeFile"), - 'stream_list': [{'name': u("StreamA")}, - {'hashes': [{'type': u("MD5"), - 'simple_hash_value': EMPTY_MD5}], - 'name': u("StreamB")}], - + 'stream_list': [ + {'name': u("StreamA")}, + TestStream._full_dict + ], # WinFile-specific implementations of abstract types. 'file_attributes_list': [u("Hidden"), u("System"), u("Temporary")], - 'permissions': { - 'full_control': False, - 'modify': True, - 'read': True, - 'read_and_execute': False, - 'write': False, - }, - + 'permissions': TestWindowsFilePermissions._full_dict, 'xsi:type': object_type, } diff --git a/cybox/test/objects/win_hook_test.py b/cybox/test/objects/win_hook_test.py index 30a0404e..bb5cea60 100644 --- a/cybox/test/objects/win_hook_test.py +++ b/cybox/test/objects/win_hook_test.py @@ -6,9 +6,8 @@ from mixbox.vendor.six import u from cybox.objects.win_hook_object import WinHook - -from cybox.test import EntityTestCase, round_trip from cybox.test.objects import ObjectTestCase +from cybox.test.objects.win_handle_test import TestWinHandle class TestWinHook(ObjectTestCase, unittest.TestCase): @@ -17,12 +16,13 @@ class TestWinHook(ObjectTestCase, unittest.TestCase): _full_dict = { 'type': u("Test Hook"), - #TODO: add 'handle' + 'handle': TestWinHandle._full_dict, 'hooking_function_name': u("test_function"), #TODO: add 'hooking_module' 'thread_id': 2, 'xsi:type': object_type, } + if __name__ == "__main__": unittest.main() diff --git a/cybox/test/objects/win_memory_page_region_test.py b/cybox/test/objects/win_memory_page_region_test.py index f5f6c4c2..cfdb1882 100644 --- a/cybox/test/objects/win_memory_page_region_test.py +++ b/cybox/test/objects/win_memory_page_region_test.py @@ -8,7 +8,8 @@ from cybox.objects.win_memory_page_region_object import WinMemoryPageRegion from cybox.compat import long -from cybox.test import EntityTestCase, round_trip +from cybox.test.common.hash_test import EMPTY_MD5 +from cybox.test.common.extracted_features_test import TestExtractedFeatures from cybox.test.objects import ObjectTestCase @@ -32,11 +33,13 @@ class TestWinMemoryPageRegion(ObjectTestCase, unittest.TestCase): 'allocation_protect': u("allocate protection"), 'state': u("A state"), 'protect': u("protection"), - # TODO: add: - # - 'extracted_features' - # - 'hashes' + 'extracted_features': TestExtractedFeatures._full_dict, + 'hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5} + ], 'xsi:type': object_type, } + if __name__ == "__main__": unittest.main() diff --git a/cybox/test/objects/win_mutex_test.py b/cybox/test/objects/win_mutex_test.py new file mode 100644 index 00000000..8b31177b --- /dev/null +++ b/cybox/test/objects/win_mutex_test.py @@ -0,0 +1,25 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_mutex_object import WinMutex +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.win_handle_test import TestWinHandle + + +class TestWinMutex(ObjectTestCase, unittest.TestCase): + object_type = "WindowsMutexObjectType" + klass = WinMutex + + _full_dict = { + 'handle': TestWinHandle._full_dict, + 'security_attributes': u("S-1-5-21-3623811015-3361044348-30300820-1013"), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_process_test.py b/cybox/test/objects/win_process_test.py new file mode 100644 index 00000000..134fcc48 --- /dev/null +++ b/cybox/test/objects/win_process_test.py @@ -0,0 +1,63 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_process_object import MemorySectionList, StartupInfo, WinProcess +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.memory_test import TestMemory +from cybox.test.objects.win_handle_test import TestWinHandle + + +class TestMemorySectionList(EntityTestCase, unittest.TestCase): + klass = MemorySectionList + + _full_dict = [ + TestMemory._full_dict, + TestMemory._full_dict + ] + + +class TestStartupInfo(EntityTestCase, unittest.TestCase): + klass = StartupInfo + + _full_dict = { + 'lpdesktop': u('Desktop Title'), + 'lptitle': u('Program Title'), + 'dwx': 0, + 'dwy': 0, + 'dwxsize': 800, + 'dwysize': 600, + 'dwxcountchars': 800, + 'dwycountchars': 600, + 'dwfillattribute': 1, + 'dwflags': 0, + 'wshowwindow': 1, + 'hstdinput': TestWinHandle._full_dict, + 'hstdoutput': TestWinHandle._full_dict, + 'hstderror': TestWinHandle._full_dict, + } + + +class TestWinProcess(ObjectTestCase, unittest.TestCase): + object_type = "WindowsProcessObjectType" + klass = WinProcess + + _full_dict = { + 'aslr_enabled': True, + 'dep_enabled': False, + 'priority': u('normal'), + 'section_list': TestMemorySectionList._full_dict, + 'security_id': u("S-1-5-21-3623811015-3361044348-30300820-1013"), + 'startup_info': TestStartupInfo._full_dict, + 'security_type': u("SidTypeUser"), + 'window_title': u('Example Title'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_service_test.py b/cybox/test/objects/win_service_test.py new file mode 100644 index 00000000..540578b0 --- /dev/null +++ b/cybox/test/objects/win_service_test.py @@ -0,0 +1,51 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_service_object import ServiceDescriptionList, WinService +from cybox.test import EntityTestCase +from cybox.test.common.hash_test import EMPTY_MD5 +from cybox.test.objects import ObjectTestCase + + +class TestServiceDescriptionList(EntityTestCase, unittest.TestCase): + klass = ServiceDescriptionList + + _full_dict = [ + u('Provides infrastructure support for deploying Store applications. This service is started on demand and if disabled Store applications will not be deployed to the system, and may not function properly.'), + u('Description 2'), + ] + + +class TestWinService(ObjectTestCase, unittest.TestCase): + object_type = "WindowsServiceObjectType" + klass = WinService + + _full_dict = { + 'service_dll_signature_exists': True, + 'service_dll_signature_verified': True, + 'description_list': TestServiceDescriptionList._full_dict, + 'display_name': u('AppXSvc'), + 'group_name': u('appx'), + 'service_name': u('AppX Deployment Service (AppXSVC)'), + 'service_dll': u('appxsvc.dll'), + 'service_dll_certificate_issuer': u('Microsoft Corporation'), + 'service_dll_certificate_subject': u('Frabrikam'), + 'service_dll_hashes': [ + {'type': u("MD5"), 'simple_hash_value': EMPTY_MD5} + ], + 'service_dll_signature_description': u('Something'), + 'startup_command_line': u('C:\WINDOWS\system32\svchost.exe -k wsappx -p'), + 'startup_type': u('SERVICE_AUTO_START'), + 'service_status': u('SERVICE_PAUSED'), + 'service_type': u('SERVICE_KERNEL_DRIVER'), + 'started_as': u('Local Service'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_system_test.py b/cybox/test/objects/win_system_test.py new file mode 100644 index 00000000..c5788425 --- /dev/null +++ b/cybox/test/objects/win_system_test.py @@ -0,0 +1,55 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_system_object import GlobalFlag, GlobalFlagList, WinSystem +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase +from cybox.test.objects.win_handle_test import TestWinHandle + + +class TestGlobalFlag(EntityTestCase, unittest.TestCase): + klass = GlobalFlag + + _full_dict = { + 'abbreviation': u('tst'), + 'destination': u('C:/TEST'), + 'hexadecimal_value': u('0x1'), + 'symbolic_name': u('somesymbol'), + } + + +class TestGlobalFlagList(EntityTestCase, unittest.TestCase): + klass = GlobalFlagList + + _full_dict = [ + TestGlobalFlag._full_dict, + TestGlobalFlag._full_dict, + ] + + +class TestWinSystem(ObjectTestCase, unittest.TestCase): + object_type = "WindowsSystemObjectType" + klass = WinSystem + + _full_dict = { + 'domain': [u('WORKINGGROUP')], + 'global_flag_list': TestGlobalFlagList._full_dict, + 'netbios_name': u('joe.local'), + 'open_handle_list': [TestWinHandle._full_dict], + 'product_id': u('00330-80000-00000-AA880'), + 'product_name': u('Windows 10'), + 'registered_organization': u('Fabrikam'), + 'registered_owner': u('Joe'), + 'windows_directory': u('C:\\WINDOWS'), + 'windows_system_directory': u('C:\\WINDOWS\\system32'), + 'windows_temp_directory': u('C:\\TEMP'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_user_account_test.py b/cybox/test/objects/win_user_account_test.py new file mode 100644 index 00000000..22d92b9b --- /dev/null +++ b/cybox/test/objects/win_user_account_test.py @@ -0,0 +1,74 @@ +# Copyright (c) 2017, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_user_account_object import WinGroup, WinGroupList, WinPrivilege, WinPrivilegeList, WinUser +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestWinGroup(EntityTestCase, unittest.TestCase): + klass = WinGroup + + _full_dict = { + 'name': u("LocalAdministrators"), + 'xsi:type': 'WindowsGroupType', + } + + +class TestWinGroupList(EntityTestCase, unittest.TestCase): + klass = WinGroupList + + _full_dict = [ + TestWinGroup._full_dict, + TestWinGroup._full_dict, + ] + + +class TestWinPrivilege(EntityTestCase, unittest.TestCase): + klass = WinPrivilege + + _full_dict = { + 'user_right': u("SeDebugPrivilege"), + 'xsi:type': 'WindowsPrivilegeType', + } + + +class TestWinPrivilegeList(EntityTestCase, unittest.TestCase): + klass = WinPrivilegeList + + _full_dict = [ + TestWinPrivilege._full_dict, + TestWinPrivilege._full_dict, + ] + + +class TestWinUser(ObjectTestCase, unittest.TestCase): + object_type = "WindowsUserAccountObjectType" + klass = WinUser + + _full_dict = { + # Account-specific fields + 'disabled': False, + 'domain': u('ADMIN'), + # UserAccount-specific fields + 'password_required': True, + 'full_name': u("Steve Ballmer"), + 'group_list': TestWinGroupList._full_dict, + 'home_directory': u("C:\\\\Users\\\\ballmer\\\\"), + 'last_login': "2011-05-12T07:14:01+07:00", + 'privilege_list': TestWinPrivilegeList._full_dict, + 'username': u("ballmer"), + 'user_password_age': u("P180D"), + # WinUser-specific fields + 'security_id': u("S-1-5-21-3623811015-3361044348-30300820-1013"), + 'security_type': u("SidTypeUser"), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_user_test.py b/cybox/test/objects/win_user_test.py deleted file mode 100644 index 3d88375d..00000000 --- a/cybox/test/objects/win_user_test.py +++ /dev/null @@ -1,47 +0,0 @@ -# Copyright (c) 2017, The MITRE Corporation. All rights reserved. -# See LICENSE.txt for complete terms. - -import unittest - -from mixbox.vendor.six import u - -from cybox.objects.win_user_object import WinUser -from cybox.test.objects import ObjectTestCase - - -class TestWinUser(ObjectTestCase, unittest.TestCase): - object_type = "WindowsUserAccountObjectType" - klass = WinUser - - _full_dict = { - # Account-specific fields - 'disabled': False, - 'domain': u('ADMIN'), - # UserAccount-specific fields - 'password_required': True, - 'full_name': u("Steve Ballmer"), - 'group_list': [ - { - 'name': u("LocalAdministrators"), - 'xsi:type': 'WindowsGroupType' - } - ], - 'home_directory': u("C:\\\\Users\\\\ballmer\\\\"), - 'last_login': "2011-05-12T07:14:01+07:00", - 'privilege_list': [ - { - 'user_right': u("SeDebugPrivilege"), - 'xsi:type': 'WindowsPrivilegeType' - } - ], - 'username': u("ballmer"), - 'user_password_age': u("P180D"), - # WinUser-specific fields - 'security_id': u("S-1-5-21-3623811015-3361044348-30300820-1013"), - 'security_type': u("SidTypeUser"), - 'xsi:type': object_type, - } - - -if __name__ == "__main__": - unittest.main() diff --git a/cybox/test/objects/win_volume_test.py b/cybox/test/objects/win_volume_test.py new file mode 100644 index 00000000..e5bac1f7 --- /dev/null +++ b/cybox/test/objects/win_volume_test.py @@ -0,0 +1,35 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.win_volume_object import WinVolume, WindowsVolumeAttributesList +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestWinVolumeAttributesList(EntityTestCase, unittest.TestCase): + klass = WindowsVolumeAttributesList + + _full_dict = [ + u('ReadOnly'), + u('Hidden') + ] + + +class TestWinVolume(ObjectTestCase, unittest.TestCase): + object_type = "WindowsVolumeObjectType" + klass = WinVolume + + _full_dict = { + 'attributes_list': TestWinVolumeAttributesList._full_dict, + 'drive_letter': u('D'), + 'drive_type': u('DRIVE_REMOVABLE'), + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/test/objects/win_waitable_timer_test.py b/cybox/test/objects/win_waitable_timer_test.py index cb1785cc..74665e45 100644 --- a/cybox/test/objects/win_waitable_timer_test.py +++ b/cybox/test/objects/win_waitable_timer_test.py @@ -6,8 +6,6 @@ from mixbox.vendor.six import u from cybox.objects.win_waitable_timer_object import WinWaitableTimer - -from cybox.test import EntityTestCase, round_trip from cybox.test.objects import ObjectTestCase @@ -22,5 +20,6 @@ class TestWinWaitableTimer(ObjectTestCase, unittest.TestCase): 'xsi:type': object_type, } + if __name__ == "__main__": unittest.main() diff --git a/cybox/test/objects/x509_certificate_test.py b/cybox/test/objects/x509_certificate_test.py new file mode 100644 index 00000000..cb8291dd --- /dev/null +++ b/cybox/test/objects/x509_certificate_test.py @@ -0,0 +1,127 @@ +# Copyright (c) 2020, The MITRE Corporation. All rights reserved. +# See LICENSE.txt for complete terms. + +import unittest + +from mixbox.vendor.six import u + +from cybox.objects.x509_certificate_object import (SubjectPublicKey, + RSAPublicKey, Validity, + X509Cert, X509Certificate, + X509CertificateSignature, + X509NonStandardExtensions, + X509V3Extensions) +from cybox.test import EntityTestCase +from cybox.test.objects import ObjectTestCase + + +class TestValidity(EntityTestCase, unittest.TestCase): + klass = Validity + + _full_dict = { + 'not_before': '2006-11-17T00:00:00+00:00', + 'not_after': '2036-07-16T23:59:59+00:00', + } + + +class TestRSAPublicKey(EntityTestCase, unittest.TestCase): + klass = RSAPublicKey + + _full_dict = { + 'modulus': u('00:ac:a0:f0:fb:80:59:d4:9c:c7:a4:cf:9d:a1:59:73:09:10:45:0c:0d:2c:6e:68:f1:6c:5b:48:68:49:59:37:fc:0b:33:19:c2:77:7f:cc:10:2d:95:34:1c:e6:eb:4d:09:a7:1c:d2:b8:c9:97:36:02:b7:89:d4:24:5f:06:c0:cc:44:94:94:8d:02:62:6f:eb:5a:dd:11:8d:28:9a:5c:84:90:10:7a:0d:bd:74:66:2f:6a:38:a0:e2:d5:54:44:eb:1d:07:9f:07:ba:6f:ee:e9:fd:4e:0b:29:f5:3e:84:a0:01:f1:9c:ab:f8:1c:7e:89:a4:e8:a1:d8:71:65:0d:a3:51:7b:ee:bc:d2:22:60:0d:b9:5b:9d:df:ba:fc:51:5b:0b:af:98:b2:e9:2e:e9:04:e8:62:87:de:2b:c8:d7:4e:c1:4c:64:1e:dd:cf:87:58:ba:4a:4f:ca:68:07:1d:1c:9d:4a:c6:d5:2f:91:cc:7c:71:72:1c:c5:c0:67:eb:32:fd:c9:92:5c:94:da:85:c0:9b:bf:53:7d:2b:09:f4:8c:9d:91:1f:97:6a:52:cb:de:09:36:a4:77:d8:7b:87:50:44:d5:3e:6e:29:69:fb:39:49:26:1e:09:a5:80:7b:40:2d:eb:e8:27:85:c9:fe:61:fd:7e:e6:7c:97:1d:d5:9d'), + 'exponent': 65537, + } + + +class TestSubjectPublicKey(EntityTestCase, unittest.TestCase): + klass = SubjectPublicKey + + _full_dict = { + 'public_key_algorithm': u('rsaEncryption'), + 'rsa_public_key': TestRSAPublicKey._full_dict, + } + + +class TestX509NonStandardExtensions(EntityTestCase, unittest.TestCase): + klass = X509NonStandardExtensions + + _full_dict = { + 'netscape_comment': u('some netscape comment'), + 'netscape_certificate_type': u('cert type'), + 'old_authority_key_identifier': u('CE:CB'), + 'old_primary_key_attributes': u('CA:TRUE'), + } + + +class TestX509V3Extensions(EntityTestCase, unittest.TestCase): + klass = X509V3Extensions + + _full_dict = { + 'basic_constraints': u('CA:TRUE'), + 'key_usage': u('Certificate Sign, CRL Sign'), + 'subject_key_identifier': u('7B:5B:45:CF:AF:CE:CB:7A:FD:31:92:1A:6A:B6:F3:46:EB:57:48:50') + } + + +class TestX509Cert(EntityTestCase, unittest.TestCase): + klass = X509Cert + + _full_dict = { + 'version': 3, + 'serial_number': u('34:4e:d5:57:20:d5:ed:ec:49:f4:2f:ce:37:db:2b:6d'), + 'signature_algorithm': u('sha1WithRSAEncryption'), + 'issuer': u('C = US, O = "thawte, Inc.", OU = Certification Services Division, OU = "(c) 2006 thawte, Inc. - For authorized use only", CN = thawte Primary Root CA'), + 'validity': TestValidity._full_dict, + 'subject': u('C = US, O = "thawte, Inc.", OU = Certification Services Division, OU = "(c) 2006 thawte, Inc. - For authorized use only", CN = thawte Primary Root CA'), + 'subject_public_key': TestSubjectPublicKey._full_dict, + 'standard_extensions': TestX509V3Extensions._full_dict, + } + + +class TestX509CertificateSignature(EntityTestCase, unittest.TestCase): + klass = X509CertificateSignature + + _full_dict = { + 'signature_algorithm': u('sha1WithRSAEncryption'), + 'signature': u('79:11:c0:4b:b3:91:b6:fc:f0:e9:67:d4:0d:6e:45:be:55:e8:93:d2:ce:03:3f:ed:da:25:b0:1d:57:cb:1e:3a:76:a0:4c:ec:50:76:e8:64:72:0c:a4:a9:f1:b8:8b:d6:d6:87:84:bb:32:e5:41:11:c0:77:d9:b3:60:9d:eb:1b:d5:d1:6e:44:44:a9:a6:01:ec:55:62:1d:77:b8:5c:8e:48:49:7c:9c:3b:57:11:ac:ad:73:37:8e:2f:78:5c:90:68:47:d9:60:60:e6:fc:07:3d:22:20:17:c4:f7:16:e9:c4:d8:72:f9:c8:73:7c:df:16:2f:15:a9:3e:fd:6a:27:b6:a1:eb:5a:ba:98:1f:d5:e3:4d:64:0a:9d:13:c8:61:ba:f5:39:1c:87:ba:b8:bd:7b:22:7f:f6:fe:ac:40:79:e5:ac:10:6f:3d:8f:1b:79:76:8b:c4:37:b3:21:18:84:e5:36:00:eb:63:20:99:b9:e9:fe:33:04:bb:41:c8:c1:02:f9:44:63:20:9e:81:ce:42:d3:d6:3f:2c:76:d3:63:9c:59:dd:8f:a6:e1:0e:a0:2e:41:f7:2e:95:47:cf:bc:fd:33:f3:f6:0b:61:7e:7e:91:2b:81:47:c2:27:30:ee:a7:10:5d:37:8f:5c:39:2b:e4:04:f0:7b:8d:56:8c:68'), + } + + +class TestX509Certificate(ObjectTestCase, unittest.TestCase): + object_type = "X509CertificateObjectType" + klass = X509Certificate + + _full_dict = { + 'certificate': TestX509Cert._full_dict, + 'raw_certificate': u('''-----BEGIN CERTIFICATE----- +MIIEIDCCAwigAwIBAgIQNE7VVyDV7exJ9C/ON9srbTANBgkqhkiG9w0BAQUFADCB +qTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5jLjEoMCYGA1UECxMf +Q2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYGA1UECxMvKGMpIDIw +MDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNlIG9ubHkxHzAdBgNV +BAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwHhcNMDYxMTE3MDAwMDAwWhcNMzYw +NzE2MjM1OTU5WjCBqTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDHRoYXd0ZSwgSW5j +LjEoMCYGA1UECxMfQ2VydGlmaWNhdGlvbiBTZXJ2aWNlcyBEaXZpc2lvbjE4MDYG +A1UECxMvKGMpIDIwMDYgdGhhd3RlLCBJbmMuIC0gRm9yIGF1dGhvcml6ZWQgdXNl +IG9ubHkxHzAdBgNVBAMTFnRoYXd0ZSBQcmltYXJ5IFJvb3QgQ0EwggEiMA0GCSqG +SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCsoPD7gFnUnMekz52hWXMJEEUMDSxuaPFs +W0hoSVk3/AszGcJ3f8wQLZU0HObrTQmnHNK4yZc2AreJ1CRfBsDMRJSUjQJib+ta +3RGNKJpchJAQeg29dGYvajig4tVUROsdB58Hum/u6f1OCyn1PoSgAfGcq/gcfomk +6KHYcWUNo1F77rzSImANuVud37r8UVsLr5iy6S7pBOhih94ryNdOwUxkHt3Ph1i6 +Sk/KaAcdHJ1KxtUvkcx8cXIcxcBn6zL9yZJclNqFwJu/U30rCfSMnZEfl2pSy94J +NqR32HuHUETVPm4pafs5SSYeCaWAe0At6+gnhcn+Yf1+5nyXHdWdAgMBAAGjQjBA +MA8GA1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBR7W0XP +r87Lev0xkhpqtvNG61dIUDANBgkqhkiG9w0BAQUFAAOCAQEAeRHAS7ORtvzw6WfU +DW5FvlXok9LOAz/t2iWwHVfLHjp2oEzsUHboZHIMpKnxuIvW1oeEuzLlQRHAd9mz +YJ3rG9XRbkREqaYB7FViHXe4XI5ISXycO1cRrK1zN44veFyQaEfZYGDm/Ac9IiAX +xPcW6cTYcvnIc3zfFi8VqT79aie2oetaupgf1eNNZAqdE8hhuvU5HIe6uL17In/2 +/qxAeeWsEG89jxt5dovEN7MhGITlNgDrYyCZuen+MwS7QcjBAvlEYyCegc5C09Y/ +LHbTY5xZ3Y+m4Q6gLkH3LpVHz7z9M/P2C2F+fpErgUfCJzDupxBdN49cOSvkBPB7 +jVaMaA== +-----END CERTIFICATE-----'''), + 'certificate_signature': TestX509CertificateSignature._full_dict, + 'xsi:type': object_type, + } + + +if __name__ == "__main__": + unittest.main() diff --git a/cybox/utils/nsparser.py b/cybox/utils/nsparser.py index 977c3224..a4ce0a0b 100644 --- a/cybox/utils/nsparser.py +++ b/cybox/utils/nsparser.py @@ -24,7 +24,7 @@ NS_DOMAINNAME_OBJECT = Namespace('http://cybox.mitre.org/objects#DomainNameObject-1', 'DomainNameObj', 'http://cybox.mitre.org/XMLSchema/objects/Domain_Name/1.0/Domain_Name_Object.xsd') NS_EMAILMESSAGE_OBJECT = Namespace('http://cybox.mitre.org/objects#EmailMessageObject-2', 'EmailMessageObj', 'http://cybox.mitre.org/XMLSchema/objects/Email_Message/2.1/Email_Message_Object.xsd') NS_FILE_OBJECT = Namespace('http://cybox.mitre.org/objects#FileObject-2', 'FileObj', 'http://cybox.mitre.org/XMLSchema/objects/File/2.1/File_Object.xsd') -NS_GUIDIALOGBOX_OBJECT = Namespace('http://cybox.mitre.org/objects#GUIDialogboxObject-2', 'GUIDialogboxObj', 'http://cybox.mitre.org/XMLSchema/objects/GUI_Dialogbox/2.1/GUI_Dialogbox_Object.xsd') +NS_GUIDIALOGBOX_OBJECT = Namespace('http://cybox.mitre.org/objects#GUIDialogboxObject-2', 'GUIDialogBoxObj', 'http://cybox.mitre.org/XMLSchema/objects/GUI_Dialogbox/2.1/GUI_Dialogbox_Object.xsd') NS_GUI_OBJECT = Namespace('http://cybox.mitre.org/objects#GUIObject-2', 'GUIObj', 'http://cybox.mitre.org/XMLSchema/objects/GUI/2.1/GUI_Object.xsd') NS_GUIWINDOW_OBJECT = Namespace('http://cybox.mitre.org/objects#GUIWindowObject-2', 'GUIWindowObj', 'http://cybox.mitre.org/XMLSchema/objects/GUI_Window/2.1/GUI_Window_Object.xsd') NS_HOSTNAME_OBJECT = Namespace('http://cybox.mitre.org/objects#HostnameObject-1', 'HostnameObj', 'http://cybox.mitre.org/XMLSchema/objects/Hostname/1.0/Hostname_Object.xsd') @@ -53,13 +53,14 @@ NS_SYSTEM_OBJECT = Namespace('http://cybox.mitre.org/objects#SystemObject-2', 'SystemObj', 'http://cybox.mitre.org/XMLSchema/objects/System/2.1/System_Object.xsd') NS_UNIXFILE_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixFileObject-2', 'UnixFileObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_File/2.1/Unix_File_Object.xsd') NS_UNIXNETWORKROUTEENTRY_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixNetworkRouteEntryObject-2', 'UnixNetworkRouteEntryObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_Network_Route_Entry/2.1/Unix_Network_Route_Entry_Object.xsd') -NS_UNIXPIPE_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixPipeObject', 'UnixPipeObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_Pipe/2.1/Unix_Pipe_Object.xsd') +NS_UNIXPIPE_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixPipeObject-2', 'UnixPipeObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_Pipe/2.1/Unix_Pipe_Object.xsd') NS_UNIXPROCESS_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixProcessObject-2', 'UnixProcessObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_Process/2.1/Unix_Process_Object.xsd') NS_UNIXUSERACCOUNT_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixUserAccountObject-2', 'UnixUserAccountObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_User_Account/2.1/Unix_User_Account_Object.xsd') NS_UNIXVOLUME_OBJECT = Namespace('http://cybox.mitre.org/objects#UnixVolumeObject-2', 'UnixVolumeObj', 'http://cybox.mitre.org/XMLSchema/objects/Unix_Volume/2.1/Unix_Volume_Object.xsd') NS_URI_OBJECT = Namespace('http://cybox.mitre.org/objects#URIObject-2', 'URIObj', 'http://cybox.mitre.org/XMLSchema/objects/URI/2.1/URI_Object.xsd') NS_URLHISTORY_OBJECT = Namespace('http://cybox.mitre.org/objects#URLHistoryObject-1', 'URLHistoryObj', 'http://cybox.mitre.org/XMLSchema/objects/URL_History/1.0/URL_History_Object.xsd') NS_USERACCOUNT_OBJECT = Namespace('http://cybox.mitre.org/objects#UserAccountObject-2', 'UserAccountObj', 'http://cybox.mitre.org/XMLSchema/objects/User_Account/2.1/User_Account_Object.xsd') +NS_USERSESSION_OBJECT = Namespace('http://cybox.mitre.org/objects#UserSessionObject-2', 'UserSessionObj', 'http://cybox.mitre.org/XMLSchema/objects/User_Session/2.1/User_Session_Object.xsd') NS_VOLUME_OBJECT = Namespace('http://cybox.mitre.org/objects#VolumeObject-2', 'VolumeObj', 'http://cybox.mitre.org/XMLSchema/objects/Volume/2.1/Volume_Object.xsd') NS_WHOIS_OBJECT = Namespace('http://cybox.mitre.org/objects#WhoisObject-2', 'WhoisObj', 'http://cybox.mitre.org/XMLSchema/objects/Whois/2.1/Whois_Object.xsd') NS_WINCOMPUTERACCOUNT_OBJECT = Namespace('http://cybox.mitre.org/objects#WinComputerAccountObject-2', 'WinComputerAccountObj', 'http://cybox.mitre.org/XMLSchema/objects/Win_Computer_Account/2.1/Win_Computer_Account_Object.xsd') diff --git a/docs/api/coverage.rst b/docs/api/coverage.rst index 355ca8c6..5dab9ad0 100644 --- a/docs/api/coverage.rst +++ b/docs/api/coverage.rst @@ -11,11 +11,11 @@ CybOX Features CybOX Construct API Coverage Documentation ============================= ========================== ========================================== Composite Observable ✓ Full :class:`cybox.core.observable.ObservableComposition` -Event ⚠ Partial :class:`cybox.core.event.Event` -Object ⚠ Partial :class:`cybox.core.object.Object` -Observables ⚠ Partial :class:`cybox.core.observable.Observables` -Observable ⚠ Partial :class:`cybox.core.observable.Observable` -Relationships ⚠ Partial +Event ✓ Full :class:`cybox.core.event.Event` +Object ✓ Full :class:`cybox.core.object.Object` +Observables ✓ Full :class:`cybox.core.observable.Observables` +Observable ✓ Full :class:`cybox.core.observable.Observable` +Relationships ✓ Full :class:`cybox.core.object.RelatedObject` ============================= ========================== ========================================== CybOX Objects @@ -32,7 +32,7 @@ ARP Cache Object ✓ Full :class:`cybox.obje Artifact Object ✓ Full :class:`cybox.objects.artifact_object.Artifact` AS Object ✓ Full :class:`cybox.objects.as_object.AutonomousSystem` Code Object ✓ Full :class:`cybox.objects.code_object.Code` -Custom Object × None +Custom Object ✓ Full :class:`cybox.objects.custom_object.Custom` Device Object ✓ Full :class:`cybox.objects.device_object.Device` Disk Object ✓ Full :class:`cybox.objects.disk_object.Disk` Disk Partition Object ✓ Full :class:`cybox.objects.disk_partition_object.DiskPartition` @@ -54,7 +54,7 @@ Linux Package Object ✓ Full :class:`cybox.obje Memory Object ✓ Full :class:`cybox.objects.memory_object.Memory` Mutex Object ✓ Full :class:`cybox.objects.mutex_object.Mutex` Network Connection Object ✓ Full :class:`cybox.objects.network_connection_object.NetworkConnection` -Network Flow Object × None +Network Flow Object ✓ Full :class:`cybox.objects.network_flow_object.NetworkFlow` Network Packet Object ✓ Full :class:`cybox.objects.network_packet_object.NetworkPacket` Network Route Entry Object ✓ Full :class:`cybox.objects.network_route_entry_object.NetworkRouteEntry` Network Route Object ✓ Full :class:`cybox.objects.network_route_object.NetRoute` @@ -68,17 +68,17 @@ Product Object ✓ Full :class:`cybox.obje Semaphore Object ✓ Full :class:`cybox.objects.semaphore_object.Semaphore` SMS Message Object ✓ Full :class:`cybox.objects.sms_message_object.SMSMessage` Socket Address Object ✓ Full :class:`cybox.objects.socket_address_object.SocketAddress` -System Object ⚠ Partial :class:`cybox.objects.system_object.System` +System Object ✓ Full :class:`cybox.objects.system_object.System` URI Object ✓ Full :class:`cybox.objects.uri_object.URI` -URL History Object × None -Unix File Object × None -Unix Network Route Entry Object × None -Unix Pipe Object × None -Unix Process Object × None -Unix User Account Object × None -Unix Volume Object × None +URL History Object ✓ Full :class:`cybox.objects.url_history.URLHistory` +Unix File Object ✓ Full :class:`cybox.objects.unix_file_object.UnixFile` +Unix Network Route Entry Object ✓ Full :class:`cybox.objects.unix_network_route_entry_object.UnixNetworkRouteEntry` +Unix Pipe Object ✓ Full :class:`cybox.objects.unix_pipe_object.UnixPipe` +Unix Process Object ✓ Full :class:`cybox.objects.unix_process_object.UnixProcess` +Unix User Account Object ✓ Full :class:`cybox.objects.unix_user_account_object.UnixUserAccount` +Unix Volume Object ✓ Full :class:`cybox.objects.unix_volume_object.UnixVolume` User Account Object ✓ Full :class:`cybox.objects.user_account_object.UserAccount` -User Session Object × None +User Session Object ✓ Full :class:`cybox.objects.user_session_object.UserSession` Volume Object ✓ Full :class:`cybox.objects.volume_object.Volume` Whois Object ✓ Full :class:`cybox.objects.whois_object.WhoisEntry` Win Computer Account Object ✓ Full :class:`cybox.objects.win_computer_account_object.WinComputerAccount` @@ -108,7 +108,7 @@ Win System Object ✓ Full :class:`cybox.obje Win System Restore Object ✓ Full :class:`cybox.objects.win_system_restore_object.WinSystemRestore` Win Task Object ✓ Full :class:`cybox.objects.win_task_object.WinTask` Win Thread Object ✓ Full :class:`cybox.objects.win_thread_object.WinThread` -Win User Account Object ✓ Full :class:`cybox.objects.win_user_object.WinUser` +Win User Account Object ✓ Full :class:`cybox.objects.win_user_account_object.WinUser` Win Volume Object ✓ Full :class:`cybox.objects.win_volume_object.WinVolume` Win Waitable Timer Object ✓ Full :class:`cybox.objects.win_waitable_timer_object.WinWaitableTimer` X509 Certificate Object ✓ Full :class:`cybox.objects.x509_certificate_object.X509Certificate` @@ -133,7 +133,7 @@ HashNameVocab-1.0 ✓ Full InformationSourceTypeVocab-1.0 ✓ Full :class:`cybox.common.vocabs.InformationSourceType` ObjectRelationshipVocab-1.0 × None *(replaced by version 1.1)* ObjectRelationshipVocab-1.1 ✓ Full :class:`cybox.common.vocabs.ObjectRelationship` -ObjectStateVocab-1.0 × None +ObjectStateVocab-1.0 ✓ Full :class:`cybox.common.vocabs.ObjectState` ToolTypeVocab-1.0 × None *(replaced by version 1.1)* ToolTypeVocab-1.1 ✓ Full :class:`cybox.common.vocabs.ToolType` ========================================= ======================================== =========================================================== diff --git a/docs/api/cybox/common/build.rst b/docs/api/cybox/common/build.rst new file mode 100644 index 00000000..de6be926 --- /dev/null +++ b/docs/api/cybox/common/build.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.build` module +================================ + +.. automodule:: cybox.common.build + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/cipher.rst b/docs/api/cybox/common/cipher.rst new file mode 100644 index 00000000..7a17a1fb --- /dev/null +++ b/docs/api/cybox/common/cipher.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.cipher` module +================================= + +.. automodule:: cybox.common.cipher + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/compensation_model.rst b/docs/api/cybox/common/compensation_model.rst new file mode 100644 index 00000000..5d9cbe65 --- /dev/null +++ b/docs/api/cybox/common/compensation_model.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.compensation_model` module +============================================= + +.. automodule:: cybox.common.compensation_model + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/compilers.rst b/docs/api/cybox/common/compilers.rst new file mode 100644 index 00000000..04993f65 --- /dev/null +++ b/docs/api/cybox/common/compilers.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.compilers` module +==================================== + +.. automodule:: cybox.common.compilers + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/configuration_settings.rst b/docs/api/cybox/common/configuration_settings.rst new file mode 100644 index 00000000..befe4e33 --- /dev/null +++ b/docs/api/cybox/common/configuration_settings.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.configuration_settings` module +================================================= + +.. automodule:: cybox.common.configuration_settings + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/dependencies.rst b/docs/api/cybox/common/dependencies.rst new file mode 100644 index 00000000..1d327cdd --- /dev/null +++ b/docs/api/cybox/common/dependencies.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.dependencies` module +======================================= + +.. automodule:: cybox.common.dependencies + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/errors.rst b/docs/api/cybox/common/errors.rst new file mode 100644 index 00000000..770cbff6 --- /dev/null +++ b/docs/api/cybox/common/errors.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.errors` module +================================= + +.. automodule:: cybox.common.errors + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/execution_environment.rst b/docs/api/cybox/common/execution_environment.rst new file mode 100644 index 00000000..254cab30 --- /dev/null +++ b/docs/api/cybox/common/execution_environment.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.execution_environment` module +================================================ + +.. automodule:: cybox.common.execution_environment + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/index.rst b/docs/api/cybox/common/index.rst index 42b99e61..dfaa19ef 100644 --- a/docs/api/cybox/common/index.rst +++ b/docs/api/cybox/common/index.rst @@ -11,16 +11,27 @@ Submodules .. toctree:: attribute_groups + build byterun + cipher + compensation_model + compilers + configuration_settings contributor data_segment daterange datetimewithprecision + dependencies digitalsignature environment_variable + errors + execution_environment extracted_features extracted_string hashes + internationalization_settings + libraries + location measuresource object_properties platform_specification @@ -28,4 +39,5 @@ Submodules structured_text time tools + usage_context vocabs diff --git a/docs/api/cybox/common/internationalization_settings.rst b/docs/api/cybox/common/internationalization_settings.rst new file mode 100644 index 00000000..803168e3 --- /dev/null +++ b/docs/api/cybox/common/internationalization_settings.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.internationalization_settings` module +======================================================== + +.. automodule:: cybox.common.internationalization_settings + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/libraries.rst b/docs/api/cybox/common/libraries.rst new file mode 100644 index 00000000..71ae454f --- /dev/null +++ b/docs/api/cybox/common/libraries.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.libraries` module +==================================== + +.. automodule:: cybox.common.libraries + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/location.rst b/docs/api/cybox/common/location.rst new file mode 100644 index 00000000..8e50462c --- /dev/null +++ b/docs/api/cybox/common/location.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.location` module +=================================== + +.. automodule:: cybox.common.location + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/common/usage_context.rst b/docs/api/cybox/common/usage_context.rst new file mode 100644 index 00000000..33d62998 --- /dev/null +++ b/docs/api/cybox/common/usage_context.rst @@ -0,0 +1,7 @@ +:mod:`cybox.common.usage_context` module +======================================== + +.. automodule:: cybox.common.usage_context + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/core/index.rst b/docs/api/cybox/core/index.rst index dc3ac2ad..56060930 100644 --- a/docs/api/cybox/core/index.rst +++ b/docs/api/cybox/core/index.rst @@ -18,3 +18,5 @@ Submodules frequency object observable + pattern_fidelity + pool diff --git a/docs/api/cybox/core/pattern_fidelity.rst b/docs/api/cybox/core/pattern_fidelity.rst new file mode 100644 index 00000000..c7f30c62 --- /dev/null +++ b/docs/api/cybox/core/pattern_fidelity.rst @@ -0,0 +1,7 @@ +:mod:`cybox.core.pattern_fidelity` module +========================================= + +.. automodule:: cybox.core.pattern_fidelity + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/core/pool.rst b/docs/api/cybox/core/pool.rst new file mode 100644 index 00000000..3723f8e3 --- /dev/null +++ b/docs/api/cybox/core/pool.rst @@ -0,0 +1,7 @@ +:mod:`cybox.core.pool` module +============================= + +.. automodule:: cybox.core.pool + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/custom_object.rst b/docs/api/cybox/objects/custom_object.rst new file mode 100644 index 00000000..0b57a99c --- /dev/null +++ b/docs/api/cybox/objects/custom_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.custom_object` module +========================================= + +.. automodule:: cybox.objects.custom_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/index.rst b/docs/api/cybox/objects/index.rst index d394552d..6bbbd70d 100644 --- a/docs/api/cybox/objects/index.rst +++ b/docs/api/cybox/objects/index.rst @@ -14,6 +14,7 @@ Submodules as_object arp_object code_object + custom_object device_object disk_object disk_partition_object @@ -35,6 +36,7 @@ Submodules memory_object mutex_object network_connection_object + network_flow_object network_packet_object network_route_entry_object network_route_object @@ -49,8 +51,16 @@ Submodules socket_address_object sms_message_object system_object + unix_file_object + unix_network_route_entry_object + unix_pipe_object + unix_process_object + unix_user_account_object + unix_volume_object uri_object + url_history_object user_account_object + user_session_object volume_object whois_object win_computer_account_object @@ -80,7 +90,7 @@ Submodules win_system_restore_object win_task_object win_thread_object - win_user_object + win_user_account_object win_volume_object win_waitable_timer_object x509_certificate_object diff --git a/docs/api/cybox/objects/network_flow_object.rst b/docs/api/cybox/objects/network_flow_object.rst new file mode 100644 index 00000000..a0d4ed09 --- /dev/null +++ b/docs/api/cybox/objects/network_flow_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.network_flow_object` module +=============================================== + +.. automodule:: cybox.objects.network_flow_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/unix_file_object.rst b/docs/api/cybox/objects/unix_file_object.rst new file mode 100644 index 00000000..6ad426f5 --- /dev/null +++ b/docs/api/cybox/objects/unix_file_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.unix_file_object` module +============================================ + +.. automodule:: cybox.objects.unix_file_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/unix_network_route_entry_object.rst b/docs/api/cybox/objects/unix_network_route_entry_object.rst new file mode 100644 index 00000000..850a5c3d --- /dev/null +++ b/docs/api/cybox/objects/unix_network_route_entry_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.unix_network_route_entry_object` module +=========================================================== + +.. automodule:: cybox.objects.unix_network_route_entry_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/unix_pipe_object.rst b/docs/api/cybox/objects/unix_pipe_object.rst new file mode 100644 index 00000000..1e9fa0dd --- /dev/null +++ b/docs/api/cybox/objects/unix_pipe_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.unix_pipe_object` module +============================================ + +.. automodule:: cybox.objects.unix_pipe_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/unix_process_object.rst b/docs/api/cybox/objects/unix_process_object.rst new file mode 100644 index 00000000..e05e3a8c --- /dev/null +++ b/docs/api/cybox/objects/unix_process_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.unix_process_object` module +=============================================== + +.. automodule:: cybox.objects.unix_process_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/unix_user_account_object.rst b/docs/api/cybox/objects/unix_user_account_object.rst new file mode 100644 index 00000000..4f11ff7e --- /dev/null +++ b/docs/api/cybox/objects/unix_user_account_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.unix_user_account_object` module +==================================================== + +.. automodule:: cybox.objects.unix_user_account_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/unix_volume_object.rst b/docs/api/cybox/objects/unix_volume_object.rst new file mode 100644 index 00000000..e52ccc15 --- /dev/null +++ b/docs/api/cybox/objects/unix_volume_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.unix_volume_object` module +============================================== + +.. automodule:: cybox.objects.unix_volume_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/url_history_object.rst b/docs/api/cybox/objects/url_history_object.rst new file mode 100644 index 00000000..411ffd70 --- /dev/null +++ b/docs/api/cybox/objects/url_history_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.url_history_object` module +============================================== + +.. automodule:: cybox.objects.url_history_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/user_session_object.rst b/docs/api/cybox/objects/user_session_object.rst new file mode 100644 index 00000000..5fdd2b41 --- /dev/null +++ b/docs/api/cybox/objects/user_session_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.user_session_object` module +=============================================== + +.. automodule:: cybox.objects.user_session_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/win_user_account_object.rst b/docs/api/cybox/objects/win_user_account_object.rst new file mode 100644 index 00000000..41bdc5a1 --- /dev/null +++ b/docs/api/cybox/objects/win_user_account_object.rst @@ -0,0 +1,7 @@ +:mod:`cybox.objects.win_user_account_object` module +=================================================== + +.. automodule:: cybox.objects.win_user_account_object + :members: + :undoc-members: + :show-inheritance: diff --git a/docs/api/cybox/objects/win_user_object.rst b/docs/api/cybox/objects/win_user_object.rst deleted file mode 100644 index 3a454575..00000000 --- a/docs/api/cybox/objects/win_user_object.rst +++ /dev/null @@ -1,7 +0,0 @@ -:mod:`cybox.objects.win_user_object` module -=========================================== - -.. automodule:: cybox.objects.win_user_object - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/examples.rst b/docs/examples.rst index 7cd05f47..aa173d09 100644 --- a/docs/examples.rst +++ b/docs/examples.rst @@ -359,7 +359,7 @@ these can be constructed from a dictionary representation. .. testcode:: - from cybox.objects.win_user_object import WinUser + from cybox.objects.win_user_account_object import WinUser winuser_dict = { # Account-specific fields 'disabled': False, diff --git a/tox.ini b/tox.ini index d9e31881..bdbc01b2 100644 --- a/tox.ini +++ b/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py27, py34, py35, py36, py37, docs, packaging +envlist = py27, py34, py35, py36, py37, py38, docs, packaging [testenv] commands = @@ -24,3 +24,4 @@ python = 3.5: py35 3.6: py36, packaging 3.7: py37 + 3.8: py38