示例#1
0
    def test_equal(self):
        # Tuple equality is provided for free by namedtuple. Every element must
        # be equal for the Namespaces to be seen as equal
        ns1 = Namespace("http://example.com/", "example", "")
        ns2 = Namespace("http://example.com/", "example", "")
        ns3 = Namespace("http://example.com", "example", "")

        self.assertEqual(ns1, ns2)
        self.assertNotEqual(ns1, ns3)
示例#2
0
def merge_packages(package_list, namespace=None):
    '''Merge a list of input MAEC Packages and return a merged Package instance.'''
    malware_subjects = []
    # Instantiate the ID generator class (for automatic ID generation)
    if not namespace:
        NS = Namespace("https://github.com/MAECProject/python-maec", "merged")
    else:
        NS = namespace
    maec.utils.set_id_namespace(NS)
    # Build the list of Malware Subjects
    for package in package_list:
        for malware_subject in package.malware_subjects:
            malware_subjects.append(malware_subject)
    # Merge the Malware Subjects
    merged_subjects = merge_malware_subjects(malware_subjects)
    # Merge the input namespace/schemaLocation dictionaries
    merged_namespaces = {}
    merged_schemalocations = {}
    for package in package_list:
        merged_namespaces.update(package.__input_namespaces__)
        merged_schemalocations.update(package.__input_schemalocations__)
    # Create a new Package with the merged Malware Subjects
    merged_package = Package()
    merged_package.malware_subjects = MalwareSubjectList(merged_subjects)
    merged_package.__input_namespaces__ = merged_namespaces
    merged_package.__input_schemalocations__ = merged_schemalocations
    return merged_package
示例#3
0
def capecbuild(capecid):
    """Build a STIX package based on a CAPEC ID."""
    data = _get_attack(capecid)
    if data:
        try:
            from stix.utils import set_id_namespace
            namespace = {NS: NS_PREFIX}
            set_id_namespace(namespace)
        except ImportError:
            from mixbox.idgen import set_id_namespace
            from mixbox.namespaces import Namespace
            namespace = Namespace(NS, NS_PREFIX, "")
            set_id_namespace(namespace)

        pkg = STIXPackage()
        pkg.stix_header = STIXHeader()
        pkg = STIXPackage()
        pkg.stix_header = STIXHeader()
        pkg.stix_header.handling = _marking()

        ttp = _buildttp(data)

        if data['related_attacks']:
            ttp.related_ttps.append(
                _buildttp(_get_attack(str(data['related_attacks'][0]))))
        pkg.add_ttp(ttp)
        xml = pkg.to_xml()
        title = pkg.id_.split(':', 1)[-1]
        if __name__ == '__main__':
            _postconstruct(xml, title)
    return xml
示例#4
0
    def test_set_semantics(self):
        nsset = NamespaceSet()
        self.assertEqual(0, len(nsset))

        ns1 = Namespace("http://example.com/", "example", "")
        nsset.add(ns1)
        self.assertEqual(1, len(nsset))

        # Adding the same namespace doesn't have an effect
        nsset.add(ns1)
        self.assertEqual(1, len(nsset))

        # Neither does adding a new namespace object that is "equal" to the
        # first.
        nsset.add(Namespace("http://example.com/", "example", ""))
        self.assertEqual(1, len(nsset))
示例#5
0
    def test_schema_locations(self):
        ns = NamespaceSet()
        ns.add_namespace_uri("a:b:c", "abc", "sc:he:ma")

        self.assertEqual(ns.get_schema_location("a:b:c"), "sc:he:ma")

        self.assertRaises(mixbox.namespaces.ConflictingSchemaLocationError,
                          ns.set_schema_location, "a:b:c", "other:schemaloc")
        self.assertRaises(mixbox.namespaces.ConflictingSchemaLocationError,
                          ns.add_namespace,
                          Namespace("a:b:c", "abc", "other:schemaloc"))
        self.assertRaises(mixbox.namespaces.ConflictingSchemaLocationError,
                          ns.add_namespace_uri, "a:b:c", "abc",
                          "other:schemaloc")
        self.assertRaises(mixbox.namespaces.NamespaceNotFoundError,
                          ns.set_schema_location, "does:not:exist", "sc:he:ma")
        self.assertRaises(mixbox.namespaces.NamespaceNotFoundError,
                          ns.get_schema_location, "does:not:exist")

        ns.set_schema_location("a:b:c", "sc:he:ma2", True)
        self.assertEqual(ns.get_schema_location("a:b:c"), "sc:he:ma2")

        # test schema location merging; these should not raise exceptions
        ns.add_namespace_uri("a:b:c", "abc", None)
        self.assertEqual(ns.get_schema_location("a:b:c"), "sc:he:ma2")

        ns.add_namespace_uri("d:e:f", "def", None)
        ns.add_namespace_uri("d:e:f", "def", "def:schema")
        self.assertEqual(ns.get_schema_location("d:e:f"), "def:schema")

        self.assertTrue(ns.is_valid())
示例#6
0
def main():
    mydata = loaddata()
    '''
    Your Namespace
    '''
    #    NAMESPACE = {sanitizer(mydata["NSXURL"]) : (mydata["NS"])}
    #    set_id_namespace(NAMESPACE)
    NAMESPACE = Namespace(sanitizer(mydata['NSXURL']), sanitizer(mydata['NS']))
    set_id_namespace(NAMESPACE)  # new ids will be prefixed by "myNS"

    wrapper = STIXPackage()
    info_src = InformationSource()
    info_src.identity = Identity(name=sanitizer(mydata["Identity"]))

    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = sanitizer(mydata["TLP_COLOR"])
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)

    timestamp = datetime.datetime.fromtimestamp(
        time.time()).strftime('%Y-%m-%d %H:%M:%S')
    MyTITLE = sanitizer(mydata["Title"])
    SHORT = timestamp

    DESCRIPTION = sanitizer(mydata["Description"])

    wrapper.stix_header = STIXHeader(information_source=info_src,
                                     title=MyTITLE,
                                     description=DESCRIPTION,
                                     short_description=SHORT)
    wrapper.stix_header.handling = handling

    indiDom = Indicator()
    indiDom.title = MyTITLE
    indiDom.add_indicator_type("IP Watchlist")

    for key in mydata["IOC"].keys():
        myip = Address(address_value=sanitizer(key), category=Address.CAT_IPV4)
        myip.condition = "Equals"

        obsu = Observable(myip)

        #if mydata[key].size:
        for idx, mydata["IOC"][key] in enumerate(mydata["IOC"][key]):
            ioc = File()
            ioc.add_hash(sanitizer(mydata["IOC"][key]))

            myip.add_related(ioc, "Downloaded")

        indiDom.add_observable(obsu)

    wrapper.add_indicator(indiDom)

    print(wrapper.to_xml())
