Example #1
0
def pre_import_stix(file, cluster=None):
    from stix.core import STIXPackage

    pkg = STIXPackage()
    pkg = pkg.from_xml(file)

    reports = pkg.reports
    header = None
    timestamp = ""
    try:
        header = reports[0].header
        timestamp = reports[0].timestamp
    except:
        header = pkg.header
    # sc = header_to_subcluster(header)
    sc = {"name": header.title, "description": header.description, "firstseen": timestamp}

    """
    campaigns= pkg.campaigns
    for campaign in campaigns:
        s = campaign_to_subcluster(campaign)
        if not s in sc:
            sc.append(s)
    """
    # ttp = pkg.ttps
    obs = pkg.observables
    if sc:
        sc["node"] = []
        sc = obs_to_node(obs, sc)
        sc["cluster"] = cluster

    return sc
def main():
    stix_package = STIXPackage()
    ta = ThreatActor()
    ta.title = "Disco Team Threat Actor Group"
    
    ta.identity = CIQIdentity3_0Instance()
    identity_spec = STIXCIQIdentity3_0()
    
    identity_spec.party_name = PartyName()
    identity_spec.party_name.add_organisation_name(OrganisationName("Disco Tean", type_="CommonUse"))
    identity_spec.party_name.add_organisation_name(OrganisationName("Equipo del Discoteca", type_="UnofficialName"))
    
    identity_spec.add_language("Spanish")
    
    address = Address()
    address.country = Country()
    address.country.add_name_element("United States")
    address.administrative_area = AdministrativeArea()
    address.administrative_area.add_name_element("California")    
    identity_spec.add_address(address)
    
    identity_spec.add_electronic_address_identifier("*****@*****.**")
    
    ta.identity.specification = identity_spec
    stix_package.add_threat_actor(ta)
    print stix_package.to_xml()
def main():
    from stix.campaign import Campaign, Attribution
    from stix.threat_actor import ThreatActor
    from stix.incident import Incident
    from stix.core import STIXPackage
    from stix.ttp import TTP, VictimTargeting

    ttp = TTP()
    ttp.title = "Victim Targeting: Customer PII and Financial Data"
    ttp.victim_targeting = VictimTargeting()
    ttp.victim_targeting.add_targeted_information("Information Assets - Financial Data")

    actor = ThreatActor()
    actor.title = "People behind the intrusion"
    attrib = Attribution()
    attrib.append(actor)

    c = Campaign()
    c.attribution = []
    c.attribution.append(attrib)
    c.title = "Compromise of ATM Machines"
    c.related_ttps.append(ttp)

    c.related_incidents.append(Incident(idref="example:incident-229ab6ba-0eb2-415b-bdf2-079e6b42f51e"))
    c.related_incidents.append(Incident(idref="example:incident-517cf274-038d-4ed4-a3ec-3ac18ad9db8a"))
    c.related_incidents.append(Incident(idref="example:incident-7d8cf96f-91cb-42d0-a1e0-bfa38ea08621"))

    pkg = STIXPackage()
    pkg.add_campaign(c)

    print pkg.to_xml()
def main():
    from stix.coa import CourseOfAction, Objective
    from stix.common import Confidence
    from stix.core import STIXPackage
    from cybox.core import Observables
    from cybox.objects.address_object import Address

    pkg = STIXPackage()
    coa = CourseOfAction()
    coa.title = "Block traffic to PIVY C2 Server (10.10.10.10)"
    coa.stage = "Response"
    coa.type_ = "Perimeter Blocking"

    obj = Objective()
    obj.description = "Block communication between the PIVY agents and the C2 Server"
    obj.applicability_confidence = Confidence("High")

    coa.objective = obj
    coa.impact = "Low"
    coa.impact.description = "This IP address is not used for legitimate hosting so there should be no operational impact."
    coa.cost = "Low"
    coa.efficacy = "High"

    addr = Address(address_value="10.10.10.10", category=Address.CAT_IPV4)
    coa.parameter_observables = Observables(addr)

    pkg.add_course_of_action(coa)

    print(pkg.to_xml(encoding=None))
def main():
    # Create a CyboX File Object
    f = File()

    # This automatically detects that it's an MD5 hash based on the length
    f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F")

    # Create an Indicator with the File Hash Object created above.
    indicator = Indicator()
    indicator.title = "File Hash Example"
    indicator.description = (
        "An indicator containing a File observable with an associated hash"
    )
    indicator.set_producer_identity("The MITRE Corporation")
    indicator.set_produced_time(utils.dates.now())

    # Add The File Object to the Indicator. This will promote the CybOX Object
    # to a CybOX Observable internally.
    indicator.add_object(f)

    # Create a STIX Package
    stix_package = STIXPackage()

    # Create the STIX Header and add a description.
    stix_header = STIXHeader()
    stix_header.description = "File Hash Indicator Example"
    stix_package.stix_header = stix_header

    # Add our Indicator object. The add() method will inspect the input and
    # append it to the `stix_package.indicators` collection.
    stix_package.add(indicator)

    # Print the XML!
    print(stix_package.to_xml())
Example #6
0
    def test_user_provided_ns(self):
        """Test that user-provided namespaces are serialized.

        """
        p = STIXPackage()
        nsinfo = nsparser.NamespaceInfo()

        # Collect classes
        nsinfo.collect(p)

        TEST_PREFIX = 'test'
        TEST_NS = 'a:unit:test'
        NEW_STIX_PREFIX = 'newstix'
        NEW_STIX_NS = "http://stix.mitre.org/stix-1"

        test_dict = {
            TEST_NS: TEST_PREFIX,
            NEW_STIX_NS: NEW_STIX_PREFIX
        }

        finalized = nsinfo._finalize_namespaces(ns_dict=test_dict)
        nsinfo.finalized_namespaces

        self.assertEqual(finalized.get(TEST_PREFIX), TEST_NS)
        self.assertEqual(finalized.get(NEW_STIX_PREFIX), NEW_STIX_NS)

        # Parse the exported document and make sure that the namespaces
        # made it through the serialization process.
        xml = p.to_xml(ns_dict=test_dict)
        e = lxml.etree.XML(xml)
        self.assertEqual(e.nsmap.get(TEST_PREFIX), TEST_NS)
        self.assertEqual(e.nsmap.get(NEW_STIX_PREFIX), NEW_STIX_NS)
def main():

    rule = """
rule silent_banker : banker
{
    meta:
        description = "This is just an example"
        thread_level = 3
        in_the_wild = true

    strings:
        $a = {6A 40 68 00 30 00 00 6A 14 8D 91}
        $b = {8D 4D B0 2B C1 83 C0 27 99 6A 4E 59 F7 F9}
        $c = "UVODFRYSIHLNWPEJXQZAKCBGMT"

    condition:
        $a or $b or $c
}
"""

    stix_package = STIXPackage()

    indicator = Indicator(title="silent_banker", description="This is just an example")

    tm = YaraTestMechanism()
    tm.rule = rule
    tm.producer = InformationSource(identity=Identity(name="Yara"))
    tm.producer.references = ["http://plusvic.github.io/yara/"]
    indicator.test_mechanisms = [tm]

    stix_package.add_indicator(indicator)
    
    print stix_package.to_xml()
Example #8
0
def to_stix(infile):
    """Converts the `infile` OpenIOC xml document into a STIX Package.

    Args:
        infile: OpenIOC xml filename to translate

    Returns:
       stix.core.STIXPackage object
    """
    observables = to_cybox(infile)

    # Build Indicators from the Observable objects
    indicators = [_observable_to_indicator_stix(o) for o in observables]

    # Wrap the created Observables in a STIX Package/Indicator
    stix_package = STIXPackage()

    # Set the Indicators collection
    stix_package.indicators = indicators

    # Create and write the STIX Header. Warning: these fields have been
    # deprecated in STIX v1.2!
    stix_header = STIXHeader()
    stix_header.package_intent = PackageIntent.TERM_INDICATORS_MALWARE_ARTIFACTS
    stix_header.description = "CybOX-represented Indicators Translated from OpenIOC File"
    stix_package.stix_header = stix_header

    return stix_package
Example #9
0
def main():
    f = File()
    f.add_hash("4EC0027BEF4D7E1786A04D021FA8A67F")
    
    indicator = Indicator()
    indicator.title = "File Hash Example"
    indicator.description = "An indicator containing a File observable with an associated hash"
    indicator.set_producer_identity("The MITRE Corporation")
    indicator.set_produced_time(datetime.now(tzutc()))
    indicator.add_object(f)
    
    party_name = PartyName(name_lines=["Foo", "Bar"], person_names=["John Smith", "Jill Smith"], organisation_names=["Foo Inc.", "Bar Corp."])
    ident_spec = STIXCIQIdentity3_0(party_name=party_name)
    ident_spec.add_electronic_address_identifier("*****@*****.**")
    ident_spec.add_free_text_line("Demonstrating Free Text!")
    ident_spec.add_contact_number("555-555-5555")
    ident_spec.add_contact_number("555-555-5556")
    identity = CIQIdentity3_0Instance(specification=ident_spec)
    indicator.set_producer_identity(identity)
    
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.description = "Example"
    stix_package.stix_header = stix_header
    stix_package.add_indicator(indicator)
    
    xml = stix_package.to_xml() 
    print(xml)
def main():
    # Create our CybOX Simple Hash Value
    shv = Hash()
    shv.simple_hash_value = "4EC0027BEF4D7E1786A04D021FA8A67F"

    # Create a CybOX File Object and add the Hash we created above.
    f = File()
    h = Hash(shv, Hash.TYPE_MD5)
    f.add_hash(h)

    # Create the STIX Package
    stix_package = STIXPackage()

    # Create the STIX Header and add a description.
    stix_header = STIXHeader()
    stix_header.description = "Simple File Hash Observable Example"
    stix_package.stix_header = stix_header

    # Add the File Hash Observable to the STIX Package. The add() method will
    # inspect the input and add it to the top-level stix_package.observables
    # collection.
    stix_package.add(f)

    # Print the XML!
    print(stix_package.to_xml())
def main():
    pkg = STIXPackage()
    affected_asset = AffectedAsset()
    affected_asset.description = "Database server at hr-data1.example.com"
    affected_asset.type_ = "Database"
    affected_asset.type_.count_affected = 1
    affected_asset.business_function_or_role = "Hosts the database for example.com"
    affected_asset.ownership_class = "Internally-Owned"
    affected_asset.management_class = "Internally-Managed"
    affected_asset.location_class = "Internally-Located"

    property_affected = PropertyAffected()
    property_affected.property_ = "Confidentiality"
    property_affected.description_of_effect = "Data was exfiltrated, has not been determined which data or how."
    property_affected.non_public_data_compromised = "Yes"
    property_affected.non_public_data_compromised.data_encrypted = False

    security_effect_nature = NatureOfSecurityEffect()
    security_effect_nature.append(property_affected)

    affected_asset.nature_of_security_effect = security_effect_nature
    affected_assets = AffectedAssets()
    affected_assets.append(affected_asset)
    incident = Incident(title="Exfiltration from hr-data1.example.com")
    incident.affected_assets = affected_assets

    pkg.add_incident(incident)

    print(pkg.to_xml(encoding=None))