示例#7
0
def cvebuild(var):
    """Search for a CVE ID and return a STIX formatted response."""
    cve = CVESearch()
    data = json.loads(cve.id(var))
    if data:
        try:
            from stix.utils import set_id_namespace
            namespace = {NS: NS_PREFIX}
            set_id_namespace(namespace)
        except ImportError:
            from stix.utils import idgen
            from mixbox.namespaces import Namespace
            namespace = Namespace(NS, NS_PREFIX, "")
            idgen.set_id_namespace(namespace)

        pkg = STIXPackage()
        pkg.stix_header = STIXHeader()
        pkg = STIXPackage()
        pkg.stix_header = STIXHeader()

        pkg.stix_header.handling = marking()

        # Define the exploit target
        expt = ExploitTarget()
        expt.title = data['id']
        expt.description = data['summary']

        # Add the vulnerability object to the package object
        expt.add_vulnerability(vulnbuild(data))

        # Do some TTP stuff with CAPEC objects
        try:
            for i in data['capec']:
                ttp = TTP()
                ttp.title = "CAPEC-" + str(i['id'])
                ttp.description = i['summary']
                ttp.exploit_targets.append(ExploitTarget(idref=expt.id_))
                pkg.add_ttp(ttp)
        except KeyError:
            pass

        # Do some weakness stuff
        if data['cwe'] != 'Unknown':
            weak = Weakness()
            weak.cwe_id = data['cwe']
            expt.add_weakness(weak)

        # Add the exploit target to the package object
        pkg.add_exploit_target(expt)

        xml = pkg.to_xml()

        # If the function is not imported then output the xml to a file.
        if __name__ == '__main__':
            title = pkg.id_.split(':', 1)[-1]
            with open(title + ".xml", "w") as text_file:
                text_file.write(xml)
        return xml
示例#8
0
def cvebuild(var):
    """Search for a CVE ID and return a STIX formatted response."""
    cve = CVESearch()
    data = json.loads(cve.id(var))
    if data:
        try:
            from stix.utils import set_id_namespace
            namespace = {NS: NS_PREFIX}
            set_id_namespace(namespace)
        except ImportError:
            from mixbox.idgen import set_id_namespace
            from mixbox.namespaces import Namespace
            namespace = Namespace(NS, NS_PREFIX, "")
            set_id_namespace(namespace)

        pkg = STIXPackage()
        pkg.stix_header = STIXHeader()
        pkg = STIXPackage()
        pkg.stix_header = STIXHeader()

        pkg.stix_header.handling = _marking()

        # Define the exploit target
        expt = ExploitTarget()
        expt.title = data['id']
        expt.description = data['summary']
        expt.information_source = InformationSource(identity=Identity(
            name="National Vulnerability Database"))

        # Add the vulnerability object to the package object
        expt.add_vulnerability(_vulnbuild(data))

        # Add the COA object to the ET object
        for coa in COAS:
            expt.potential_coas.append(
                CourseOfAction(idref=coa['id'], timestamp=expt.timestamp))

        # Do some TTP stuff with CAPEC objects
        if TTPON is True:
            try:
                for i in data['capec']:
                    pkg.add_ttp(_buildttp(i, expt))
            except KeyError:
                pass

        expt.add_weakness(_weakbuild(data))

        # Add the exploit target to the package object
        pkg.add_exploit_target(expt)

        xml = pkg.to_xml()
        title = pkg.id_.split(':', 1)[-1]
        # If the function is not imported then output the xml to a file.
        if __name__ == '__main__':
            _postconstruct(xml, title)
        return xml
    else:
        sys.exit("[-] Error retrieving details for " + var)
示例#9
0
 def __init__(self):
     # namespace dictionary
     self.ns_dict = {
         SNSConfig.get_stix_ns_url(): SNSConfig.get_stix_ns_name(),
     }
     ns_ctim_sns = Namespace(SNSConfig.get_stix_ns_url(), SNSConfig.get_stix_ns_name(), schema_location=None)
     # id generator
     idgen.set_id_namespace(ns_ctim_sns)
     self.generator = idgen._get_generator()
def _custom_namespace(url, alias):
    try:
        from stix.utils import set_id_namespace
        namespace = {url: alias}
        set_id_namespace(namespace)
    except ImportError:
        from mixbox.namespaces import Namespace
        from stix.utils import idgen
        namespace = Namespace(url, alias, "")
        idgen.set_id_namespace(namespace)
示例#11
0
    def test_namedtuple(self):
        # Verify behavior of the namedtuple (mainly, that you can access
        # attributes but not modify them.
        ns = Namespace("http://example.com/", "example", "")
        self.assertEqual("http://example.com/", ns.name)
        self.assertEqual("example", ns.prefix)
        self.assertEqual("", ns.schema_location)

        self.assertRaises(AttributeError, setattr, ns, 'name', "urn:example")
        self.assertRaises(AttributeError, setattr, ns, 'prefix', "example")
        self.assertRaises(AttributeError, setattr, ns, 'schema_location', "")
示例#12
0
    def __init__(
        self,
        identity_name=DEFAULT_IDENTITY_NAME,
        ns_url=DEFAULT_NS_URL,
        ns_name=DEFAULT_NS_NAME,
    ):
        self.identity_name = identity_name
        self.events = []

        ns_ctim_sns = Namespace(ns_url, ns_name, schema_location=None)
        idgen.set_id_namespace(ns_ctim_sns)
        self.generator = idgen._get_generator()
示例#13
0
    def test_set_semantics(self):
        nsset = NamespaceSet()
        self.assertEqual(0, len(nsset))

        ns1 = Namespace("http://example.com/", "example", "")
        nsset.add_namespace(ns1)
        self.assertEqual(1, len(nsset))

        # Adding the same namespace doesn't have an effect
        nsset.add_namespace(ns1)
        self.assertEqual(1, len(nsset))

        # Neither does adding a new namespace object that is "equal" to the
        # first.
        nsset.add_namespace(Namespace("http://example.com/", "example", ""))
        self.assertEqual(1, len(nsset))

        # Adding a prefix doesn't change the set size
        nsset.add_namespace_uri("http://example.com/", "example2")
        self.assertEqual(1, len(nsset))

        self.assertTrue(nsset.contains_namespace("http://example.com/"))

        self.assertTrue(nsset.is_valid())
示例#14
0
 def __init__(self, config, dom):
     self.protocol_to_port_mapping = dict(
         modbus=502,
         snmp=161,
         http=80,
         s7comm=102,
     )
     port_path_list = map(lambda x: '//conpot_template/protocols/'+x+'/@port', self.protocol_to_port_mapping.keys())
     for port_path in port_path_list:
         try:
             protocol_port = ast.literal_eval(dom.xpath(port_path)[0])
             protocol_name = port_path.rsplit("/", 2)[1]
             self.protocol_to_port_mapping[protocol_name] = protocol_port
         except IndexError:
             continue
     conpot_namespace = Namespace(CONPOT_NAMESPACE_URL, CONPOT_NAMESPACE, '')
     idgen.set_id_namespace(conpot_namespace)
示例#15
0
    def test_prefixes(self):
        ns = NamespaceSet()
        ns.add_namespace_uri("a:b:c", "pfx")
        ns.add_namespace_uri("a:b:c", "pfx2")
        ns.add_prefix("a:b:c", "pfx3")
        self.assertEqual(len(ns.get_prefixes("a:b:c")), 3)
        self.assertTrue(ns.is_valid())

        ns.remove_prefix("pfx3")
        self.assertEqual(len(ns.get_prefixes("a:b:c")), 2)
        self.assertTrue(ns.is_valid())

        # Make sure prefix_iter() gives the same prefixes as get_prefixes().
        self.assertEqual(len(ns.get_prefixes("a:b:c")),
                         len(list(ns.prefix_iter("a:b:c"))))
        #self.assertTrue(all(map(operator.eq, ns.get_prefixes("a:b:c"),
        #                        ns.prefix_iter("a:b:c"))))
        # One time, I saw the above test code fail.  I never saw it again.
        # Seems like the prefixes may have come out in a different order or
        # something... guess I'll play it safe and copy them to sorted
        # lists before comparing.
        pfxs1 = sorted(ns.get_prefixes("a:b:c"))
        pfxs2 = sorted(ns.prefix_iter("a:b:c"))
        self.assertTrue(all(map(operator.eq, pfxs1, pfxs2)))

        self.assertEqual(ns.namespace_for_prefix("pfx"), "a:b:c")
        self.assertEqual(ns.namespace_for_prefix("pfx2"), "a:b:c")

        # Should get an exception if we try to map the same prefix to a
        # different namespace.
        self.assertRaises(mixbox.namespaces.DuplicatePrefixError,
                          ns.add_namespace_uri, "x:y:z", "pfx")
        self.assertRaises(mixbox.namespaces.DuplicatePrefixError,
                          ns.add_namespace, Namespace("x:y:z", "pfx", None))

        self.assertRaises(mixbox.namespaces.NamespaceNotFoundError,
                          ns.get_prefixes, "does:not:exist")
        self.assertRaises(mixbox.namespaces.NamespaceNotFoundError,
                          ns.prefix_iter, "does:not:exist")
        self.assertRaises(mixbox.namespaces.NamespaceNotFoundError,
                          ns.add_prefix, "does:not:exist", "dne")

        ns.remove_prefix("does:not:exist")

        self.assertTrue(ns.is_valid())
iocs = {
    'title': stixTitle,
    'desc': stixDescription,
    'hash': file_hashes,
    'fname': filenames,
    'ips': ip_addresses,
    'urls': urls,
    'subject': email_subjects,
    'senders': email_sender,
    'domains': domain
}

# disable warning 'The use of this field has been deprecated' - STIXHeader()
warnings.filterwarnings("ignore")

NAMESPACE = Namespace("http://bimb.com/stix", "bimb")
set_id_namespace(NAMESPACE)


def main(iocs=iocs):

    stix_header = STIXHeader(title=iocs['title'],
                             description=iocs['desc'],
                             package_intents=["Indicators - Watchlist"])

    stix_package = STIXPackage(stix_header=stix_header)

    # add indicator - file hash
    if iocs.get('hash'):
        indicator_file_hash = Indicator(title="Malicious File")
        indicator_file_hash.add_indicator_type("File Hash Watchlist")
示例#17
0
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from mixbox.namespaces import Namespace, NamespaceSet, register_namespace