Example #12
0
def generateMainPackage(events):
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = "Export from " + namespace[1] + " MISP"
    stix_header.package_intents = "Threat Report"
    stix_package.stix_header = stix_header
    return stix_package
def buildSTIX(ident,confid,restconfid, effect, resteffect,typeIncident,resttype,asset,restasset,hashPkg):
    # IMPLEMENTATION WORKAROUND - 
    # restConfid --> header.description
    # resteffect --> breach.description
    # resttype --> reporter.description
    # restasset --> reporter.identity.name 
    # setup stix document
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.description = restconfid # "Example description"
    stix_package.stix_header = stix_header
    # add incident and confidence
    breach = Incident(id_=ident)
    breach.description = resteffect # "Intrusion into enterprise network"
    breach.confidence = Confidence()
    breach.confidence.value=confid
    breach._binding_class.xml_type = typeIncident
    # stamp with reporter
    breach.reporter = InformationSource()
    breach.reporter.description = resttype #"The person who reported it"

    breach.reporter.time = Time()
    breach.reporter.time.produced_time = datetime.strptime("2014-03-11","%Y-%m-%d") # when they submitted it

    breach.reporter.identity = Identity()
    breach.reporter.identity.name = restasset # "Sample Investigations, LLC"

    # set incident-specific timestamps
    breach.time = incidentTime()
    breach.title = "Breach of CyberTech Dynamics"
    breach.time.initial_compromise = datetime.strptime("2012-01-30", "%Y-%m-%d") 
    breach.time.incident_discovery = datetime.strptime("2012-05-10", "%Y-%m-%d") 
    breach.time.restoration_achieved = datetime.strptime("2012-08-10", "%Y-%m-%d") 
    breach.time.incident_reported = datetime.strptime("2012-12-10", "%Y-%m-%d") 

    # add the impact
    #impact = ImpactAssessment()
    #impact.add_effect("Unintended Access")
    #breach.impact_assessment = impact
    affected_asset = AffectedAsset()
    affected_asset.description = "Database server at hr-data1.example.com" 
    affected_asset.type_ = asset
    
    breach.affected_assets = affected_asset
    #print("asset type: %s"%(breach.affected_assets[0].type_))
    # add the victim
    breach.add_victim (hashPkg)

    # add the impact
    impact = ImpactAssessment()
    impact.add_effect(effect)
    breach.impact_assessment = impact

    stix_package.add_incident(breach)
    #print("hey, I've got an incident! list size=%s"%(len(stix_package._incidents)))

    # Print the XML!
    #print(stix_package.to_xml())
    return stix_package
Example #14
0
 def init_stix(self):
     stix_package = STIXPackage()
     stix_header = STIXHeader()
     info_source = InformationSource()
     info_source.description = 'HAR file analysis of visit to malicious URL'
     stix_header.information_source = info_source
     stix_package.stix_header = stix_header
     return stix_package
Example #15
0
def main():
    fn = 'ex_01.xml'
    stix_package = STIXPackage.from_xml(fn)
    stix_dict = stix_package.to_dict() # parse to dictionary
    pprint(stix_dict)

    stix_package_two = STIXPackage.from_dict(stix_dict) # create python-stix object from dictionary
    xml = stix_package_two.to_xml() # generate xml from python-stix object
    print(xml)
Example #16
0
def file_to_stix(file_):
    '''transform files into stix packages'''
    try:
        stix_package = STIXPackage.from_xml(file_)
    except UnsupportedVersionError as ex:
        updated = ramrod.update(file_)
        updated_xml = updated.document.as_stringio()
        stix_package = STIXPackage.from_xml(updated_xml)
    return stix_package
Example #17
0
    def __repr__(self):
        stix_package = STIXPackage()
        stix_header = STIXHeader()
        stix_package.stix_header = stix_header

        for d in self.data:
            i = self._create_indicator(d)
            stix_package.add_indicator(i)
        return stix_package.to_xml()
def pkg_builder(mailbox_cfg, mailitem):
    pkg = STIXPackage(
        id_="%s:Package-%s" % (constants.DEFAULT_STIX_ALIAS, uuid.uuid4()),
        indicators=data_to_indicator(mailbox_cfg, mailitem),
        stix_header=stix_header(
            title=mailitem.email_subject),
    )
    data = pkg.to_xml(ns_dict={mailbox_cfg.stix_prefix: constants.DEFAULT_STIX_ALIAS}, include_idgen=False, include_schemalocs=False)
    #return StringIO(data)
    return data
Example #19
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)
Example #20
0
def build_stix( input_dict ):
    # setup stix document
    stix_package = STIXPackage()
    stix_header = STIXHeader()

    stix_header.description = "Incident report for " + input_dict['organization']
    stix_header.add_package_intent ("Incident")

    # Add handling requirements if needed
    if input_dict['sensitive'] == "True":
        mark = SimpleMarkingStructure()
        mark.statement = "Sensitive"
        mark_spec = MarkingSpecification()
        mark_spec.marking_structures.append(mark)
        stix_header.handling = Marking(mark_spec)


    stix_package.stix_header = stix_header

    # add incident and confidence
    incident = Incident()
    incident.description = input_dict['description']
    incident.confidence = input_dict['confidence']

    # add incident reporter
    incident.reporter = InformationSource()
    incident.reporter.description = "Person who reported the incident"

    incident.reporter.time = Time()
    incident.reporter.time.produced_time = datetime.strptime(input_dict['timestamp'], "%Y-%m-%d") # when they submitted it

    incident.reporter.identity = Identity()
    incident.reporter.identity.name = input_dict['submitter']

    # incident time is a complex object with support for a bunch of different "when stuff happened" items
    incident.time = incidentTime()
    incident.title = "Breach of " + input_dict['organization']
    incident.time.incident_discovery = datetime.strptime(input_dict['timestamp'], "%Y-%m-%d") # when they submitted it

    # add the impact
    impact = ImpactAssessment()
    impact.add_effect(input_dict['damage'])
    incident.impact_assessment = impact

    #Add the thing that was stolen
    jewels = AffectedAsset()
    jewels.type_ = input_dict['asset']
    incident.add_affected_asset (jewels)

    # add the victim
    incident.add_victim (input_dict['organization'])

    stix_package.add_incident(incident)

    return stix_package
def main():

  data = json.load(open("data.json"))

  stix_package = STIXPackage(stix_header=STIXHeader(title=data['title'], package_intents='Incident'))

  ttps = {}

  for info in data['ips']:
    if info['bot'] not in ttps:
      ttps[info['bot']] = TTP(title=info['bot'])
      stix_package.add_ttp(ttps[info['bot']])

    incident = Incident(title=info['ip'])
    incident.time = Time()
    incident.time.first_malicious_action = info['first_seen']

    addr = Address(address_value=info['ip'], category=Address.CAT_IPV4)
    observable = Observable(item=addr)
    stix_package.add_observable(observable)

    related_ttp = RelatedTTP(TTP(idref=ttps[info['bot']].id_), relationship="Used Malware")
    incident.leveraged_ttps.append(related_ttp)

    related_observable = RelatedObservable(Observable(idref=observable.id_))
    incident.related_observables.append(related_observable)

    stix_package.add_incident(incident)

  print stix_package.to_xml()
def main():
    stix_package = STIXPackage()
    
    addr1 = Observable(Address(address_value="198.51.100.2", category=Address.CAT_IPV4))
    addr2 = Observable(Address(address_value="198.51.100.17", category=Address.CAT_IPV4))
    addr3 = Observable(Address(address_value="203.0.113.19", category=Address.CAT_IPV4))
    
    stix_package.add_observable(addr1)
    stix_package.add_observable(addr2)
    stix_package.add_observable(addr3)
    
    obs_addr1 = Observable()
    obs_addr2 = Observable()
    obs_addr3 = Observable()
    
    obs_addr1.id_ = None
    obs_addr2.id_ = None
    obs_addr3.id_ = None
    
    obs_addr1.idref = addr1.id_
    obs_addr2.idref = addr2.id_
    obs_addr3.idref = addr3.id_
    
    infrastructure = Infrastructure()
    infrastructure.observable_characterization = Observables([obs_addr1, obs_addr2, obs_addr3])
    
    resource = Resource()
    resource.infrastructure = infrastructure
    
    ttp = TTP(title="Malware C2 Channel")
    ttp.resources = resource
    
    stix_package.add_ttp(ttp)
    print stix_package.to_xml()
def main():
    stix_package = STIXPackage()
    ttp_phishing = TTP(title="Phishing")
    
    attack_pattern = AttackPattern()
    attack_pattern.capec_id = "CAPEC-98"
    attack_pattern.description = ("Phishing")
    
    ttp_phishing.behavior = Behavior()
    ttp_phishing.behavior.add_attack_pattern(attack_pattern)
    
    ttp_pivy = TTP(title="Poison Ivy Variant d1c6")
    malware_instance = MalwareInstance()
    malware_instance.add_name("Poison Ivy Variant d1c6")
    malware_instance.add_type("Remote Access Trojan")
    
    ttp_pivy.behavior = Behavior()
    ttp_pivy.behavior.add_malware_instance(malware_instance)
    
    ta_bravo = ThreatActor(title="Adversary Bravo")
    ta_bravo.identity = Identity(name="Adversary Bravo")
    
    related_ttp_phishing = RelatedTTP(TTP(idref=ttp_phishing.id_), relationship="Leverages Attack Pattern")
    ta_bravo.observed_ttps.append(related_ttp_phishing)
    
    related_ttp_pivy = RelatedTTP(TTP(idref=ttp_pivy.id_), relationship="Leverages Malware")
    ta_bravo.observed_ttps.append(related_ttp_pivy)
    
    stix_package.add_ttp(ttp_phishing)
    stix_package.add_ttp(ttp_pivy)
    stix_package.add_threat_actor(ta_bravo)
    
    print stix_package.to_xml()
Example #24
0
def taxii_content_block_to_stix(content_block):
    '''transform taxii content blocks into stix packages'''
    xml = StringIO(content_block.content)
    try:
        stix_package = STIXPackage.from_xml(xml)
    except UnsupportedVersionError as ex:
        updated = ramrod.update(xml)
        updated_xml = updated.document.as_stringio()
        stix_package = STIXPackage.from_xml(updated_xml)
    xml.close()
    return stix_package
def main():
    pkg = STIXPackage()
    vuln = Vulnerability()
    vuln.cve_id = "CVE-2013-3893"
    
    et = ExploitTarget(title="Javascript vulnerability in MSIE 6-11")
    et.add_vulnerability(vuln)

    pkg.add_exploit_target(et)
    
    print pkg.to_xml()