NS_CYBOX_CORE = Namespace('http://cybox.mitre.org/cybox-2', 'cybox', 'http://cybox.mitre.org/XMLSchema/core/2.1/cybox_core.xsd')
NS_CYBOX_COMMON = Namespace('http://cybox.mitre.org/common-2', 'cyboxCommon', 'http://cybox.mitre.org/XMLSchema/common/2.1/cybox_common.xsd')
NS_CYBOX_VOCABS = Namespace('http://cybox.mitre.org/default_vocabularies-2', 'cyboxVocabs', 'http://cybox.mitre.org/XMLSchema/default_vocabularies/2.1/cybox_default_vocabularies.xsd')
NS_ACCOUNT_OBJECT = Namespace('http://cybox.mitre.org/objects#AccountObject-2', 'AccountObj', 'http://cybox.mitre.org/XMLSchema/objects/Account/2.1/Account_Object.xsd')
NS_ADDRESS_OBJECT = Namespace('http://cybox.mitre.org/objects#AddressObject-2', 'AddressObj', 'http://cybox.mitre.org/XMLSchema/objects/Address/2.1/Address_Object.xsd')
NS_API_OBJECT = Namespace('http://cybox.mitre.org/objects#APIObject-2', 'APIObj', 'http://cybox.mitre.org/XMLSchema/objects/API/2.1/API_Object.xsd')
NS_ARCHIVEFILE_OBJECT = Namespace('http://cybox.mitre.org/objects#ArchiveFileObject-1', 'ArchiveFileObj', 'http://cybox.mitre.org/XMLSchema/objects/Archive_File/1.0/Archive_File_Object.xsd')
NS_ARPCACHE_OBJECT = Namespace('http://cybox.mitre.org/objects#ARPCacheObject-1', 'ARPCacheObj', 'http://cybox.mitre.org/XMLSchema/objects/ARP_Cache/1.0/ARP_Cache_Object.xsd')
NS_ARTIFACT_OBJECT = Namespace('http://cybox.mitre.org/objects#ArtifactObject-2', 'ArtifactObj', 'http://cybox.mitre.org/XMLSchema/objects/Artifact/2.1/Artifact_Object.xsd')
NS_AS_OBJECT = Namespace('http://cybox.mitre.org/objects#ASObject-1', 'ASObj', 'http://cybox.mitre.org/XMLSchema/objects/AS/1.0/AS_Object.xsd')
NS_CODE_OBJECT = Namespace('http://cybox.mitre.org/objects#CodeObject-2', 'CodeObj', 'http://cybox.mitre.org/XMLSchema/objects/Code/2.1/Code_Object.xsd')
NS_CUSTOM_OBJECT = Namespace('http://cybox.mitre.org/objects#CustomObject-1', 'CustomObj', 'http://cybox.mitre.org/XMLSchema/objects/Custom/1.1/Custom_Object.xsd')
NS_DEVICE_OBJECT = Namespace('http://cybox.mitre.org/objects#DeviceObject-2', 'DeviceObj', 'http://cybox.mitre.org/XMLSchema/objects/Device/2.1/Device_Object.xsd')
NS_DISK_OBJECT = Namespace('http://cybox.mitre.org/objects#DiskObject-2', 'DiskObj', 'http://cybox.mitre.org/XMLSchema/objects/Disk/2.1/Disk_Object.xsd')
NS_DISKPARTITION_OBJECT = Namespace('http://cybox.mitre.org/objects#DiskPartitionObject-2', 'DiskPartitionObj', 'http://cybox.mitre.org/XMLSchema/objects/Disk_Partition/2.1/Disk_Partition_Object.xsd')
NS_DNSCACHE_OBJECT = Namespace('http://cybox.mitre.org/objects#DNSCacheObject-2', 'DNSCacheObj', 'http://cybox.mitre.org/XMLSchema/objects/DNS_Cache/2.1/DNS_Cache_Object.xsd')
NS_DNSQUERY_OBJECT = Namespace('http://cybox.mitre.org/objects#DNSQueryObject-2', 'DNSQueryObj', 'http://cybox.mitre.org/XMLSchema/objects/DNS_Query/2.1/DNS_Query_Object.xsd')
NS_DNSRECORD_OBJECT = Namespace('http://cybox.mitre.org/objects#DNSRecordObject-2', 'DNSRecordObj', 'http://cybox.mitre.org/XMLSchema/objects/DNS_Record/2.1/DNS_Record_Object.xsd')
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_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')
NS_HTTPSESSION_OBJECT = Namespace('http://cybox.mitre.org/objects#HTTPSessionObject-2', 'HTTPSessionObj', 'http://cybox.mitre.org/XMLSchema/objects/HTTP_Session/2.1/HTTP_Session_Object.xsd')
示例#18
0
def main():

    ######################################################################
    # MODIFICARE LE VARIABILI SEGUENTI

    # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28)
    MyTITLE = "GandCrab"

    # La description strutturiamola come segue
    # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)>
    DESCRIPTION = "CERT-PA - Nuova campagna di Cyber-Estorsione basata su ransomware GandCrab - https://www.cert-pa.it/notizie/nuova-campagna-di-cyber-estorsione-basata-su-ransomware-gandcrab/"

    # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community 
    IDENTITY = "CERT-PA via Cyber Saiyan Community"
    #
    ######################################################################

    # Build STIX file
    info_src = InformationSource()
    info_src.identity = Identity(name=IDENTITY)

    NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN")
    set_id_namespace(NAMESPACE)

    timestamp = datetime.datetime.fromtimestamp(time.time()).strftime('%Y-%m-%d %H:%M:%S')
    SHORT = timestamp

    wrapper = STIXPackage()
    
    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)
    
    handling = Marking()
    handling.add_marking(marking_specification)
    
    wrapper.stix_header = STIXHeader(information_source=info_src, title=MyTITLE.encode(encoding='UTF-8', errors='replace'), description=DESCRIPTION.encode(encoding='UTF-8', errors='replace'), short_description=SHORT.encode(encoding='UTF-8', errors='replace'))
    wrapper.stix_header.handling = handling
    
    # HASH indicators
    indicatorHASH = Indicator()
    indicatorHASH.title = MyTITLE + " - HASH"
    indicatorHASH.add_indicator_type("File Hash Watchlist")
    
    # DOMAIN indicators
    indiDOMAIN = Indicator()
    indiDOMAIN.title = MyTITLE + " - DOMAIN"
    indiDOMAIN.add_indicator_type("Domain Watchlist")

    # URL indicators
    indiURL = Indicator()
    indiURL.title = MyTITLE + " - URL"
    indiURL.add_indicator_type("URL Watchlist")

    # IP indicators
    indiIP = Indicator()
    indiIP.title = MyTITLE + " - IP"
    indiIP.add_indicator_type("IP Watchlist")

    # EMAIL indicators
    indiEMAIL = Indicator()
    indiEMAIL.title = MyTITLE + " - EMAIL"
    indiEMAIL.add_indicator_type("Malicious E-mail")

    # Read IoC file
    file_ioc = "CS-ioc.txt"
    ioc = loaddata(file_ioc)

    print "Reading IoC file..."
    for idx, ioc in enumerate(ioc):
        notfound = 1
        
        # sha256
        p = re.compile(r"^[0-9a-f]{64}$", re.IGNORECASE)
        m = p.match(ioc)
        if m and notfound:
            filei = File()
            filei.add_hash(Hash(ioc))
        
            obsi = Observable(filei)
            indicatorHASH.add_observable(obsi)
            print "SHA256: " + ioc
            notfound = 0

        #md5
        p = re.compile(r"^[0-9a-f]{32}$", re.IGNORECASE)
        m = p.match(ioc)
        if m and notfound:
            filej = File()
            filej.add_hash(Hash(ioc))
        
            obsj = Observable(filej)
            indicatorHASH.add_observable(obsj)
            print "MD5: " + ioc
            notfound = 0

        #sha1
        p = re.compile(r"^[0-9a-f]{40}$", re.IGNORECASE)
        m = p.match(ioc)
        if m and notfound:
            filek = File()
            filek.add_hash(Hash(ioc))
        
            obsk = Observable(filek)
            indicatorHASH.add_observable(obsk)
            print "SHA1: " + ioc
            notfound = 0

        #domains
        if validators.domain(ioc) and notfound:
            url = URI()
            url.value = ioc
            url.type_ =  URI.TYPE_DOMAIN
            url.condition = "Equals"

            obsu = Observable(url)
            indiDOMAIN.add_observable(obsu)
            print "DOMAIN: " + ioc
            notfound = 0

        #url
        if validators.url(ioc) and notfound:
            url = URI()
            url.value = ioc
            url.type_ =  URI.TYPE_URL
            url.condition = "Equals"
            
            obsu = Observable(url)
            indiURL.add_observable(obsu)
            print "URL: " + ioc
            notfound = 0

        #ip
        if validators.ipv4(ioc) and notfound:
            ip = Address()
            ip.address_value = ioc
        
            obsu = Observable(ip)
            indiIP.add_observable(obsu)
            print "IP: " + ioc
            notfound = 0

    # add all indicators to STIX
    wrapper.add_indicator(indicatorHASH)
    wrapper.add_indicator(indiDOMAIN)
    wrapper.add_indicator(indiURL)
    wrapper.add_indicator(indiIP)
    wrapper.add_indicator(indiEMAIL)
   
    # print STIX file to stdout
    print "Writing STIX package: package.stix"
    f = open ("package.stix", "w")
    f.write (wrapper.to_xml())
    f.close ()
    print 
示例#19
0
    _XSI_TYPE = "AIS:AISMarkingStructure"

    is_proprietary = fields.TypedField("Is_Proprietary", IsProprietary)
    not_proprietary = fields.TypedField("Not_Proprietary", NotProprietary)

    def __init__(self, is_proprietary=None, not_proprietary=None):
        super(AISMarkingStructure, self).__init__()

        self.is_proprietary = is_proprietary
        self.not_proprietary = not_proprietary


NAMESPACES = [
    Namespace(
        'http://www.us-cert.gov/STIXMarkingStructure#AISConsentMarking-2',
        'AIS',
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/AIS_Bundle_Marking_1.1.1_v1.0.xsd'
    )
]


def _update_namespaces():
    # Update the python-stix namespace dictionary
    from stix.utils import nsparser
    import mixbox.namespaces

    nsparser.STIX_NAMESPACES.add_namespace(NAMESPACES[0])
    mixbox.namespaces.register_namespace(NAMESPACES[0])


_update_namespaces()
示例#20
0
from stix.core import STIXPackage
from mixbox.idgen import set_id_namespace
from mixbox.namespaces import Namespace
from stix.indicator import Indicator
from cybox.core import Observable
from cybox.objects.address_object import Address
from cybox.objects.file_object import File
from cybox.common import Hash
from cybox.objects.uri_object import URI
from cybox.objects.win_registry_key_object import WinRegistryKey

#from cybox.objects.domain_name_object import DomainName
OUTPUT_FORMATS = ('csv', 'json', 'yara', 'autofocus', 'stix')

#NAMESPACE = {"http://www.cert.gov.uk" : "certuk"}
NAMESPACE = Namespace("http://www.cert.gov.uk", "certuk")
set_id_namespace(NAMESPACE)

stix_package = STIXPackage()
add_ind_list = []

ind_ip = Indicator()
ind_ip.add_indicator_type("IP Watchlist")

ind_file = Indicator()
ind_file.add_indicator_type("File Hash Watchlist")

ind_url = Indicator()
ind_url.add_indicator_type("URL Watchlist")