Example #26
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
def main():
    maec_malware_instance = MAECInstance()
    maec_malware_instance.add_name("Poison Ivy Variant v4392-acc")
    maec_malware_instance.add_type("Remote Access Trojan")
    maec_malware_instance.maec = etree.fromstring(MAEC_XML, parser=etree.ETCompatXMLParser())

    ttp = TTP(title="Poison Ivy Variant v4392-acc")
    ttp.behavior = Behavior()
    ttp.behavior.add_malware_instance(maec_malware_instance)

    stix_package = STIXPackage()
    stix_package.add_ttp(ttp)

    print(stix_package.to_xml(encoding=None))
def main():
    alpha_package = STIXPackage()
    alpha_package.stix_header = STIXHeader()
    alpha_package.stix_header.title = "Report on Adversary Alpha's Campaign against the Industrial Control Sector"
    alpha_package.stix_header.package_intents = "Campaign Characterization"
    alpha_package.stix_header.handling = Marking()

    alpha_marking = MarkingSpecification()
    alpha_marking.controlled_structure = "../../../../node()"
    alpha_tlp_marking = TLPMarkingStructure()
    alpha_tlp_marking.color = "AMBER"
    alpha_marking.marking_structures.append(alpha_tlp_marking)
    alpha_package.stix_header.handling.add_marking(alpha_marking)

    rat_package = STIXPackage()
    rat_package.stix_header = STIXHeader()
    rat_package.stix_header.title = "Indicators for Malware DrownedRat"
    rat_package.stix_header.package_intents = "Indicators - Malware Artifacts"
    rat_package.stix_header.handling = Marking()

    rat_marking = MarkingSpecification()
    rat_marking.controlled_structure = "../../../../node()"
    rat_tlp_marking = TLPMarkingStructure()
    rat_tlp_marking.color = "RED"
    alpha_marking.marking_structures.append(rat_tlp_marking)
    rat_package.stix_header.handling.add_marking(rat_marking)

    stix_package = STIXPackage()
    info_src = InformationSource()
    info_src.identity = Identity(name="Government Sharing Program - GSP")
    stix_package.stix_header = STIXHeader(information_source=info_src)
    stix_package.related_packages.append(alpha_package)
    stix_package.related_packages.append(rat_package)

    print stix_package.to_xml()
def main():
    stix_package = STIXPackage()
    stix_header = STIXHeader()

    # Add tool information
    stix_header.information_source = InformationSource()
    stix_header.information_source.tools = ToolInformationList()
    stix_header.information_source.tools.append(ToolInformation("python-stix ex_04.py", "The MITRE Corporation"))

    stix_header.description = "Example "
    stix_package.stix_header = stix_header

    print(stix_package.to_xml())
    print(stix_package.to_dict())
Example #30
0
def stix_pkg(config, src, endpoint, payload, title='random test data',
             description='random test data',
             package_intents='Indicators - Watchlist',
             tlp_color='WHITE', dest=None):
    '''package observables'''
    # setup the xmlns...
    xmlns_url = config['edge']['sites'][dest]['stix']['xmlns_url']
    xmlns_name = config['edge']['sites'][dest]['stix']['xmlns_name']
    set_stix_id_namespace({xmlns_url: xmlns_name})
    set_cybox_id_namespace(Namespace(xmlns_url, xmlns_name))
    # construct a stix package...
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = title
    stix_header.description = description
    stix_header.package_intents = package_intents
    marking = MarkingSpecification()
    marking.controlled_structure = '../../../../descendant-or-self::node()'
    tlp_marking = TLPMarkingStructure()
    tlp_marking.color = tlp_color
    marking.marking_structures.append(tlp_marking)
    stix_package.stix_header = stix_header
    stix_package.stix_header.handling = Marking()
    stix_package.stix_header.handling.add_marking(marking)
    if isinstance(payload, Observable):
        stix_package.add_observable(payload)
    elif isinstance(payload, Indicator):
        stix_package.add_indicator(payload)
    elif isinstance(payload, Incident):
        stix_package.add_incident(payload)
    return(stix_package)
Example #31
0
 def test_deprecated_related_packages(self):
     i = Indicator()
     i.related_packages.append(STIXPackage())
     self.assertEqual(len(i.related_packages), 1)
Example #32
0
def gatherIOCs(folderPath, synConn, synackConn, ackConn, resolvedIPs, results, fullHTTPArray, udpconn, dnspacket, icmpPacket, ftpconn, sshconn, foundIPs):
	#print "Gather IOCs"
	stix_package = STIXPackage()
	stix_report = stixReport() 	# need to add indicator references to this
	stix_header_information_source = InformationSource()
	stix_header_information_source.description = "From Cuckoo sandbox IOC_STIX reporting module"	
	stix_report.header = Header()
	stix_report.header.title = "A bunch of related indicators"
	stix_report.header.short_description = "A short description for the indicators oooooh!"
	stix_report.header.information_source = stix_header_information_source
		


# IP address
	for susip in resolvedIPs:
		stix_package.add(susIP(susip))
		stix_report.add_indicator(Indicator(idref=susIP(susip)._id))
	
# IPs found as static strings in the file	
	for IP in foundIPs:
		stix_package.add(susIPfound(IP))
		stix_report.add_indicator(Indicator(idref=susIPfound(IP)._id))

# TCP Connection attempt and Connection established
	for tcp in synConn:
		if tcp not in ackConn:
			#print "tcp: ", tcp		
			stix_package.add(TCPConnectionAttemptFailedObj(tcp))
			stix_report.add_indicator(Indicator(idref=TCPConnectionAttemptFailedObj(tcp)._id))

	for tcpest in synConn:
		if tcpest in synackConn and tcpest in ackConn:
			#print "tcpest: ", tcpest		
			stix_package.add(TCPConnectionEstablishedObj(tcpest))
			stix_report.add_indicator(Indicator(idref=TCPConnectionEstablishedObj(tcpest)._id))

# Full HTTP Request
	for ht in fullHTTPArray:
		#print "ht array part:  ", ht, type(ht)
		stix_package.add(HTTPFullObj(ht))
		stix_report.add_indicator(Indicator(idref=HTTPFullObj(ht)._id))

# UDP Connection
	#print udpconn, type(udpconn)
	for udp in udpconn:
		if udp[0]!='53' and udp[1]!='53': # ignore DNS UDP packets (they are logged else where)
			#print "udp: ", udp		
			stix_package.add(UDPRequestObj(udp))
			stix_report.add_indicator(Indicator(idref=UDPRequestObj(udp)._id))

# DNS Connection
	for dns in dnspacket:
		#print "dns: ", dns		
		stix_package.add(DNSRequestObj(dns))
		stix_report.add_indicator(Indicator(idref=DNSRequestObj(dns)._id))

# ICMP Connection
	for icmp in icmpPacket:
		#print "ICMP: ", icmp
		if icmp[0] == 0 or icmp[0] == 8:
			stix_package.add(ICMPObj(icmp))
			stix_report.add_indicator(Indicator(idref=ICMPObj(icmp)._id))

# FTP Connection
	for ftp in ftpconn:
		#print "FTP: ", ftp
		if ftp[4]=='220' or ftp[4]=='230' or ftp[4]=='250':			
			stix_package.add(FTPObj(ftp))
			stix_report.add_indicator(Indicator(idref=FTPObj(ftp)._id))
		elif ftp[5]=="USER" or ftp[5]=="PASS" or ftp[5]=="STOR" or ftp[5]=="RETR":
			stix_package.add(FTPObj(ftp))
			stix_report.add_indicator(Indicator(idref=FTPObj(ftp)._id))
			

# SSH Connection
	for ssh in sshconn:
		#print "SSH: ", ssh
		stix_package.add(SSHObj(ssh))
		stix_report.add_indicator(Indicator(idref=SSHObj(ssh)._id))

	stix_package.add_report(stix_report)
	#print results["target"]		
	IOCStix = open(folderPath+"/"+str(results["target"]["file"]["name"])+".xml",'w')
	IOCStix.write(stix_package.to_xml())
	IOCStix.close()	
Example #33
0
 def test_deprecated_related_packages(self):
     t = ttp.TTP()
     t.related_packages.append(STIXPackage())
     self.assertEqual(len(t.related_packages), 1)
Example #34
0
 def test_deprecated_related_packages(self):
     c = coa.CourseOfAction()
     c.related_packages.append(STIXPackage())
     self.assertEqual(len(c.related_packages), 1)