ind_domain = Indicator()
示例#21
0
def load_stix(stix):
    # Just save the pain and load it if the first character is a <
    log.debug("Loading STIX...")
    if sys.version_info < (3, 5):
        json_exception = ValueError
    else:
        json_exception = json.JSONDecodeError

    if isinstance(stix, STIXPackage):
        log.debug("Argument was already STIX package, ignoring.")
        # Oh cool we're ok
        # Who tried to load this? Honestly.
        return stix

    elif hasattr(stix, 'read'):
        log.debug("Argument has 'read' attribute, assuming file-like.")

        # It's a file!
        # But somehow, sometimes, reading it returns a bytes stream
        # and the loader dies on python 3.4.
        # Luckily, STIXPackage.from_json (which is mixbox.Entity.from_json)
        # will happily load a string.
        # So we're going to play dirty.

        data = stix.read()
        log.debug("Read file, type %s.", type(data))

        if isinstance(data, bytes):
            data = data.decode()
        try:
            log.debug("Attempting to load from JSON...")
            # Try loading from JSON
            stix_package = STIXPackage.from_json(data)
        except json_exception:
            log.debug("Attempting to load from XML...")
            # Ok then try loading from XML
            # Loop zoop
            # Read the STIX into an Etree
            stix.seek(0)
            stix_xml = etree.fromstring(stix.read())

            ns_map = stix_xml.nsmap

            # Remove any "marking" sections because the US-Cert is evil
            log.debug("Removing Marking elements...")
            pattern = ".//{http://data-marking.mitre.org/Marking-1}Marking"
            for element in stix_xml.findall(pattern):
                element.getparent().remove(element)

            log.debug("Writing cleaned XML to Tempfile")
            f = SpooledTemporaryFile(max_size=10 * 1024)
            f.write(etree.tostring(stix_xml))
            f.seek(0)

            # Pray to anything you hold sacred
            ns_objmap = map(lambda x: Namespace(ns_map[x], x), ns_map)

            for ns in ns_objmap:
                log.debug("Trying to add namespace %s", ns)
                try:
                    nsparser.STIX_NAMESPACES.add_namespace(ns)
                    mixbox.namespaces.register_namespace(ns)
                except Exception as ex:
                    log.exception(ex)
            try:
                log.debug("Attempting to read clean XML into STIX...")
                stix_package = STIXPackage.from_xml(f)
            except Exception as ex:
                # No joy. Quit.
                log.fatal("Could not :<")
                log.exception(ex)
                f.seek(0)
                with open("FAILED_STIX.xml", "wb") as g:
                    g.write(f.read())
                raise STIXLoadError("Could not load stix file. {}".format(ex))

        return stix_package

    elif isinstance(stix, (str, bytes)):
        if isinstance(stix, bytes):
            stix = stix.decode()

        # It's text, we'll need to use a temporary file

        # Create a temporary file to load from
        # Y'know I should probably give it a max size before jumping to disk
        # idk, 10MB? Sounds reasonable.
        f = SpooledTemporaryFile(max_size=10 * 1024)

        # O I have idea for sneak
        # Will be very sneak
        # Write the (probably) XML to file
        f.write(stix.encode("utf-8"))

        # Reset the file so we can read from it
        f.seek(0)

        # AHA SNEAK DIDN'T EXPECT RECURSION DID YOU
        return load_stix(f)
示例#22
0
 def setUp(self):
     ioc_ns = Namespace(
         "http://stix.mitre.org/extensions/TestMechanism#OpenIOC2010-1",
         "stix-openioc", '')
     idgen.set_id_namespace(ioc_ns)
示例#23
0
def main():
    ######################################################################
    # MODIFICARE LE VARIABILI SEGUENTI

    MyTITLE = "APT28 / Fancy Bear"
    DESCRIPTION = "Emanuele De Lucia - APT28 / Fancy Bear still targeting military institutions - https://www.emanueledelucia.net/apt28-targeting-military-institutions/"

    sha256 = []
    md5 = [
        '43D7FFD611932CF51D7150B176ECFC29', '549726B8BFB1919A343AC764D48FDC81'
    ]
    sha1 = []
    domains = ['beatguitar.com']
    urls = [
        'https://beatguitar.com/aadv/gJNn/X2/ep/VQOA/3.SMPTE292M/?ct=+lMQKtXi0kf+3MVk38U=',
        'https://beatguitar.com/n2qqSy/HPSe0/SY/yAsFy8/mSaYZP/lw.sip/?n=VxL0BnijNmtTnSFIcoQ='
    ]
    ips = ['185.99.133.72']
    emails = []

    ######################################################################

    # Costruzione STIX file
    NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN")
    set_id_namespace(NAMESPACE)

    timestamp = datetime.datetime.fromtimestamp(
        time.time()).strftime('%Y-%m-%d %H:%M:%S')
    SHORT = timestamp

    wrapper = STIXPackage()
    info_src = InformationSource()
    info_src.identity = Identity(name="CyberSaiyan Community")

    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = "WHITE"
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)

    wrapper.stix_header = STIXHeader(information_source=info_src,
                                     title=MyTITLE,
                                     description=DESCRIPTION,
                                     short_description=SHORT)
    wrapper.stix_header.handling = handling

    # HASH indicators
    indicatorHASH = Indicator()
    indicatorHASH.title = MyTITLE + " - HASH"
    indicatorHASH.add_indicator_type("File Hash Watchlist")

    for idx, sha256 in enumerate(sha256):
        filei = File()
        filei.add_hash(Hash(sha256))

        obsi = Observable(filei)
        indicatorHASH.add_observable(obsi)

    for idx, md5 in enumerate(md5):
        filej = File()
        filej.add_hash(Hash(md5))

        obsj = Observable(filej)
        indicatorHASH.add_observable(obsj)

    for idx, sha1 in enumerate(sha1):
        filek = File()
        filek.add_hash(Hash(sha1))

        obsk = Observable(filek)
        indicatorHASH.add_observable(obsk)

    # DOMAIN indicators
    indiDOMAIN = Indicator()
    indiDOMAIN.title = MyTITLE + " - DOMAIN"
    indiDOMAIN.add_indicator_type("Domain Watchlist")

    for idu, domains in enumerate(domains):
        url = URI()
        url.value = domains
        url.type_ = URI.TYPE_DOMAIN
        url.condition = "Equals"

        obsu = Observable(url)
        indiDOMAIN.add_observable(obsu)

    # URL indicators
    indiURL = Indicator()
    indiURL.title = MyTITLE + " - URL"
    indiURL.add_indicator_type("URL Watchlist")

    for idu, urls in enumerate(urls):
        url = URI()
        url.value = urls
        url.type_ = URI.TYPE_URL
        url.condition = "Equals"

        obsu = Observable(url)
        indiURL.add_observable(obsu)

    # IP indicators
    indiIP = Indicator()
    indiIP.title = MyTITLE + " - IP"
    indiIP.add_indicator_type("IP Watchlist")

    for idu, ips in enumerate(ips):
        ip = Address()
        ip.address_value = ips

        obsu = Observable(ip)
        indiIP.add_observable(obsu)

    # EMAIL indicators
    indiEMAIL = Indicator()
    indiEMAIL.title = MyTITLE + " - EMAIL"
    indiEMAIL.add_indicator_type("Malicious E-mail")

    for idu, emails in enumerate(emails):
        email = EmailAddress()
        email.address_value = emails

        obsu = Observable(email)
        indiEMAIL.add_observable(obsu)

    # add all indicators
    wrapper.add_indicator(indicatorHASH)
    wrapper.add_indicator(indiDOMAIN)
    wrapper.add_indicator(indiURL)
    wrapper.add_indicator(indiIP)
    wrapper.add_indicator(indiEMAIL)

    print(wrapper.to_xml())
示例#24
0
from cybox.objects.file_object import File
from stix.exploit_target import Vulnerability
from cybox.objects.mutex_object import Mutex
from cybox.common import Hash
from stix.indicator import Indicator, CompositeIndicatorExpression
from stix.common import InformationSource, Identity
from cybox.common import Time
from lxml import etree as et
from stix.common.vocabs import PackageIntent
from stix.core import STIXPackage
from mixbox.idgen import set_id_namespace
from mixbox.namespaces import Namespace
from IPy import *

PULSE_SERVER_BASE = "https://otx.alienvault.com/"
STIXNAMESPACE = Namespace("https://otx.alienvault.com", "alienvault-otx")
set_id_namespace(STIXNAMESPACE)


class StixExport:
    def __init__(self, pulse):
        self.stix_package = STIXPackage()
        self.stix_header = STIXHeader()
        self.pulse = pulse
        self.hash_translation = {
            "FileHash-MD5": Hash.TYPE_MD5,
            "FileHash-SHA1": Hash.TYPE_SHA1,
            "FileHash-SHA256": Hash.TYPE_SHA256
        }
        self.address_translation = {
            "IPv4": Address.CAT_IPV4,
示例#25
0
# Copyright (c) 2017, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

from mixbox.namespaces import Namespace

ISA_NAMESPACES = [
    # ISA v2/EDH v3
    Namespace(
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ISAMarkingsAssertionsType.v2.xsd',
        'isam-assert-v2',
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ISAMarkingsAssertionsType.v2.xsd'
    ),
    Namespace(
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ISAMarkingsType.v2.xsd',
        'isam-v2',
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ISAMarkingsType.v2.xsd'
    ),
    Namespace(
        'urn:edm:edh:cyber:v3', 'edh-v3',
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/SD-EDH_Profile_Cyber.v3.xsd'
    )
]
示例#26
0
def init_id_namespace():
    # setup namespace...
    short_namespace = "openioc"
    namespace = Namespace("http://openioc.org/", short_namespace, "")
    set_id_namespace(namespace)
示例#27
0
def main():
    # define constants
    TI_REQUEST_URL = "https://api.intelgraph.idefense.com/rest/threatindicator/v0"
    # iDefense API Key
    # To avoid hard-coding creds, I'm using environment variables

    if os.environ.get('IDEF_TOKEN') is None:
        print(
            "error: please store your iDefense IntelGraph API key in the IDEF_TOKEN environment"
        )
        sys.exit(1)

    API_KEY = os.environ.get('IDEF_TOKEN')
    API_SECRET = ''

    # TODO: use command-line parameter
    timestr = datetime.datetime.utcnow() - datetime.timedelta(days=1)
    LAST_IMPORT = timestr.strftime("%Y-%m-%dT%H:%M:%S") + ".000Z"

    HEADERS = {
        "Content-Type": "application/json",
        "auth-token": API_KEY,
        "X-Api-Key-Proof": API_SECRET
    }

    print(HEADERS)

    page = 1
    more_data = True
    count = 0

    # Set namespace
    NAMESPACE = Namespace("https://intelgraph.idefense.com", "idefense")
    set_id_namespace(NAMESPACE)

    # Create STIX Package
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.description = "iDefense Threat Indicators Feed"
    stix_package.stix_header = stix_header

    ttps = {}
    malware = {}

    try:

        while more_data:
            request_payload = {
                "start_date": LAST_IMPORT,
                "page_size": 200,
                "page": page
            }
            r = requests.post(TI_REQUEST_URL,
                              headers=HEADERS,
                              data=json.dumps(request_payload))
            print(r)
            response = []
            if r.status_code == requests.codes.ok:
                try:
                    # Read in response as json
                    response = r.json()

                except (ValueError, KeyError):
                    print("Response couldn't be decoded :(")
                    more_data = False
                    continue

                more_data = response.get('more', 'False')
                print("Page %d ==> %s (%s)" %
                      (page, response['more'], response['total_size']))
                page += 1

                # Iterate the response
                for indicatorD in response['results']:
                    count += 1
                    # Indicator value such as the value of the IP/Domain/URL
                    indicator = indicatorD.get('key')
                    print(indicator, indicatorD.get('type'))
                    if indicatorD.get('last_seen_as') is None:
                        last_seen_as = 'UNKNOWN'
                    else:
                        last_seen_as = ''.join(indicatorD.get('last_seen_as'))

                    # Identify TTP
                    if last_seen_as not in ttps:
                        ttps[last_seen_as] = TTP(title=last_seen_as)
                        stix_package.add_ttp(ttps[last_seen_as])

                    # Identify malware source
                    if 'files' in indicatorD:
                        for hashD in indicatorD['files']:
                            md5 = hashD.get('key')
                            # Malware Family classification of the hash if available
                            if hashD.get('malware_family') is None:
                                malware_family = "Unknown"
                            else:
                                malware_family = ''.join(
                                    hashD.get('malware_family'))
                            if md5 not in malware:
                                malware[md5] = add_malware(
                                    md5, malware_family, hashD.get('uuid'))

                    if indicatorD.get('type') == "url":
                        # Create indicator
                        indicator = Indicator(
                            id_="indicator-{0}".format(indicatorD.get('uuid')),
                            title=''.join(indicatorD.get('malware_family')),
                            timestamp=indicatorD.get('last_seen'))
                        indicator.add_indicator_type("URL Watchlist")

                        # Populate URL
                        url = URI()
                        url.value = indicatorD.get('key')
                        url.type_ = URI.TYPE_URL
                        url.value.condition = "Equals"

                        indicator.add_observable(url)

                    elif indicatorD.get('type') == "domain":
                        # Populate domain name
                        indicator = Indicator(
                            id_="indicator-{0}".format(indicatorD.get('uuid')),
                            title=''.join(indicatorD.get('malware_family')),
                            timestamp=indicatorD.get('last_seen'))
                        indicator.add_indicator_type("Domain Watchlist")
                        domain = DomainName()
                        domain.value = indicatorD.get('key')
                        domain.value.condition = "Equals"
                        indicator.add_observable(domain)

                    elif indicatorD.get('type') == "ip":
                        # Create indicator
                        indicator = Indicator(
                            id_="indicator-{0}".format(indicatorD.get('uuid')),
                            title=indicatorD.get('malware_family'),
                            timestamp=indicatorD.get('last_seen'))
                        indicator.add_indicator_type("IP Watchlist")
                        # Populate IP address
                        addr = Address(address_value=indicatorD.get('key'),
                                       category=Address.CAT_IPV4)
                        addr.condition = "Equals"
                        indicator.add_observable(addr)

                    # Link TTP
                    indicator.add_indicated_ttp(
                        TTP(idref=ttps[last_seen_as].id_))
                    # Indicate confidence score
                    indicator.confidence = Confidence(
                        value=VocabString(indicatorD.get('confidence')))
                    # Add related indicator to malware
                    indicator.add_related_indicator(malware[md5])
                    # Add to package
                    stix_package.add_indicator(indicator)

            else:
                print("API request couldn't be fulfilled due status code: %d" %
                      r.status_code)
                more_data = False

    except requests.exceptions.ConnectionError as e:
        print("Check your network connection\n %s" % str(e))

    except requests.exceptions.HTTPError as e:
        print("Bad HTTP response\n %s" % str(e))

    except Exception as e:
        print("Uncaught exception\n %s" % str(e))

    # Output to XML
    with open('stix-1.2.1.xml', 'wb') as f:
        f.write(stix_package.to_xml())
示例#28
0
# Copyright (c) 2015, The MITRE Corporation. All rights reserved.
# See LICENSE.txt for complete terms.

import unittest

from mixbox.namespaces import Namespace
from mixbox import idgen

TEST_NS = Namespace("http://some.namespace.com", "something", '')


class IDGeneratorMinimalTest(unittest.TestCase):
    def test_id(self):
        # Make sure we can create an ID with a minimum of effort.

        # TODO: actually delete the module and reimport it to make sure there
        # is nothing left over from another test.
        self.assertNotEqual(idgen.create_id(), "")


class IDGeneratorTest(unittest.TestCase):
    """Tests for the cybox.utils.IDGenerator class."""
    def setUp(self):
        method = idgen.IDGenerator.METHOD_INT
        self.generator = idgen.IDGenerator(method=method)

    def test_incrementing_ids(self):
        self.assertEqual(self.generator.create_id(), "example:guid-1")
        self.assertEqual(self.generator.create_id(), "example:guid-2")
        self.assertEqual(self.generator.create_id(), "example:guid-3")
示例#29
0
from cbfeeds import CbFeed
from cbfeeds import CbFeedInfo

from stix.core import STIXPackage
from stix.utils.parser import EntityParser, UnsupportedVersionError
from cybox.bindings.file_object import FileObjectType
from cybox.bindings.domain_name_object import DomainNameObjectType
from cybox.bindings.address_object import AddressObjectType

from stix.utils import nsparser
import mixbox.namespaces
from mixbox.namespaces import Namespace

ADDITIONAL_NAMESPACES = [
    Namespace(
        'http://us-cert.gov/ciscp', 'CISCP',
        'http://www.us-cert.gov/sites/default/files/STIX_Namespace/ciscp_vocab_v1.1.1.xsd'
    )
]


def merge(d1, d2):
    """ given two dictionaries, return a single dictionary
        that merges the two.   
    """

    result = d1
    if not d2: return result
    for k in d2:
        if k in result:
            result[k].extend(d2[k])
        else:
示例#30
0
def main(argv):
    ######################################################################
    # Se non impostati da command line vengono utilizzati i seguenti valori per TITLE, DESCRIPTION, IDENTITY
    # Il title e' ID univoco della minaccia (es. Cobalt / Danabot / APT28)
    TITLE = "Test"

    # La description strutturiamola come segue
    # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)>
    DESCRIPTION = "Cyber Saiyan - Test - https://infosharing.cybersaiyan.it"

    # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community 
    IDENTITY = "Cyber Saiyan Community"

    # File degli IoC
    IOCFILE = "CS-ioc.txt"

    # Prefisso STIX output files STIX 1.2 e STIX 2
    OUTFILEPREFIX = "package"

    # Short Description - UNUSED
    SHORT = "unused"
    ######################################################################

    VERBOSE = 0

    # Parse ARGV[]
    try:
        opts, args = getopt.getopt(argv, "ht:d:i:f:o:v")
    except getopt.GetoptError:
        print(
            "CS_build_stix-from_files.py [-t TITLE] [-d DESCRIPTION] [-i IDENTITY] [-f IOC_FILE] [-o STIX_FILES_PREFIX]")
        sys.exit(2)

    for opt, arg in opts:
        if opt == "-h":
            print(
                "CS_build_stix-from_files.py [-t TITLE] [-d DESCRIPTION] [-i IDENTITY] [-f IOC_FILE] [-o STIX_FILES_PREFIX]")
            sys.exit()
        elif opt == "-t":
            TITLE = arg
        elif opt == "-d":
            DESCRIPTION = arg
        elif opt == "-i":
            IDENTITY = arg
        elif opt == "-f":
            IOCFILE = arg
        elif opt == "-o":
            OUTFILEPREFIX = arg
        elif opt == "-v":
            VERBOSE = 1

    print("---------------------")
    print("TITLE: " + TITLE)
    print("DESCRIPTION: " + DESCRIPTION)
    print("IDENTITY: " + IDENTITY)
    print("IOC FILE: " + IOCFILE)
    print("---------------------")

    ########################
    # Commond data
    timestamp = datetime.utcnow().strftime("%Y-%m-%d %H:%M:%S")

    ########################
    # Build STIX 1.2 file
    info_src = InformationSource()
    info_src.identity = Identity(name=IDENTITY)

    NAMESPACE = Namespace("https://infosharing.cybersaiyan.it", "CYBERSAIYAN")
    set_id_namespace(NAMESPACE)

    wrapper = STIXPackage()

    marking_specification = MarkingSpecification()
    marking_specification.controlled_structure = "//node() | //@*"
    tlp = TLPMarkingStructure()
    tlp.color = "white"
    marking_specification.marking_structures.append(tlp)

    handling = Marking()
    handling.add_marking(marking_specification)

    wrapper.stix_header = STIXHeader(information_source=info_src,
                                     title=TITLE,
                                     description=DESCRIPTION,
                                     short_description=SHORT)
    wrapper.stix_header.handling = handling

    # HASH indicators
    indicatorHASH = Indicator()
    indicatorHASH.title = TITLE + " - HASH"
    indicatorHASH.add_indicator_type("File Hash Watchlist")

    # DOMAIN indicators
    indiDOMAIN = Indicator()
    indiDOMAIN.title = TITLE + " - DOMAIN"
    indiDOMAIN.add_indicator_type("Domain Watchlist")

    # URL indicators
    indiURL = Indicator()
    indiURL.title = TITLE + " - URL"
    indiURL.add_indicator_type("URL Watchlist")

    # IP indicators
    indiIP = Indicator()
    indiIP.title = TITLE + " - IP"
    indiIP.add_indicator_type("IP Watchlist")

    # EMAIL indicators
    indiEMAIL = Indicator()
    indiEMAIL.title = TITLE + " - EMAIL"
    indiEMAIL.add_indicator_type("Malicious E-mail")

    ########################
    # Build STIX 2 file
    pattern_sha256 = []
    pattern_md5 = []
    pattern_sha1 = []
    pattern_domain = []
    pattern_url = []
    pattern_ip = []
    pattern_email = []

    # Marking
    marking_def_white = stix2.TLP_WHITE

    # campagna
    # [TODO] aggiungere tutti i campi dello STIX 1.2 (es. IDENTITY)
    campaign_MAIN = stix2.Campaign(
        created=timestamp,
        modified=timestamp,
        name=TITLE,
        description=DESCRIPTION,
        first_seen=timestamp,
        objective="TBD"
    )

    ########################
    # Read IoC file
    loaddata(IOCFILE)

    if (VERBOSE): print("Reading IoC file " + IOCFILE + "...")
    ioccount = 0

    # sha256
    for ioc in listSHA256:
        # STIX 1.2
        filei = File()
        filei.add_hash(Hash(ioc))

        obsi = Observable(filei)
        indicatorHASH.add_observable(obsi)
        if (VERBOSE): print("SHA256: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_sha256.append("[file:hashes.'SHA-256' = '" + ioc + "'] OR ")

    # md5
    for ioc in listMD5:
        # STIX 1.2
        filej = File()
        filej.add_hash(Hash(ioc))

        obsj = Observable(filej)
        indicatorHASH.add_observable(obsj)
        if (VERBOSE): print("MD5: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_md5.append("[file:hashes.'MD5' = '" + ioc + "'] OR ")

    # sha1
    for ioc in listSHA1:
        # STIX 1.2
        filek = File()
        filek.add_hash(Hash(ioc))

        obsk = Observable(filek)
        indicatorHASH.add_observable(obsk)
        if (VERBOSE): print("SHA1: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_sha1.append("[file:hashes.'SHA1' = '" + ioc + "'] OR ")

    # domains
    for ioc in listDOMAIN:
        # STIX 1.2
        url = URI()
        url.value = ioc
        url.type_ = URI.TYPE_DOMAIN
        url.condition = "Equals"

        obsu = Observable(url)
        indiDOMAIN.add_observable(obsu)
        if (VERBOSE): print("DOMAIN: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_domain.append("[domain-name:value = '" + ioc + "'] OR ")

    # url
    for ioc in listURL:
        # STIX 1.2
        url = URI()
        url.value = ioc
        url.type_ = URI.TYPE_URL
        url.condition = "Equals"

        obsu = Observable(url)
        indiURL.add_observable(obsu)
        if (VERBOSE): print("URL: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_url.append("[url:value = '" + ioc + "'] OR ")

    # ip
    for ioc in listIP:
        # STIX 1.2
        ip = Address()
        ip.address_value = ioc

        obsu = Observable(ip)
        indiIP.add_observable(obsu)
        if (VERBOSE): print("IP: " + ioc)

        ioccount += 1

        # STIX 2
        pattern_ip.append("[ipv4-addr:value = '" + ioc + "'] OR ")

    # email
    for ioc in listEMAIL:
        # STIX 1.2
        email = EmailAddress()
        email.address_value = ioc

        obsu = Observable(email)
        indiEMAIL.add_observable(obsu)

        if (VERBOSE): print("Email: " + ioc)
        ioccount += 1

        # STIX 2
        pattern_email.append("[email-message:from_ref.value = '" + ioc + "'] OR ")

    # subject
    for ioc in listSUBJECT:
        # STIX 1.2
        emailsubject = EmailMessage()
        emailsubject.subject = ioc

        obsu = Observable(emailsubject)
        indiEMAIL.add_observable(obsu)

        if (VERBOSE): print("Subject: " + ioc)
        ioccount += 1

        # STIX 2 (http://docs.oasis-open.org/cti/stix/v2.0/stix-v2.0-part5-stix-patterning.html)
        # Replace all quotes in a subject string with escaped quotes
        pattern_email.append("[email-message:subject = '" + ioc.replace("'", "\\'") + "'] OR ")

    ########################
    # add all indicators to STIX 1.2
    wrapper.add_indicator(indicatorHASH)
    wrapper.add_indicator(indiDOMAIN)
    wrapper.add_indicator(indiURL)
    wrapper.add_indicator(indiIP)
    wrapper.add_indicator(indiEMAIL)

    ########################
    # prepare for STIX 2
    bundle_objects = [campaign_MAIN, marking_def_white]

    if len(pattern_sha256) != 0:
        stix2_sha256 = "".join(pattern_sha256)
        stix2_sha256 = stix2_sha256[:-4]

        indicator_SHA256 = stix2.Indicator(
            name=TITLE + " - SHA256",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_sha256,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_SHA256 = stix2.Relationship(indicator_SHA256, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_SHA256)
        bundle_objects.append(relationship_indicator_SHA256)

    if len(pattern_md5) != 0:
        stix2_md5 = "".join(pattern_md5)
        stix2_md5 = stix2_md5[:-4]

        indicator_MD5 = stix2.Indicator(
            name=TITLE + " - MD5",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_md5,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_MD5 = stix2.Relationship(indicator_MD5, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_MD5)
        bundle_objects.append(relationship_indicator_MD5)

    if len(pattern_sha1) != 0:
        stix2_sha1 = "".join(pattern_sha1)
        stix2_sha1 = stix2_sha1[:-4]

        indicator_SHA1 = stix2.Indicator(
            name=TITLE + " - SHA1",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_sha1,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_SHA1 = stix2.Relationship(indicator_SHA1, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_SHA1)
        bundle_objects.append(relationship_indicator_SHA1)

    if len(pattern_domain) != 0:
        stix2_domain = "".join(pattern_domain)
        stix2_domain = stix2_domain[:-4]

        indicator_DOMAINS = stix2.Indicator(
            name=TITLE + " - DOMAINS",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_domain,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_DOMAINS = stix2.Relationship(indicator_DOMAINS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_DOMAINS)
        bundle_objects.append(relationship_indicator_DOMAINS)

    if len(pattern_url) != 0:
        stix2_url = "".join(pattern_url)
        stix2_url = stix2_url[:-4]

        indicator_URLS = stix2.Indicator(
            name=TITLE + " - URL",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_url,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_URLS = stix2.Relationship(indicator_URLS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_URLS)
        bundle_objects.append(relationship_indicator_URLS)

    if len(pattern_ip) != 0:
        stix2_ip = "".join(pattern_ip)
        stix2_ip = stix2_ip[:-4]

        indicator_IPS = stix2.Indicator(
            name=TITLE + " - IPS",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_ip,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_IPS = stix2.Relationship(indicator_IPS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_IPS)
        bundle_objects.append(relationship_indicator_IPS)

    if len(pattern_email) != 0:
        stix2_email = "".join(pattern_email)
        stix2_email = stix2_email[:-4]

        indicator_EMAILS = stix2.Indicator(
            name=TITLE + " - EMAILS",
            created=timestamp,
            modified=timestamp,
            description=DESCRIPTION,
            labels=["malicious-activity"],
            pattern=stix2_email,
            object_marking_refs=[marking_def_white]
        )
        relationship_indicator_EMAILS = stix2.Relationship(indicator_EMAILS, "indicates", campaign_MAIN)
        bundle_objects.append(indicator_EMAILS)
        bundle_objects.append(relationship_indicator_EMAILS)

    # creo il bunble STIX 2
    bundlestix2 = stix2.Bundle(objects=bundle_objects)

    if (ioccount > 0):
        ########################
        # save to STIX 1.2 file
        print("Writing STIX 1.2 package: " + OUTFILEPREFIX + ".stix")
        f = open(OUTFILEPREFIX + ".stix", "wb")
        f.write(wrapper.to_xml())
        f.close()

        ########################
        # save to STIX 2 file
        print("Writing STIX 2 package: " + OUTFILEPREFIX + ".stix2")
        g = open(OUTFILEPREFIX + ".stix2", "w")
        g.write(str(bundlestix2))
        g.close()
    else:
        print("No IoC found")