Example #35
0
class StixManager(object):
    def __init__(self, threat_name="Generic Threat", threat_descr="Generic Threat", author="Nozomi Networks Labs" , log=True):

        for i in ADDITIONAL_NAMESPACES:
            nsparser.STIX_NAMESPACES.add_namespace(i)
            mixbox.namespaces.register_namespace(i)

        self._pkg = STIXPackage()
        self.set_stix_header(threat_name, threat_descr)
        self._src_file = None
        self.__author = author
        

        self._lookup = set()
        self.__log = log
        
    def _is_ascii(self, value):
        return value.isascii()

    def load_raw_file(self, fname):
        with open(fname, 'r') as f:
            rawdata = f.readlines()

        for line in rawdata:
            ioc = line.strip()
            if len(ioc) > 0:
                res = self.add_raw_indicator(ioc)
                if res is True:
                    if self.__log is True:
                        logging.info("Auto-detected indicator: %s", ioc)
                else:
                    if self.__log is True:
                        logging.warning("Unknown indicator format: %s", ioc)
                self._src_file = fname
        return True

    def save_stix_file(self , file_name):
        try:
            with open(file_name, 'wb') as f:
                f.write(self._pkg.to_xml())
            return True
        except Exception as e:
            if self.__log is True:
                logging.error(e)
            return False

    def set_stix_header(self, threat_name, threat_descr, threat_source=None, reference=None):
        # Create a STIX Package
        hdr = STIXHeader()
        hdr.title =  threat_name
        hdr.add_description(threat_descr)
        hdr.information_source = InformationSource()

        if threat_source is not None:
            hdr.information_source.description = threat_source

        if reference is not None:
            hdr.information_source.references = fields.TypedField(reference, References)

        # Set the produced time to now
        hdr.information_source.time = Time()
        hdr.information_source.time.produced_time = datetime.utcnow()

        self._pkg.stix_header = hdr

    def add_raw_indicator(self , orig_indicator, ts=None):
        indicator_value = orig_indicator
        if not self._is_ascii(indicator_value):
            return False

        indicator_type, _ = guess_type(indicator_value)
        # Create a CyboX File Object
        if indicator_type == StixItemType.IPADDR:
            title = "Malicious IPv4 - %s" % indicator_value
            descr = "Malicious IPv4 involved with %s" % self._pkg.stix_header.title
            cybox = Address(indicator_value , Address.CAT_IPV4)
        elif indicator_type == StixItemType.DOMAIN:
            title = "Malicious domain - %s" % indicator_value
            descr = "Malicious domain involved with %s" % self._pkg.stix_header.title
            cybox = DomainName()
            cybox.value = indicator_value
        elif indicator_type == StixItemType.MD5:
            title = "Malicious MD5 - %s" % indicator_value
            descr = "Malicious MD5 involved with %s" % self._pkg.stix_header.title
            cybox = File()
            cybox.add_hash(indicator_value )
        elif indicator_type == StixItemType.SHA256:
            title = "Malicious SHA256 - %s" % indicator_value
            descr = "Malicious SHA256 involved with %s" % self._pkg.stix_header.title
            cybox = File()
            cybox.add_hash(indicator_value )
        elif indicator_type == StixItemType.SHA1:
            title = "Malicious SHA1 - %s" % indicator_value
            descr = "Malicious SHA1 involved with %s" % self._pkg.stix_header.title
            cybox = File()
            cybox.add_hash(indicator_value )
        elif indicator_type == StixItemType.URL:
            title = "Malicious URL - %s" % indicator_value
            descr = "Malicious URL involved with %s" % self._pkg.stix_header.title
            cybox = URI()
            cybox.value = indicator_value
            cybox.type_ = URI.TYPE_URL

        if indicator_type == StixItemType.UNKNOWN:
            return False

        indicator = Indicator()
        indicator.title = title
        indicator.description = descr
        indicator.add_object(cybox)
        indicator.set_producer_identity(self.__author)
        if ts:
            indicator.set_produced_time(ts)
        else:
            indicator.set_produced_time(utils.dates.now())

        self._add(indicator)
        return True

    def _add(self, indicator):
        ioc = self._parse_indicator(indicator)
        assert len(ioc) == 1, "Multiple observables in a single indicator not supported yet"
        ioc = ioc.pop()

        # Check for duplicates
        if self.is_duplicated(ioc.value):
            if self.__log is True:
                logging.warning("Skipping duplicated indicator: %s", ioc.value)
            return False

        # Update description
        _, type_descr = guess_type(ioc.value)
        indicator.title = "Malicious %s - %s" % (type_descr, ioc.value)
        indicator.description = "Malicious %s involved with the threat %s" % (type_descr, self._pkg.stix_header.title)

        # Update the lookup table
        self._lookup.add(ioc.value)

        self._pkg.add(indicator)
        return True

    def is_duplicated(self, ivalue):
        return ivalue in self._lookup

    def _parse_indicator(self, indicator):
        processed_indicators = set()

        title = indicator.title
        description = indicator.description
        timestamp = indicator.get_produced_time()

        if timestamp:
            timestamp = timestamp.value
        else:
            logging.warning("Failed to get produced time")

        for obj in indicator.observables:
            # Object attributes
            obj_val = None
            obj_type = None

            # Extract the object properties
            obj_prop = obj.to_obj().Object.Properties
            if isinstance(obj_prop, domain_name_object.DomainNameObjectType):
                obj_val = obj_prop.Value.valueOf_
                obj_type = StixItemType.DOMAIN
            elif isinstance(obj_prop, file_object.FileObjectType):
                # TODO: support multiple hashes
                obj_hash = obj_prop.Hashes.get_Hash()[0]
                obj_hash_type = obj_hash.Type.valueOf_.upper()
                if obj_hash_type in ['SHA256', 'SHA1', 'MD5']:
                    obj_val = obj_hash.get_Simple_Hash_Value().valueOf_
                    if obj_hash_type == 'SHA256':
                        obj_type = StixItemType.SHA256
                    elif obj_hash_type == 'SHA1':
                        obj_type = StixItemType.SHA1
                    elif obj_hash_type == 'MD5':
                        obj_type = StixItemType.MD5
                    else:
                        obj_type = StixItemType.UNKNOWN
                else:
                    if self.__log is True:
                        logging.warning("Unsupported hash type: %s" % obj_hash_type)
            elif isinstance(obj_prop, uri_object.URIObjectType):
                obj_val = obj_prop.Value.valueOf_
                obj_type = StixItemType.URL
            elif isinstance(obj_prop, address_object.AddressObjectType):
                obj_val = obj_prop.Address_Value.valueOf_
                obj_type = StixItemType.IPADDR
            else:
                obj_val = indicator
                obj_type = StixItemType.UNKNOWN

            # Strip-out the value
            obj_val = obj_val.strip()

            ioc = StixIndicator(obj_type, obj_val, title, description, timestamp)
            processed_indicators.add(ioc)

        # Return indicators
        return processed_indicators
Example #36
0
from stix.exploit_target.vulnerability import Vulnerability

# Build a Product Object that characterizes our affected software
software = Product()
software.product = "Foobar"
software.version = "3.0"
software.edition = "GOTY"

# Wrap the Product Object in an Observable instance
observable = Observable(software)

# Attach the Product observable to the affected_sofware list of
# RelatedObservable instances. This wraps our Observable in a
# RelatedObservable layer.
vuln = Vulnerability()
vuln.affected_software.append(observable)

# Create the Exploit Target
et = ExploitTarget()

# Attach our Vulnerability to the Exploit Target
et.vulnerabilities.append(vuln)

# Build a STIX Package
package = STIXPackage()

# Attach the Exploit Target instance to the Package
package.exploit_targets.append(et)

# Print!
print package.to_xml()
Example #37
0
 def test_from_xml_default_encoded(self):
     utf8_xml = XML.encode('utf-8')
     sio = BytesIO(utf8_xml)
     sp = STIXPackage.from_xml(sio)
     header = sp.stix_header
     self.assertEqual(header.title, UNICODE_STR)
Example #38
0
    def received(s, content, collection):

        # Hack XML header on.
        package = STIXPackage.from_xml(StringIO.StringIO(content))
        print("Received", package.id_)
Example #39
0
 def test_deprecated_related_packages(self):
     i = incident.Incident()
     i.related_packages.append(STIXPackage())
     self.assertEqual(len(i.related_packages), 1)
Example #40
0
def main():

    data = json.load(open("data.json"))

    stix_package = STIXPackage(stix_header=STIXHeader(
        title=data['title'], package_intents='Incident'))

    ttps = {}

    for info in data['ips']:
        # Add TTP, unless it's already been added
        if info['bot'] not in ttps:
            ttps[info['bot']] = TTP(title=info['bot'])
            stix_package.add_ttp(ttps[info['bot']])

        # Add indicator
        indicator = Indicator(title=info['ip'])
        addr = Address(address_value=info['ip'], category=Address.CAT_IPV4)
        addr.condition = "Equals"
        indicator.add_observable(addr)
        indicator.add_indicated_ttp(TTP(idref=ttps[info['bot']].id_))

        stix_package.add_indicator(indicator)

        # Add incident
        incident = Incident(title=info['ip'])
        incident.time = Time()
        incident.time.first_malicious_action = info['first_seen']

        addr = Address(address_value=info['ip'], category=Address.CAT_IPV4)
        observable = Observable(item=addr)
        stix_package.add_observable(observable)

        related_ttp = RelatedTTP(TTP(idref=ttps[info['bot']].id_),
                                 relationship="Used Malware")
        incident.leveraged_ttps.append(related_ttp)

        related_observable = RelatedObservable(
            Observable(idref=observable.id_))
        incident.related_observables.append(related_observable)

        related_indicator = RelatedIndicator(Indicator(idref=indicator.id_))
        incident.related_indicators.append(related_indicator)

        stix_package.add_incident(incident)

    print stix_package.to_xml()
 def test_parsing_maec_fails(self):
     try:
         STIXPackage.from_xml(PythonMAECInPackageTests.XML_MAEC)
     except ImportError as e:
         self.assertTrue(all(x in str(e) for x in ("No module named", "maec")))
 def test_parse_malware_maec(self):
     """Test parsing a MaecInstance from XML
     """
     stix_pkg = STIXPackage.from_xml(self.XML_MAEC)
     mw = stix_pkg.ttps.ttp[0].behavior.malware_instances[0].to_dict()
     self.assertTrue('names' in mw)
Example #43
0
        print("Confidence: " + str(ind.confidence.value))

        # look up ttp from list in package
        for ref_ttp in ind.indicated_ttps:
            print("TTP: " + str(pkg.find(ref_ttp.item.idref).title))

        for obs in ind.observables:
            if obs.object_.related_objects:
                #  attachment is inline
                print("Attachment ID: " + str(obs.object_.id_))
                print("Attachment Filename: " + str(obs.object_.related_objects[0].properties.file_name))
                print("Attachment File extension: " + str(obs.object_.related_objects[0].properties.file_extension))
                print("Relationship: " + str(obs.object_.related_objects[0].relationship))
            elif obs.object_.properties.header:
                print("Subject : " + str(obs.object_.properties.header.subject))
                if obs.object_.properties.attachments:
                    print("Attachment -> : " + str(obs.object_.properties.attachments[0].object_reference))

    return 0

if __name__ == '__main__':
    try:
        fname = sys.argv[1]
    except:
        exit(1)
    fd = open(fname)
    stix_pkg = STIXPackage.from_xml(fd)

    parse_stix(stix_pkg)
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 = raw_input("Insert Title Ioc:")

    # La description strutturiamola come segue
    # <IOC PRODUCER> - <Descrizione della minaccia/campagna> - <URL (if any)>
    DESCRIPTION = raw_input("Insert Decription:")

    # La sorgente che ha generato l'IoC con riferimento a Cyber Saiyan Community
    IDENTITY = raw_input("Insert User Identity:")

    # File degli IoC
    IOCFILE = raw_input("Add IoC Source File:")

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

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

    VERBOSE = 0

    # UTF8 encode
    TITLE = TITLE.encode('utf8')
    DESCRIPTION = DESCRIPTION.encode('utf8')
    IDENTITY = IDENTITY.encode('utf8')

    print "\nStix File generation in progress...."
    #print (TITLE) #"TITLE: " + TITLE
    #print (DESCRIPTION) #"DESCRIPTION: " + DESCRIPTION
    #print (IDENTITY) #"IDENTITY: " + IDENTITY
    #print (IOCFILE) #"IOC FILE: " + IOCFILE
    #print "---------------------"

    ########################
    # Commond data
    timestamp = datetime.datetime.fromtimestamp(
        time.time()).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)

    # 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.MarkingDefinition(definition_type="tlp",
                                                definition={"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
    ioc = loaddata(IOCFILE)

    if (VERBOSE): print "Reading IoC file " + IOCFILE + "..."
    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:
            # STIX 1.2
            filei = File()
            filei.add_hash(Hash(ioc))

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

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

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

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

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

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

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

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

        #domains
        if validators.domain(ioc) and notfound:
            # 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
            notfound = 0

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

        #url
        if validators.url(ioc) and notfound:
            # 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
            notfound = 0

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

        #ip
        if validators.ipv4(ioc) and notfound:
            # STIX 1.2
            ip = Address()
            ip.address_value = ioc

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

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

        #email
        if validators.email(ioc) and notfound:
            # STIX 1.2
            email = EmailAddress()
            email.address_value = ioc

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

            if (VERBOSE): print "Email: " + ioc
            notfound = 0

            # STIX 2
            pattern_email.append("[email-message:from_ref.value = '" + ioc +
                                 "'] 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
    bundle = stix2.Bundle(objects=bundle_objects)

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

    ########################
    # save to STIX 2 file
    print "Writing STIX 2 package: " + OUTFILEPREFIX + ".stix2"
    g = open(OUTFILEPREFIX + ".stix2", "w")
    sys.stdout = g
    print bundle
Example #45
0
    def transform(self, event):
        stix_package = STIXPackage()
        self._add_header(stix_package, "Unauthorized traffic to honeypot",
                         "Describes one or more honeypot incidents")

        incident = Incident(
            id_="%s:%s-%s" %
            (CONPOT_NAMESPACE, 'incident', event['session_id']))
        initial_time = StixTime()
        initial_time.initial_compromise = event['timestamp'].isoformat()
        incident.time = initial_time
        incident.title = "Conpot Event"
        incident.short_description = "Traffic to Conpot ICS honeypot"
        incident.add_category(
            VocabString(value='Scans/Probes/Attempted Access'))

        tool_list = ToolInformationList()
        tool_list.append(
            ToolInformation.from_dict({
                'name':
                "Conpot",
                'vendor':
                "Conpot Team",
                'version':
                conpot.__version__,
                'description':
                textwrap.dedent(
                    'Conpot is a low interactive server side Industrial Control Systems '
                    'honeypot designed to be easy to deploy, modify and extend.'
                )
            }))
        incident.reporter = InformationSource(tools=tool_list)

        incident.add_discovery_method("Monitoring Service")
        incident.confidence = "High"

        # Victim Targeting by Sector
        ciq_identity = CIQIdentity3_0Instance()
        #identity_spec = STIXCIQIdentity3_0()
        #identity_spec.organisation_info = OrganisationInfo(industry_type="Electricity, Industrial Control Systems")
        #ciq_identity.specification = identity_spec
        ttp = TTP(
            title=
            "Victim Targeting: Electricity Sector and Industrial Control System Sector"
        )
        ttp.victim_targeting = VictimTargeting()
        ttp.victim_targeting.identity = ciq_identity

        incident.leveraged_ttps.append(ttp)

        indicator = Indicator(title="Conpot Event")
        indicator.description = "Conpot network event"
        indicator.confidence = "High"
        source_port = Port.from_dict({
            'port_value': event['remote'][1],
            'layer4_protocol': 'tcp'
        })
        dest_port = Port.from_dict({
            'port_value':
            self.protocol_to_port_mapping[event['data_type']],
            'layer4_protocol':
            'tcp'
        })
        source_ip = Address.from_dict({
            'address_value': event['remote'][0],
            'category': Address.CAT_IPV4
        })
        dest_ip = Address.from_dict({
            'address_value': event['public_ip'],
            'category': Address.CAT_IPV4
        })
        source_address = SocketAddress.from_dict({
            'ip_address':
            source_ip.to_dict(),
            'port':
            source_port.to_dict()
        })
        dest_address = SocketAddress.from_dict({
            'ip_address': dest_ip.to_dict(),
            'port': dest_port.to_dict()
        })
        network_connection = NetworkConnection.from_dict({
            'source_socket_address':
            source_address.to_dict(),
            'destination_socket_address':
            dest_address.to_dict(),
            'layer3_protocol':
            u"IPv4",
            'layer4_protocol':
            u"TCP",
            'layer7_protocol':
            event['data_type'],
            'source_tcp_state':
            u"ESTABLISHED",
            'destination_tcp_state':
            u"ESTABLISHED",
        })
        indicator.add_observable(Observable(network_connection))

        artifact = Artifact()
        artifact.data = json.dumps(event['data'])
        artifact.packaging.append(ZlibCompression())
        artifact.packaging.append(Base64Encoding())
        indicator.add_observable(Observable(artifact))

        incident.related_indicators.append(indicator)
        stix_package.add_incident(incident)

        stix_package_xml = stix_package.to_xml()
        return stix_package_xml
Example #46
0
"""


# Create a VocabString class for our CustomVocab-1.0 vocabular
class CustomVocab(vocabs.VocabString):
    _namespace = 'http://customvocabs.com/vocabs-1'
    _XSI_TYPE = 'customVocabs:CustomVocab-1.0'
    _ALLOWED_VALUES = ('FOO', 'BAR')


# Register our Custom Vocabulary class so parsing and serialization works
vocabs.add_vocab(CustomVocab)

# Parse the input document
sio = StringIO(XML)
package = STIXPackage.from_xml(sio)

# Retrieve the first (and only) Package_Intent entry
package_intent = package.stix_header.package_intents[0]

# Print information about the input Package_Intent
print type(package_intent), package_intent.xsi_type, package_intent

# Add another Package Intent
bar = CustomVocab('BAR')
package.stix_header.add_package_intent(bar)

schemalocs = {'http://customvocabs.com/vocabs-1': '/path/to/customVocabs.xsd'}

# This will include the 'BAR' CustomVocab entry
print package.to_xml(schemaloc_dict=schemalocs)
Example #47
0
 def test_from_xml_utf16_encoded(self):
     utf16_xml = XML.encode('utf-16')
     sio = BytesIO(utf16_xml)
     sp = STIXPackage.from_xml(sio, encoding='utf-16')
     header = sp.stix_header
     self.assertEqual(header.title, UNICODE_STR)
Example #48
0
def stix_framing(*args):
    import datetime, re
    from stix.core import STIXPackage, STIXHeader
    from cybox.utils import Namespace
    # As python3 is forced anyway, mixbox is used and we don't need to try to import idgen from stix.utils
    from mixbox import idgen
    from stix import __version__ as STIXVER
    NS_DICT = {
        "http://cybox.mitre.org/common-2": 'cyboxCommon',
        "http://cybox.mitre.org/cybox-2": 'cybox',
        "http://cybox.mitre.org/default_vocabularies-2": 'cyboxVocabs',
        "http://cybox.mitre.org/objects#AccountObject-2": 'AccountObj',
        "http://cybox.mitre.org/objects#ArtifactObject-2": 'ArtifactObj',
        "http://cybox.mitre.org/objects#ASObject-1": 'ASObj',
        "http://cybox.mitre.org/objects#AddressObject-2": 'AddressObj',
        "http://cybox.mitre.org/objects#PortObject-2": 'PortObj',
        "http://cybox.mitre.org/objects#DomainNameObject-1": 'DomainNameObj',
        "http://cybox.mitre.org/objects#EmailMessageObject-2":
        'EmailMessageObj',
        "http://cybox.mitre.org/objects#FileObject-2": 'FileObj',
        "http://cybox.mitre.org/objects#HTTPSessionObject-2": 'HTTPSessionObj',
        "http://cybox.mitre.org/objects#HostnameObject-1": 'HostnameObj',
        "http://cybox.mitre.org/objects#MutexObject-2": 'MutexObj',
        "http://cybox.mitre.org/objects#PipeObject-2": 'PipeObj',
        "http://cybox.mitre.org/objects#URIObject-2": 'URIObj',
        "http://cybox.mitre.org/objects#WinRegistryKeyObject-2":
        'WinRegistryKeyObj',
        'http://cybox.mitre.org/objects#WinServiceObject-2': 'WinServiceObj',
        "http://cybox.mitre.org/objects#NetworkConnectionObject-2":
        'NetworkConnectionObj',
        "http://cybox.mitre.org/objects#NetworkSocketObject-2":
        'NetworkSocketObj',
        "http://cybox.mitre.org/objects#SocketAddressObject-1":
        'SocketAddressObj',
        "http://cybox.mitre.org/objects#SystemObject-2": 'SystemObj',
        "http://cybox.mitre.org/objects#ProcessObject-2": 'ProcessObj',
        "http://cybox.mitre.org/objects#X509CertificateObject-2":
        'X509CertificateObj',
        "http://cybox.mitre.org/objects#WhoisObject-2": 'WhoisObj',
        "http://cybox.mitre.org/objects#WinExecutableFileObject-2":
        'WinExecutableFileObj',
        "http://cybox.mitre.org/objects#UnixUserAccountObject-2":
        "UnixUserAccountObj",
        "http://cybox.mitre.org/objects#UserAccountObject-2": "UserAccountObj",
        "http://cybox.mitre.org/objects#WinUserAccountObject-2":
        "WinUserAccountObj",
        "http://data-marking.mitre.org/Marking-1": 'marking',
        "http://data-marking.mitre.org/extensions/MarkingStructure#TLP-1":
        'tlpMarking',
        "http://stix.mitre.org/ExploitTarget-1": 'et',
        "http://stix.mitre.org/Incident-1": 'incident',
        "http://stix.mitre.org/Indicator-2": 'indicator',
        "http://stix.mitre.org/CourseOfAction-1": 'coa',
        "http://stix.mitre.org/TTP-1": 'ttp',
        "http://stix.mitre.org/ThreatActor-1": 'ta',
        "http://stix.mitre.org/common-1": 'stixCommon',
        "http://stix.mitre.org/default_vocabularies-1": 'stixVocabs',
        "http://stix.mitre.org/extensions/Identity#CIQIdentity3.0-1":
        'ciqIdentity',
        "http://stix.mitre.org/extensions/TestMechanism#Snort-1": 'snortTM',
        "http://stix.mitre.org/stix-1": 'stix',
        "http://www.w3.org/2001/XMLSchema-instance": 'xsi',
        "urn:oasis:names:tc:ciq:xal:3": 'xal',
        "urn:oasis:names:tc:ciq:xnl:3": 'xnl',
        "urn:oasis:names:tc:ciq:xpil:3": 'xpil',
    }
    SCHEMALOC_DICT = {
        'http://cybox.mitre.org/common-2':
        'http://cybox.mitre.org/XMLSchema/common/2.1/cybox_common.xsd',
        'http://cybox.mitre.org/cybox-2':
        'http://cybox.mitre.org/XMLSchema/core/2.1/cybox_core.xsd',
        'http://cybox.mitre.org/default_vocabularies-2':
        'http://cybox.mitre.org/XMLSchema/default_vocabularies/2.1/cybox_default_vocabularies.xsd',
        'http://cybox.mitre.org/objects#AccountObject-2':
        ' http://cybox.mitre.org/XMLSchema/objects/Account/2.1/Account_Object.xsd',
        'http://cybox.mitre.org/objects#ArtifactObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Artifact/2.1/Artifact_Object.xsd',
        'http://cybox.mitre.org/objects#ASObject-1':
        'http://cybox.mitre.org/XMLSchema/objects/AS/1.0/AS_Object.xsd',
        'http://cybox.mitre.org/objects#AddressObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Address/2.1/Address_Object.xsd',
        'http://cybox.mitre.org/objects#PortObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Port/2.1/Port_Object.xsd',
        'http://cybox.mitre.org/objects#DomainNameObject-1':
        'http://cybox.mitre.org/XMLSchema/objects/Domain_Name/1.0/Domain_Name_Object.xsd',
        'http://cybox.mitre.org/objects#EmailMessageObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Email_Message/2.1/Email_Message_Object.xsd',
        'http://cybox.mitre.org/objects#FileObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/File/2.1/File_Object.xsd',
        'http://cybox.mitre.org/objects#HTTPSessionObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/HTTP_Session/2.1/HTTP_Session_Object.xsd',
        'http://cybox.mitre.org/objects#HostnameObject-1':
        'http://cybox.mitre.org/XMLSchema/objects/Hostname/1.0/Hostname_Object.xsd',
        'http://cybox.mitre.org/objects#MutexObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Mutex/2.1/Mutex_Object.xsd',
        'http://cybox.mitre.org/objects#PipeObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Pipe/2.1/Pipe_Object.xsd',
        'http://cybox.mitre.org/objects#URIObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/URI/2.1/URI_Object.xsd',
        'http://cybox.mitre.org/objects#WinServiceObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Win_Service/2.1/Win_Service_Object.xsd',
        'http://cybox.mitre.org/objects#WinRegistryKeyObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Win_Registry_Key/2.1/Win_Registry_Key_Object.xsd',
        'http://cybox.mitre.org/objects#NetworkConnectionObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Network_Connection/2.0.1/Network_Connection_Object.xsd',
        'http://cybox.mitre.org/objects#NetworkSocketObject-2':
        'https://cybox.mitre.org/XMLSchema/objects/Network_Socket/2.1/Network_Socket_Object.xsd',
        'http://cybox.mitre.org/objects#SystemObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/System/2.1/System_Object.xsd',
        'http://cybox.mitre.org/objects#SocketAddressObject-1':
        'http://cybox.mitre.org/XMLSchema/objects/Socket_Address/1.1/Socket_Address_Object.xsd',
        'http://cybox.mitre.org/objects#ProcessObject-2':
        'https://cybox.mitre.org/XMLSchema/objects/Process/2.1/Process_Object.xsd',
        'http://cybox.mitre.org/objects#X509CertificateObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/X509_Certificate/2.1/X509_Certificate_Object.xsd',
        'http://cybox.mitre.org/objects#WhoisObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Whois/2.1/Whois_Object.xsd',
        'http://cybox.mitre.org/objects#WinExecutableFileObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Win_Executable_File/2.1/Win_Executable_File_Object.xsd',
        'http://cybox.mitre.org/objects#UnixUserAccountObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Unix_User_Account/2.1/Unix_User_Account_Object.xsd',
        'http://cybox.mitre.org/objects#UserAccountObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/User_Account/2.1/User_Account_Object.xsd',
        'http://cybox.mitre.org/objects#WinUserAccountObject-2':
        'http://cybox.mitre.org/XMLSchema/objects/Win_User_Account/2.1/Win_User_Account_Object.xsd',
        'http://data-marking.mitre.org/Marking-1':
        'http://stix.mitre.org/XMLSchema/data_marking/1.1.1/data_marking.xsd',
        'http://data-marking.mitre.org/extensions/MarkingStructure#TLP-1':
        'http://stix.mitre.org/XMLSchema/extensions/marking/tlp/1.1.1/tlp_marking.xsd',
        'http://stix.mitre.org/ExploitTarget-1':
        'http://stix.mitre.org/XMLSchema/exploit_target/1.1.1/exploit_target.xsd',
        'http://stix.mitre.org/Incident-1':
        'http://stix.mitre.org/XMLSchema/incident/1.1.1/incident.xsd',
        'http://stix.mitre.org/Indicator-2':
        'http://stix.mitre.org/XMLSchema/indicator/2.1.1/indicator.xsd',
        'http://stix.mitre.org/CourseOfAction-1':
        'http://stix.mitre.org/XMLSchema/course_of_action/1.1.1/course_of_action.xsd',
        'http://stix.mitre.org/TTP-1':
        'http://stix.mitre.org/XMLSchema/ttp/1.1.1/ttp.xsd',
        'http://stix.mitre.org/ThreatActor-1':
        'http://stix.mitre.org/XMLSchema/threat_actor/1.1.1/threat_actor.xsd',
        'http://stix.mitre.org/common-1':
        'http://stix.mitre.org/XMLSchema/common/1.1.1/stix_common.xsd',
        'http://stix.mitre.org/default_vocabularies-1':
        'http://stix.mitre.org/XMLSchema/default_vocabularies/1.1.1/stix_default_vocabularies.xsd',
        'http://stix.mitre.org/extensions/Identity#CIQIdentity3.0-1':
        'http://stix.mitre.org/XMLSchema/extensions/identity/ciq_3.0/1.1.1/ciq_3.0_identity.xsd',
        'http://stix.mitre.org/extensions/TestMechanism#Snort-1':
        'http://stix.mitre.org/XMLSchema/extensions/test_mechanism/snort/1.1.1/snort_test_mechanism.xsd',
        'http://stix.mitre.org/stix-1':
        'http://stix.mitre.org/XMLSchema/core/1.1.1/stix_core.xsd',
        'urn:oasis:names:tc:ciq:xal:3':
        'http://stix.mitre.org/XMLSchema/external/oasis_ciq_3.0/xAL.xsd',
        'urn:oasis:names:tc:ciq:xnl:3':
        'http://stix.mitre.org/XMLSchema/external/oasis_ciq_3.0/xNL.xsd',
        'urn:oasis:names:tc:ciq:xpil:3':
        'http://stix.mitre.org/XMLSchema/external/oasis_ciq_3.0/xPIL.xsd',
    }

    baseurl, orgname, return_type = args
    if not baseurl:
        baseurl = 'https://www.misp-project.org'
    real_orgname = args[1]
    orgname = re.sub('[\W]+', '', orgname.replace(" ", "_"))
    NS_DICT[baseurl] = orgname
    try:
        idgen.set_id_namespace(Namespace(baseurl, orgname))
    except TypeError:
        idgen.set_id_namespace(Namespace(baseurl, orgname, "MISP"))
    stix_package = STIXPackage()
    stix_header = STIXHeader()
    stix_header.title = "Export from {} MISP".format(real_orgname)
    stix_header.package_intents = "Threat Report"
    stix_package.stix_header = stix_header
    stix_package.version = "1.1.1"
    stix_package.timestamp = datetime.datetime.now()
    return stix_json_framing(
        stix_package) if return_type == 'json' else stix_xml_framing(
            stix_package, NS_DICT, SCHEMALOC_DICT)
Example #49
0
    def _import_collection(self, client, site, collection, data_set=False):

        collection_name = collection.name
        sanitized_feed_name = cleanup_string(
            "%s%s" % (site.get('site'), collection_name))
        feed_summary = "%s %s" % (site.get('site'), collection_name)
        available = collection.available
        collection_type = collection.type
        default_score = site.get('default_score')
        logger.info("%s,%s,%s,%s,%s" %
                    (site.get('site'), collection_name, sanitized_feed_name,
                     available, collection_type))

        if not available:
            return False

        #
        # Sanity check on start date
        #
        start_date_str = site.get('start_date')
        if not start_date_str or len(start_date_str) == 0:
            start_date_str = "2019-01-01 00:00:00"

        #
        # Create a feed helper object
        #
        feed_helper = FeedHelper(site.get('output_path'), sanitized_feed_name,
                                 site.get('minutes_to_advance'),
                                 start_date_str)

        if not data_set:
            logger.info("Feed start time %s" % feed_helper.start_date)
        logger.info("polling Collection: {}...".format(collection.name))

        #
        # Build up the URI for polling
        #

        if not site.get('poll_path', ''):
            uri = None
        else:
            uri = ''
            if site.get('use_https'):
                uri += 'https://'
            else:
                uri += 'http://'

            uri += site.get('site')
            uri += site.get('poll_path')
            logger.info('Poll path: {}'.format(uri))

        reports = []
        while True:
            num_times_empty_content_blocks = 0
            try:
                try:
                    logger.info("Polling Collection: {0}".format(
                        collection.name))
                    content_blocks = client.poll(
                        uri=uri,
                        collection_name=collection.name,
                        begin_date=feed_helper.start_date,
                        end_date=feed_helper.end_date,
                        content_bindings=BINDING_CHOICES)

                except Exception as e:
                    logger.info(e.message)
                    content_blocks = []

                #
                # Iterate through all content_blocks
                #
                num_blocks = 0

                if not data_set:
                    logger.info("polling start_date: {}, end_date: {}".format(
                        feed_helper.start_date, feed_helper.end_date))
                for block in content_blocks:
                    logger.debug(block.content)

                    #
                    # if in export mode then save off this content block
                    #
                    if self.export_dir:
                        self.export_xml(collection_name,
                                        feed_helper.start_date,
                                        feed_helper.end_date, num_blocks,
                                        block.content)

                    #
                    # This code accounts for a case found with ThreatCentral.io where the content is url encoded.
                    # etree.fromstring can parse this data.
                    #
                    try:
                        root = etree.fromstring(block.content)
                        content = root.find(
                            './/{http://taxii.mitre.org/messages/taxii_xml_binding-1.1}Content'
                        )
                        if content is not None and len(content) == 0 and len(
                                list(content)) == 0:
                            #
                            # Content has no children.  So lets make sure we parse the xml text for content and re-add
                            # it as valid XML so we can parse
                            #
                            new_stix_package = etree.fromstring(
                                root.find(
                                    "{http://taxii.mitre.org/messages/taxii_xml_binding-1.1}Content_Block/{http://taxii.mitre.org/messages/taxii_xml_binding-1.1}Content"
                                ).text)
                            content.append(new_stix_package)

                        #
                        # Since we modified the xml, we need create a new xml message string to parse
                        #
                        message = etree.tostring(root)

                        #
                        # Write the content block to disk so we can parse with python stix
                        #
                        file_handle, file_path = self.write_to_temp_file(
                            message)

                        #
                        # Parse STIX data
                        #
                        stix_package = STIXPackage.from_xml(file_path)

                        #
                        # if it is a DATA_SET make feed_summary from the stix_header description
                        # NOTE: this is for RecordedFuture, also note that we only do this for data_sets.
                        #       to date I have only seen RecordedFuture use data_sets
                        #
                        if data_set and stix_package.stix_header and stix_package.stix_header.descriptions:
                            for desc in stix_package.stix_header.descriptions:
                                feed_summary = "{}: {}".format(
                                    desc.value, collection_name)
                                break

                        #
                        # Get the timestamp of the STIX Package so we can use this in our feed
                        #
                        timestamp = total_seconds(stix_package.timestamp)

                        if not stix_package.indicators and not stix_package.observables:
                            num_times_empty_content_blocks += 1
                            if num_times_empty_content_blocks > 10:
                                break

                        if stix_package.indicators:
                            for indicator in stix_package.indicators:

                                if not indicator or not indicator.observable:
                                    continue

                                if indicator.confidence:

                                    if str(indicator.confidence.value).isdigit(
                                    ):
                                        #
                                        # Get the confidence score and use it for our score
                                        #
                                        score = int(
                                            indicator.confidence.to_dict().get(
                                                "value", default_score))
                                    else:
                                        if str(indicator.confidence.value
                                               ).lower() == "high":
                                            score = 75
                                        elif str(indicator.confidence.value
                                                 ).lower() == "medium":
                                            score = 50
                                        elif str(indicator.confidence.value
                                                 ).lower() == "low":
                                            score = 25
                                        else:
                                            score = default_score
                                else:
                                    score = default_score

                                if not indicator.timestamp:
                                    timestamp = 0
                                else:
                                    timestamp = int(
                                        (indicator.timestamp -
                                         datetime.datetime(1970, 1, 1).replace(
                                             tzinfo=dateutil.tz.tzutc())
                                         ).total_seconds())

                                reports.extend(
                                    cybox_parse_observable(
                                        indicator.observable, indicator,
                                        timestamp, score))

                        #
                        # Now lets find some data.  Iterate through all observables and parse
                        #
                        if stix_package.observables:
                            for observable in stix_package.observables:
                                if not observable:
                                    continue
                                #
                                # Cybox observable returns a list
                                #
                                reports.extend(
                                    cybox_parse_observable(
                                        observable, None, timestamp,
                                        default_score))

                        #
                        # Delete our temporary file
                        #
                        file_handle.close()

                        num_blocks += 1

                        #
                        # end for loop through content blocks
                        #

                    except Exception as e:
                        # logger.info(traceback.format_exc())
                        logger.info(e.message)
                        continue

                logger.info("content blocks read: {}".format(num_blocks))
                logger.info("current number of reports: {}".format(
                    len(reports)))

                if len(reports) > site.get('reports_limit'):
                    logger.info(
                        "We have reached the reports limit of {0}".format(
                            site.get('reports_limit')))
                    break
                #
                # DEBUG CODE
                #
                # if len(reports) > 10:
                #    break

                #
                # Attempt to advance the start time and end time
                #

            except Exception as e:
                logger.info(traceback.format_exc())

            #
            # If it is just a data_set, the data is unordered, so we can just break out of the while loop
            #
            if data_set:
                break

            if feed_helper.advance():
                continue
            else:
                break
            #
            # end While True
            #

        logger.info("Found {} new reports.".format(len(reports)))

        if not data_set:
            #
            # We only want to concatenate if we are NOT a data set, otherwise we want to refresh all the reports
            #
            logger.info("Adding existing reports...")
            reports = feed_helper.load_existing_feed_data() + reports

        logger.info("Total number of reports: {}".format(len(reports)))

        if site.get('reports_limit') < len(reports):
            logger.info("Truncating reports to length {0}".format(
                site.get('reports_limit')))
            reports = reports[:site.get('reports_limit')]

        data = build_feed_data(sanitized_feed_name,
                               "%s %s" % (site.get('site'), collection_name),
                               feed_summary, site.get('site'),
                               site.get('icon_link'), reports)

        if feed_helper.write_feed(data):
            feed_helper.save_details()

        #
        # Create Cb Response Feed if necessary
        #

        feed_id = None

        try:
            feeds = get_object_by_name_or_id(self.cb,
                                             Feed,
                                             name=sanitized_feed_name)

            if not feeds:
                logger.info(
                    "Feed {} was not found, so we are going to create it".
                    format(sanitized_feed_name))

            elif len(feeds) > 1:
                logger.warning(
                    "Multiple feeds found, selecting Feed id {}".format(
                        feeds[0].id))
                feed_id = feeds[0].id

            elif feeds:
                feed_id = feeds[0].id
                logger.info("Feed {} was found as Feed ID {}".format(
                    sanitized_feed_name, feed_id))

        except Exception as e:
            logger.info(e.message)

        if not feed_id:
            logger.info("Creating {} feed for the first time".format(
                sanitized_feed_name))

            f = self.cb.create(Feed)
            f.feed_url = "file://" + feed_helper.path
            f.enabled = site.get('feeds_enable')
            f.use_proxy = False
            f.validate_server_cert = False
            try:
                f.save()
            except ServerError as se:
                if se.error_code == 500:
                    logger.info("Could not add feed:")
                    logger.info(
                        " Received error code 500 from server. This is usually because the server cannot retrieve the feed."
                    )
                    logger.info(
                        " Check to ensure the Cb server has network connectivity and the credentials are correct."
                    )
                else:
                    logger.info("Could not add feed: {0:s}".format(str(se)))
            except Exception as e:
                logger.info("Could not add feed: {0:s}".format(str(e)))
            else:
                logger.info("Feed data: {0:s}".format(str(f)))
                logger.info("Added feed. New feed ID is {0:d}".format(f.id))
                feed_id = f.id

        return feed_id
Example #50
0
    def test_deprecated_warning(self):
        from stix.core import STIXPackage

        l = RelatedPackageRefs()
        l.append(STIXPackage())
Example #51
0
def main():
    stix_pkg = STIXPackage()

    # create LM-style kill chain
    # REF: http://stix.mitre.org/language/version{{site.current_version}}/stix_v{{site.current_version}}_lmco_killchain.xml

    recon = KillChainPhase(
        phase_id="stix:TTP-af1016d6-a744-4ed7-ac91-00fe2272185a",
        name="Reconnaissance",
        ordinality="1")
    weapon = KillChainPhase(
        phase_id="stix:TTP-445b4827-3cca-42bd-8421-f2e947133c16",
        name="Weaponization",
        ordinality="2")
    deliver = KillChainPhase(
        phase_id="stix:TTP-79a0e041-9d5f-49bb-ada4-8322622b162d",
        name="Delivery",
        ordinality="3")
    exploit = KillChainPhase(
        phase_id="stix:TTP-f706e4e7-53d8-44ef-967f-81535c9db7d0",
        name="Exploitation",
        ordinality="4")
    install = KillChainPhase(
        phase_id="stix:TTP-e1e4e3f7-be3b-4b39-b80a-a593cfd99a4f",
        name="Installation",
        ordinality="5")
    control = KillChainPhase(
        phase_id="stix:TTP-d6dc32b9-2538-4951-8733-3cb9ef1daae2",
        name="Command and Control",
        ordinality="6")
    action = KillChainPhase(
        phase_id="stix:TTP-786ca8f9-2d9a-4213-b38e-399af4a2e5d6",
        name="Actions on Objectives",
        ordinality="7")

    lmchain = KillChain(id_="stix:TTP-af3e707f-2fb9-49e5-8c37-14026ca0a5ff",
                        name="LM Cyber Kill Chain")
    lmchain.definer = "LMCO"

    lmchain.kill_chain_phases = [
        recon, weapon, deliver, exploit, install, control, action
    ]
    stix_pkg.ttps.kill_chains.append(lmchain)

    infect = KillChainPhase(name="Infect Machine")
    exfil = KillChainPhase(name="Exfiltrate Data")

    mychain = KillChain(name="Organization-specific Kill Chain")
    mychain.definer = "Myself"

    mychain.kill_chain_phases = [infect, exfil]
    stix_pkg.ttps.kill_chains.append(mychain)

    indicator = Indicator()
    indicator.kill_chain_phases = KillChainPhasesReference([
        KillChainPhaseReference(phase_id=exfil.phase_id,
                                kill_chain_id=mychain.id_),
        KillChainPhaseReference(phase_id=action.phase_id,
                                kill_chain_id=lmchain.id_)
    ])
    stix_pkg.add_indicator(indicator)

    print stix_pkg.to_xml()
def main():
    mydata = loaddata()

    #    NAMESPACE = {sanitizer(mydata["NSXURL"]) : sanitizer(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["filename"]) + ": " + sanitizer(
        mydata["hashes"]["md5"])
    ShortDescription = timestamp

    DESCRIPTION = "STIX Report for: " + sanitizer(
        mydata["filename"]) + " - " + sanitizer(mydata["hashes"]["md5"])

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

    fileobj = File()
    fileobj.file_name = sanitizer(mydata["filename"])
    fileobj.file_format = sanitizer(mydata["file_type"])
    fileobj.size_in_bytes = sanitizer(mydata["file_size"])
    fileobj.add_hash(Hash(sanitizer(mydata["hashes"]["md5"])))
    fileobj.add_hash(Hash(sanitizer(mydata["hashes"]["sha1"])))
    fileobj.add_hash(Hash(sanitizer(mydata["hashes"]["sha256"])))

    observable = Observable(fileobj)

    if "URL_file_hosting" in mydata:
        for idx, mydata["URL_file_hosting"] in enumerate(
                mydata["URL_file_hosting"]):
            url = URI()
            url.value = sanitizer(mydata["URL_file_hosting"])
            url.type_ = URI.TYPE_URL
            url.condition = "Equals"

            fileobj.add_related(url, "Downloaded_From")

    indicator = Indicator()
    indicator.title = MyTITLE
    indicator.add_indicator_type("File Hash Watchlist")
    indicator.add_observable(observable)

    wrapper.add_indicator(indicator)
    print(wrapper.to_xml())
from stix.core import STIXPackage
from stix.incident import Incident
from stix.common import InformationSource
from cybox.common import Time
from datetime import datetime
from stix.common import Identity
from stix.incident import Time as incidentTime  # different type than common:Time
from stix.incident import Incident, ImpactAssessment
from stix.incident.impact_assessment import Effects
from stix.common import References

# setup stix document
stix_package = STIXPackage()

# add incident and confidence
breach = Incident()
breach.description = "Parity Wallet Hacked"
breach.confidence = "High"  # investigators were able to thoroughly validate the incident, Low means not yet validated

# stamp with reporter
breach.reporter = InformationSource()
breach.reporter.description = "https://paritytech.io/blog/security-alert.html"

breach.reporter.time = Time()
breach.reporter.time.produced_time = datetime.strptime(
    "2017-11-08", "%Y-%m-%d")  # when they submitted it

breach.reporter.identity = Identity()
breach.reporter.identity.name = "parity technologies ltd"

# set incident-specific timestamps
Example #54
0
def process_cases(misp, case_list):
    for case_id in case_list:
        LOGGER.info('Fetching case: {0}'.format(case_id))

        case_url = 'https://api.xforce.ibmcloud.com/casefiles/{0}/stix'.format(case_id)
        response = requests.get(case_url, headers=get_api_headers())

        if not response.status_code == 200:
            LOGGER.info('Failed to get case. Status code: {0}'.format(response.status_code))
            continue

        LOGGER.info('Case request OK!')

        stix_xml = StringIO(response.text)
        stix_package = STIXPackage.from_xml(stix_xml)
        stix_xml.close()

        title = stix_package.stix_header.title
        author = stix_package.stix_header.information_source.contributing_sources[0].identity.name

        LOGGER.info('New case from {0}: {1}'.format(author, title))

        if not stix_package.observables:
            LOGGER.warning('Case does not have any recorded observables. Skipping...')
            continue

        event = False
        event_search = misp.search_index(eventinfo=title)

        if not event_search == []:
            for result in event_search:
                if result['info'] == title:
                    event = event_search[0]

        if event:
            LOGGER.warning('Event already exists. Will only update attributes.')

        else:
            event = make_new_event(misp, stix_package)

        if not event:
            LOGGER.warning('Failed to make or retrieve event.')
            continue

        observables = stix_package.observables.observables
        LOGGER.info('Processing {0} observables...'.format(len(observables)))

        for observable in observables:
            attribute_value = None

            if hasattr(observable.object_.properties, 'hashes'):
                if observable.object_.properties.hashes.sha256:
                    attribute_value = str(observable.object_.properties.hashes.sha256.value).lower()
                    attribute_category = 'Payload delivery'
                    attribute_type = 'sha256'

                elif observable.object_.properties.hashes.sha1:
                    attribute_value = str(observable.object_.properties.hashes.sha1.value).lower()
                    attribute_category = 'Payload delivery'
                    attribute_type = 'sha1'

                elif observable.object_.properties.hashes.md5:
                    attribute_value = str(observable.object_.properties.hashes.md5.value).lower()
                    attribute_category = 'Payload delivery'
                    attribute_type = 'md5'

            elif hasattr(observable.object_.properties, 'type_'):
                if observable.object_.properties.type_ == 'URL':
                    observable_value = str(observable.object_.properties.value)
                    attribute_category = 'Network activity'

                    if is_valid_domain(observable_value):
                        attribute_value = observable_value

                        if attribute_value.count('.') == 1:
                            attribute_type = 'domain'

                        else:
                            attribute_type = 'hostname'

                    elif is_valid_url(observable_value):
                        attribute_value = observable_value
                        attribute_category = 'Network activity'
                        attribute_type = 'url'

                    elif is_valid_url('https://{0}'.format(observable_value)):
                        attribute_value = 'https://{0}'.format(observable_value)
                        attribute_category = 'Network activity'
                        attribute_type = 'url'

            elif hasattr(observable.object_.properties, 'address_value'):
                attribute_value = str(observable.object_.properties.address_value)
                attribute_category = 'Network activity'

                if 'scan' in title.lower():
                    attribute_type = 'ip-src'

                else:
                    attribute_type = 'ip-dst'

            if not attribute_value:
                LOGGER.warning('Unable to determine observable type: {0}'.format(str(type(observable.object_.properties))))
                continue

            attribute_exists = False
            attribute_search = misp.search(controller='attributes', value=attribute_value)

            if not attribute_search['Attribute'] == []:
                for attribute_result in attribute_search['Attribute']:
                    if int(attribute_result['event_id']) == int(event['id']):
                        attribute_exists = True

            if attribute_exists:
                continue

            attribute_json = {'category': attribute_category, 'type': attribute_type, 'value': attribute_value, 'to_ids': MISP_TO_IDS}
            new_attr = misp.add_attribute(event, attribute_json, pythonify=True)

        if MISP_PUBLISH_EVENTS:
            LOGGER.info('Publishing event...')
            misp.publish(event)

        LOGGER.info('Case complete!')
def main():
    # NOTE: ID values will differ due to being regenerated on each script execution
    pkg = STIXPackage()
    pkg.title = "Examples of Observable Composition"

    # USE CASE: single obj with single condition
    obs = File()
    obs.file_name = "foo.exe"
    obs.file_name.condition = "Contains"
    pkg.add_observable(obs)

    # USE CASE: single obj with multiple conditions
    obs = File()
    obs.file_name = "foo"
    obs.file_name.condition = "Contains"
    obs.size_in_bytes = '1896000'
    obs.size_in_bytes.condition = "Equals"
    pkg.add_observable(obs)

    # USE CASE: multiple obj with individual conditions
    obs = EmailMessage()

    obs.subject = "Syria strategic plans leaked"
    obs.subject.condition = "Equals"
    file_obj = File()
    file_obj.file_name = "bombISIS.pdf"
    file_obj.file_name.condition = "Equals"
    obs.add_related(file_obj, "Contains")

    pkg.add_observable(obs)

    # USE CASE: multiple objects  with complex condition like (A OR B) AND C

    # orcomp = either of a mutex or file are present

    orcomp = ObservableComposition()
    orcomp.operator = "OR"
    obs = Mutex()
    obs.name = 'foo'
    obs.name.condition = "Contains"

    orcomp.add(obs)

    obs = File()
    obs.file_name = "barfoobar"
    obs.file_name.condition = "Equals"

    orcomp.add(obs)

    # andcomp = the above is true AND a network connection is present
    andcomp = ObservableComposition()
    andcomp.operator = "AND"

    andcomp.add(orcomp)

    obs = NetworkConnection()
    sock = SocketAddress()
    sock.ip_address = "46.123.99.25"
    sock.ip_address.category = "ipv4-addr"
    sock.ip_address.condition = "Equals"
    obs.destination_socket_address = sock
    andcomp.add(obs)

    pkg.add_observable(andcomp)

    # USE CASE:  single object, one property with multiple values
    obs = SocketAddress()
    obs.ip_address = ['10.0.0.0', '10.0.0.1',
                      '10.0.0.2']  # comma delimiter automagically added
    obs.ip_address.condition = "Equals"
    obs.ip_address.apply_condition = "ANY"

    pkg.add_observable(obs)

    print pkg.to_xml()
Example #56
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)
Example #57
0
    def parse_stix(self, reference='', make_event=False, source=''):
        """
        Parse the document.

        :param reference: The reference to the data.
        :type reference: str
        :param make_event: Whether or not to create an Event for this document.
        :type make_event: bool
        :param source: The source of this document.
        :type source: str
        :raises: :class:`crits.standards.parsers.STIXParserException`

        Until we have a way to map source strings in a STIX document to
        a source in CRITs, we are being safe and using the source provided
        as the true source.
        """

        f = StringIO(self.data)
        self.package = STIXPackage.from_xml(f)
        f.close()
        if not self.package:
            raise STIXParserException("STIX package failure")

        stix_header = self.package.stix_header
        if stix_header and stix_header.information_source and stix_header.information_source.identity:
            self.information_source = stix_header.information_source.identity.name
            if self.information_source:
                info_src = "STIX Source: %s" % self.information_source
                if not reference:
                    reference = ''
                else:
                    reference += ", "
                reference += info_src
        if does_source_exist(source):
            self.source.name = source
        elif does_source_exist(self.information_source):
            self.source.name = self.information_source
        else:
            raise STIXParserException("No source to attribute data to.")

        self.source_instance.reference = reference
        self.source.instances.append(self.source_instance)

        if make_event:
            title = "STIX Document %s" % self.package.id_
            event_type = "Collective Threat Intelligence"
            date = datetime.datetime.now()
            description = str(date)
            header = self.package.stix_header
            if isinstance(header, STIXHeader):
                if header.title:
                    title = header.title
                if hasattr(header, 'package_intents'):
                    event_type = str(header.package_intents[0])
                if header.description:
                    description = header.description
                    if isinstance(description, StructuredText):
                        try:
                            description = description.to_dict()
                        except:
                            pass
            res = add_new_event(title, description, event_type,
                                self.source.name, self.source_instance.method,
                                self.source_instance.reference, date,
                                self.source_instance.analyst)
            if res['success']:
                self.event = res['object']
                self.imported[self.package.id_] = ('Event', res['object'])

                # Get relationships to the Event
                if self.package.incidents:
                    incdnts = self.package.incidents
                    for rel in getattr(incdnts[0], 'related_indicators', ()):
                        self.event_rels[rel.item.idref] = (
                            rel.relationship.value, rel.confidence.value.value)
            else:
                self.failed.append((res['message'], "STIX Event", ""))

        if self.package.indicators:
            self.parse_indicators(self.package.indicators)

        if self.package.observables and self.package.observables.observables:
            self.parse_observables(self.package.observables.observables)

        if self.package.threat_actors:
            self.parse_threat_actors(self.package.threat_actors)
Example #58
0
def main():
    txt = demisto.args().get("iocXml").encode("utf-8")
    stx = convert_to_json(txt)
    if stx:
        stix2_to_demisto(stx)
    else:
        with tempfile.NamedTemporaryFile() as temp:
            temp.write(demisto.args()["iocXml"].encode("utf-8"))
            temp.flush()
            stix_package = STIXPackage.from_xml(temp.name)
        data = list()  # type: list
        i = 0

        stix_id = stix_package.id_
        if stix_package.indicators:
            for ind in stix_package.indicators:
                ind_id = ind.id_
                for obs in ind.observables:
                    if hasattr(obs.object_.properties, "hashes"):
                        # File object
                        for digest in obs.object_.properties.hashes:
                            if hasattr(digest, "simple_hash_value"):
                                if isinstance(digest.simple_hash_value.value,
                                              list):
                                    for hash in digest.simple_hash_value.value:
                                        create_new_ioc(data, i, ind.timestamp,
                                                       stix_id, ind_id)
                                        data[i]["indicator_type"] = "File"
                                        data[i]["value"] = hash
                                        i = i + 1
                                else:
                                    create_new_ioc(data, i, ind.timestamp,
                                                   stix_id, ind_id)
                                    data[i]["indicator_type"] = "File"
                                    data[i][
                                        "value"] = digest.simple_hash_value.value.strip(
                                        )
                                    i = i + 1
                    elif hasattr(obs.object_.properties, "category"):
                        # Address object
                        category = obs.object_.properties.category
                        if category.startswith("ip"):
                            for ip in obs.object_.properties.address_value.values:
                                create_new_ioc(data, i, ind.timestamp, stix_id,
                                               ind_id)
                                data[i]["indicator_type"] = "IP"
                                data[i]["value"] = ip
                                i = i + 1
                    elif hasattr(obs.object_.properties, "type_"):
                        if obs.object_.properties.type_ == "URL":
                            # URI object
                            create_new_ioc(data, i, ind.timestamp, stix_id,
                                           ind_id)
                            data[i]["indicator_type"] = "URL"
                            data[i][
                                "value"] = obs.object_.properties.value.value
                            i = i + 1
                        elif hasattr(obs.object_.properties.value, "values"):
                            for url in obs.object_.properties.value.values:
                                # URI object
                                create_new_ioc(data, i, ind.timestamp, stix_id,
                                               ind_id)
                                data[i]["indicator_type"] = "URL"
                                data[i]["value"] = url
                                i = i + 1
        json_data = json.dumps(data)
        demisto.results(json_data)
 def test_deprecated_related_packages(self):
     t = ta.ThreatActor()
     t.related_packages.append(STIXPackage())
     self.assertEqual(len(t.related_packages), 1)
Example #60
0
        for message in sliced_search(misp, args.start, args.end,
                                     args.day_slice, args.time_wait,
                                     datasrc_dict, allowed_attribute_set,
                                     args.quiet, attribute_status_dict,
                                     stix_export_file, yara_export_file,
                                     snort_export_file, bool(args.mail)):
            if args.verbose and message is not None:
                print message
            if isinstance(sock, socket.socket) and message is not None:
                sock.send(message)

    if isinstance(sock, socket.socket):
        sock.close()

    if args.stix_export_path:
        stix_package = STIXPackage()
        stix_header = STIXHeader()
        stix_header.description = "MISP checkioc STIX export"
        stix_package.stix_header = stix_header

        for indicator in stix_indicators:
            stix_package.add(indicator)

        stix_export_file.write(stix_package.to_xml())

        stix_export_file.close()

    if args.yara_export_path:
        yara_export_file.close()

    if args.snort_export_path: