def rel_mem_store():
    cam = Campaign(id=CAMPAIGN_ID, **CAMPAIGN_KWARGS)
    idy = Identity(id=IDENTITY_ID, **IDENTITY_KWARGS)
    ind = Indicator(id=INDICATOR_ID, **INDICATOR_KWARGS)
    mal = Malware(id=MALWARE_ID, **MALWARE_KWARGS)
    rel1 = Relationship(ind, 'indicates', mal, id=RELATIONSHIP_IDS[0])
    rel2 = Relationship(mal, 'targets', idy, id=RELATIONSHIP_IDS[1])
    rel3 = Relationship(cam, 'uses', mal, id=RELATIONSHIP_IDS[2])
    stix_objs = [cam, idy, ind, mal, rel1, rel2, rel3]
    yield MemoryStore(stix_objs)
示例#2
0
    def createDNSObs(self, DNSOBJ):
        DNSObs = []
        DNSRel = []
        for host in DNSOBJ:
            IP = IPv4Address(value=host["ip"])
            DNS = DomainName(
                value=host["domain"]
            )  # , resolves_to_refs=IP.id) ref https://github.com/OpenCTI-Platform/client-python/issues/155
            Rel = Relationship(
                source_ref=DNS.id, target_ref=IP.id, relationship_type="resolves-to"
            )

            if self.CreateIndicator:
                STIXPattern = self.getStixPattern(host["domain"], "FQDN")
                DNSind = Indicator(
                    name=host["domain"], pattern=STIXPattern, pattern_type="stix"
                )
                STIXPattern = self.getStixPattern(host["ip"], "ipv4")
                IPind = Indicator(
                    name=host["ip"], pattern=STIXPattern, pattern_type="stix"
                )
                DNSObs.append(DNSind)
                DNSObs.append(IPind)
            DNSObs.append(IP)
            DNSObs.append(DNS)
            DNSRel.append(Rel)

        return [DNSObs, DNSRel]
示例#3
0
    def createPrimaryBinary(self, file: cuckooReportDropped, external_references):
        hashes = {
            "MD5": file.md5.upper(),
            "SHA-1": file.sha1.upper(),
            "SHA-256": file.sha256.upper(),
            "SHA-512": file.sha512.upper(),
            "SSDEEP": file.ssdeep.upper(),
        }

        STIXPattern = self.getStixPattern(file.sha256, "sha256")

        size = 0
        try:
            if file.size:
                size = file.size
        except:
            pass

        Filex = File(hashes=hashes, size=size, name=file.name, mime_type=file.type)
        ind = Indicator(
            name=file.name,
            pattern=STIXPattern,
            pattern_type="stix",
            external_references=external_references,
        )

        rel = Relationship(
            source_ref=Filex.id, relationship_type="based-on", target_ref=ind.id
        )

        return [Filex, ind, rel]
示例#4
0
    def processAndSubmit(self):
        # Create SDO's / Cyber Obs
        ext_ref = ExternalReference(
            source_name=f"Cuckoo Sandbox Report {str(self.report.info.id)}",
            url=f"{self.cuckoo_url}/analysis/{str(self.report.info.id)}/summary",
            external_id=str(self.report.info.id),
        )

        if self.report.network.hosts:
            ips = self.createIPObs(self.report.network.hosts)
        else:
            ips = []

        if self.report.network.domains:
            fqdns = self.createDNSObs(self.report.network.domains)
        else:
            fqdns = [[], []]

        if self.report.process:
            processes = self.createProcessObs(self.report.process)
        else:
            processes = []

        if self.EnableRegKeys:
            if self.report.behavior:
                if self.report.behavior.regkey_written:
                    registry_keys = self.createRegKeysObs(
                        self.report.behavior.regkey_written
                    )
                else:
                    registry_keys = None
            else:
                registry_keys = None
        else:
            registry_keys = None

        if self.EnableNetTraffic:
            if self.report.network:
                network_traffic = self.createNetTrafficObs(self.report.network)
            else:
                network_traffic = None
        else:
            network_traffic = None

        if self.report.dropped:
            dropped_binaries = self.createBinarieObs(self.report.dropped)
        else:
            dropped_binaries = []

        if self.report.signatures:
            AttackPatterns = self.getAttackPatterns(self.report.signatures)
        else:
            AttackPatterns = []

        self.helper.log_info(fqdns)

        # Get all IDs from ATPs/CyberObs
        IDs = self.get_related(
            ips,
            fqdns[0],
            processes,
            network_traffic,
            dropped_binaries,
            AttackPatterns,
            registry_keys,
        )

        # Create Main binary and link All ATPs/Cyber Obs
        payload = self.createPrimaryBinary(self.report.target.file, ext_ref)
        payload_relations = []
        bundle_ids = []
        for ID in IDs:
            try:
                IDx = ID.id
                bundle_ids.append(
                    ID
                )  # Get list for bundle w/o Attack Patterns that exisit
            except:
                IDx = ID
            payload_relations.append(
                Relationship(
                    relationship_type="related-to",
                    source_ref=payload[0].id,
                    target_ref=IDx,
                )
            )
        for ATP in AttackPatterns:
            payload_relations.append(
                Relationship(
                    relationship_type="related-to",
                    source_ref=payload[0].id,
                    target_ref=ATP,
                )
            )
        IDs.append(payload[0])  # Add Observeable
        IDs.append(payload[1])  # Add Indicator
        bundle_ids.append(payload[0])
        bundle_ids.append(payload[1])
        payload_relations.append(payload[2])

        if int(self.report.info.score) >= self.ReportScore:
            # Create Report and link All ATPs/Cyber Obs/Payload
            report = self.createCuckooReport(self.report, IDs, ext_ref)
            b = Bundle(
                report, bundle_ids, payload_relations, fqdns[1]
            )  # fqdns[1] is the Resolves-to relations
        else:
            b = Bundle(bundle_ids, payload_relations, fqdns[1])

        self.helper.send_stix2_bundle(b.serialize())

        return None
示例#5
0
    type="intrusion-set",
    spec_version="2.1",
    id="intrusion-set--ed69450a-f067-4b51-9ba2-c4616b9a6713",
    created="2016-08-08T15:50:10.983Z",
    modified="2016-08-08T15:50:10.983Z",
    name="APT BPP",
    description=
    "An advanced persistent threat that seeks to disrupt Branistan's election with multiple attacks.",
    first_seen="2016-01-08T12:50:40.123Z",
    resource_level="government",
    primary_motivation="ideology",
    goals=["Influence the Branistan election", "Disrupt the BPP"],
    secondary_motivations=["dominance"],
    aliases=["Bran-teaser"])

relationship1 = Relationship(campaign1, 'attributed-to', threat_actor)
relationship2 = Relationship(campaign2, 'attributed-to', threat_actor)
relationship3 = Relationship(campaign1, 'attributed-to', intrusionset)
relationship4 = Relationship(campaign2, 'attributed-to', intrusionset)
relationship5 = Relationship(intrusionset, 'attributed-to', threat_actor)
relationship6 = Relationship(intrusionset, 'targets', identity2)
relationship7 = Relationship(intrusionset, 'uses', attack_pattern1)
relationship8 = Relationship(intrusionset, 'uses', attack_pattern2)
relationship9 = Relationship(campaign1, 'targets', identity2)
relationship10 = Relationship(campaign2, 'targets', identity2)
relationship11 = Relationship(campaign1, 'uses', attack_pattern1)
relationship12 = Relationship(campaign2, 'uses', attack_pattern2)
relationship13 = Relationship(threat_actor, 'impersonates', identity2)
relationship14 = Relationship(threat_actor, 'targets', identity2)
relationship15 = Relationship(threat_actor, 'attributed-to', identity1)
relationship16 = Relationship(campaign2, 'targets', identity2)
示例#6
0
def simulate(actors, orgs, tools, malwares, fs, start_date, td):
    """
    Run one round of attacks and defenses with the given data set.

    Each threat actor in the 'actors' parameter takes an opportunity to choose
    and attack a target. The actor chooses a tool (and possibly malware) from
    the specified STIX data sets, and generates a random indicator. The attack
    is either successful or unsuccessful. 

    Parameters
    ----------
    actors : list of ThreatActor objects

    orgs : list of Identity objects
        STIX formatted Identity set filtered for identity_class=organization
    tools : list of Tool objects
        STIX formatted tool set to choose from
    malwares : list of Malware objects
        STIX formatted malware set to choose from
    fs : FileSystemStore
        Data store to save events
    start_date : datetime
        Start date for the events in the current round of the simulation
    td : time delta
        Time between each cyber event
    """

    # Reference to convert the agent's sophistication level to an integer
    skill_levels = {
        "minimal": 1,
        "intermediate": 2,
        "advanced": 3,
        "expert": 4,
        "innovator": 5,
        "strategic": 6
    }

    for agent in actors:
        # Pick a random target  @TODO - make this more logical later
        target_id = np.random.choice([org.id for org in orgs])
        target = [org for org in orgs if org['id'] == target_id][0]

        success = np.random.choice([True, False])
        tool = tools[np.random.randint(0, len(tools))]
        tool_rels = fs.query([
            Filter('type', '=', 'relationship'),
            Filter('source_ref', '=', agent.id),
            Filter('target_ref', '=', tool.id)
        ])
        if len(tool_rels) == 0:
            fs.add(Relationship(agent, 'uses', tool))
        indicator_type = np.random.choice(['IPv4 address', 'domain name'])
        used_malware = np.random.choice(['yes', 'no'], p=[.25, .75])
        if used_malware == 'yes':
            malware = malwares[np.random.randint(0, len(malwares))]
            mw_rels = fs.query([
                Filter('type', '=', 'relationship'),
                Filter('source_ref', '=', agent.id),
                Filter('target_ref', '=', malware.id)
            ])
            if len(mw_rels) == 0:
                fs.add(Relationship(agent, 'uses', malware.id))
        target_description = json.loads(target.description)

        description = f'On {str(start_date)[:10]}, '
        if success is True:
            description += 'an attacker successfully attacked a company named '
        else:
            description += 'an attack was attempted against a company named '
        description += (
            f'{target.name.upper()} located in the country of '
            f'{target_description["Background"]["headquarters"]}. The '
            f'attacker used the tool, {tool.name}, during its attack. ')
        if hasattr(agent, 'goals'):
            description += (f'It is believed the goal of the attack was to '
                            f'{np.random.choice(agent.goals)}.')
        description += (
            f' One of the indicators discovered was the {indicator_type}, '
            f'{random_indicator(indicator_type)}.')
        if used_malware == 'yes':
            description += (f' The attacker also attempted to use the malware '
                            f'{malware.name}.')

        fs.add(
            Sighting(description=description,
                     first_seen=start_date,
                     sighting_of_ref=agent.id))
        start_date += timedelta(td)
示例#7
0
from stix2.v21 import (ThreatActor, Identity, Relationship, Bundle)

threat_actor = ThreatActor(
    id="threat-actor--dfaa8d77-07e2-4e28-b2c8-92e9f7b04428",
    created="2014-11-19T23:39:03.893Z",
    modified="2014-11-19T23:39:03.893Z",
    name="Disco Team Threat Actor Group",
    description=
    "This organized threat actor group operates to create profit from all types of crime.",
    threat_actor_types=["crime-syndicate"],
    aliases=["Equipo del Discoteca"],
    roles=["agent"],
    goals=["Steal Credit Card Information"],
    sophistication="expert",
    resource_level="organization",
    primary_motivation="personal-gain")

identity = Identity(
    id="identity--733c5838-34d9-4fbf-949c-62aba761184c",
    created="2016-08-23T18:05:49.307Z",
    modified="2016-08-23T18:05:49.307Z",
    name="Disco Team",
    description=
    "Disco Team is the name of an organized threat actor crime-syndicate.",
    identity_class="organization",
    contact_information="*****@*****.**")

relationship = Relationship(threat_actor, 'attributed-to', identity)

bundle = Bundle(objects=[threat_actor, identity, relationship])
                  malware_types=["remote-access-trojan"],
                  kill_chain_phases=[init_comp],
                  spec_version="2.1",
                  type="malware",
                  is_family="false")

ref = ExternalReference(source_name="capec",
                        description="phishing",
                        url="https://capec.mitre.org/data/definitions/98.html",
                        external_id="CAPEC-98")

attack_pattern = AttackPattern(
    id="attack-pattern--8ac90ff3-ecf8-4835-95b8-6aea6a623df5",
    created="2015-05-07T14:22:14.760Z",
    modified="2015-05-07T14:22:14.760Z",
    name="Phishing",
    description="Spear phishing used as a delivery mechanism for malware.",
    kill_chain_phases=[init_comp],
    external_references=[ref],
    spec_version="2.1",
    type="attack-pattern")

relationship1 = Relationship(threat_actor, 'uses', malware)
relationship2 = Relationship(threat_actor, 'uses', attack_pattern)
relationship3 = Relationship(threat_actor, 'attributed-to', identity)

bundle = Bundle(objects=[
    threat_actor, malware, attack_pattern, identity, relationship1,
    relationship2, relationship3
])
示例#9
0
def create_threatactor(stix, nouns, adjectives, countries, fs):
    """
    Create a  basic threat actor profile, including country attribution, and 
    save to the given data store. 

    Parameters
    ----------
    stix : dictionary
        Seed vocabulary for APT profiles
    nouns : list
        Words available for first word in APT name
    adjectives : list
        Words avialables for second word in APT name
    countries : list
        List of country objects (for setting attribution)
    fs : FileSystemStore object
        Where to locate the APT data
    """

    # Create the name, but don't reuse nouns/adjs already chosen
    actors = fs.query(Filter('type', '=', 'threat-actor'))
    names_taken = [ta.name for ta in actors]
    adj = np.random.choice(adjectives)
    while adj in [name.split(' ')[0] for name in names_taken]:
        adj = np.random.choice(adjectives)
    noun = np.random.choice(nouns)
    while noun in [name.split(' ')[1] for name in names_taken]:
        noun = np.random.choice(nouns)
    agent_name = adj + " " + noun

    sophistication = str(np.random.choice(stix['threat-actor-sophistication']))
    actor_type = np.random.choice(
        list(stix["threat-actor-type"].keys()),
        p=list(stix["threat-actor-type"].values()))

    # target sectors
    sectors = list(np.random.choice(
        stix['sectors'], np.random.randint(2, 4), False))
    
    description = {
        'sophistication': sophistication,
        'actor_type': actor_type,
        'target_sectors': sectors
    }

    aliases = [f"APT {1000+(len(actors))}"]
    aliases_taken = []
    for ta in actors:
        aliases_taken.extend(ta.aliases)
    alias = (
        f"{np.random.choice(stix['colors'])} "
        f"{np.random.choice(stix['animals'])}")
    while alias in aliases_taken:
        alias = (
            f'{np.random.choice(stix["colors"])} '
            f'{np.random.choice(stix["animals"])}')
    aliases.append(alias)

    first_seen = date.fromordinal(np.random.randint(
        date.today().replace(year=date.today().year-10).toordinal(),
        date.today().toordinal()))

    last_seen = date.fromordinal(np.random.randint(
        date.today().replace(year=date.today().year-1).toordinal(),
        date.today().toordinal()))
    while last_seen < first_seen:
        last_seen = date.fromordinal(np.random.randint(
            date.today().replace(year=date.today().year-1).toordinal(),
            date.today().toordinal()))

    resource_level = "government"

    motivations = list(np.random.choice(
        stix['attack-motivation'], np.random.randint(2, 4), replace=False))
    primary_motivation = str(motivations[0])
    secondary_motivations = motivations[1:]
    goals = list(
        np.random.choice(stix['goals'], np.random.randint(2, 4), False))

    apt = IntrusionSet(
        name=agent_name,
        aliases=aliases,
        first_seen=first_seen,
        last_seen=last_seen,
        resource_level=resource_level,
        description=json.dumps(description),
        primary_motivation=primary_motivation,
        secondary_motivations=secondary_motivations,
        goals=goals
    )
    fs.add(apt)

    # Find countries most likely to host threat actors
    relationships = fs.query([
        Filter("type", "=", "relationship"),
        Filter("relationship_type", "=", "located-at"),
        Filter("source_ref", "contains", "intrusion-set")])
    have_actors = [country.name for country in fs.query([
        Filter("type", "=", "location"),
        Filter("id", "in", [r.target_ref for r in relationships])])]
    if actor_type == "terrorist":
        attr_countries = [
            country.name for country in countries
            if hasattr(country, 'terrorism') and
            country.name not in have_actors]
    elif actor_type == "nation-state":
        attr_countries = [
            (country.name, country.percent_GDP_on_military)
            for country in countries
            if hasattr(country, 'international_disputes') and
            country.name not in have_actors]
        attr_countries.sort(key=lambda x: x[1])
        attr_countries = [country[0] for country in attr_countries]
    else:
        attr_countries = [
            country.name for country in countries
            if country.name not in have_actors]
    if len(attr_countries) == 0:
        attr_countries = [
            country.name for country in countries
            if country.name not in have_actors]
        if len(attr_countries) == 0:
            # all of the countries already have at least one actor
            attr_countries = [country.name for country in countries]
    # Set attribution
    country = fs.query([
        Filter("type", "=", "location"),
        Filter("name", "=", attr_countries.pop())])
    fs.add(Relationship(apt, 'located-at', country[0]))
示例#10
0
def create_organization(stix, fs, country, org_names, assessment):
    """
    Generate a company profile and save to the STIX data store

    Parameters
    ----------
    stix : dictionary
        Seed vocabulary for organization profiles
    fs : FileSystemStore object
        Data store to save organization information
    country : string
        Name of country with which to associate organization
    org_names : list
        organization names to choose from
    assessment : dictionary
        representation of NIST 800-171 assessment table
    """

    name = np.random.choice(org_names)
    revenue = int(np.random.chisquare(1) * 10000)
    while revenue == 0:
        revenue = int(np.random.chisquare(1) * 10000)
    sector = np.random.choice(stix['sectors'])

    description = {
        "Background": {
            "headquarters": country.name,
            "number of employees": "{:,}".format(
                np.random.randint(500, 15000)),
            "annual revenue": "$"+"{:,}".format(revenue)+" million"
        },
        "Network": {
            "size": np.random.randint(1, 100)
        }
    }

    score = 0
    vulns = []
    dist = np.random.beta(2, 2)  # overall scoring distribution
    while dist == 0:
        dist = np.random.beta(2, 2)
    for cat in assessment:
        for r in assessment[cat]:
            pf = np.random.choice(a=['Yes', 'No'], p=[dist, 1-dist])
            if pf == 'Yes':
                score += r['Value']
            else:
                vulns.append(r['Requirement'])
    description["Security Posture"] = {
        "vulnerability": int(score/313 * 100),
        "vulns": vulns
    }

    # Add asset to the STIX data store
    organization = Identity(
        name=name,
        identity_class='organization',
        sectors=sector,
        description=json.dumps(description)
    )
    fs.add(organization)

    # Tie organization to country (headquarters)
    country_id = fs.query([
        Filter('type', '=', 'location'), Filter("name", "=", country.name)])[0].id
    fs.add(Relationship(organization, 'located-at', country_id))
示例#11
0
        processes = list(set([a.strip() for a in f.read().split()]))

    with open("emails.txt") as f:
        emails = list(set([a.strip() for a in f.read().split()]))

    res = []
    malware = Malware(name="Pegasus",
                      is_family=False,
                      description="IOCs for Pegasus")
    res.append(malware)
    for d in domains:
        i = Indicator(indicator_types=["malicious-activity"],
                      pattern="[domain-name:value='{}']".format(d),
                      pattern_type="stix")
        res.append(i)
        res.append(Relationship(i, 'indicates', malware))

    for p in processes:
        i = Indicator(indicator_types=["malicious-activity"],
                      pattern="[process:name='{}']".format(p),
                      pattern_type="stix")
        res.append(i)
        res.append(Relationship(i, 'indicates', malware))

    for f in filenames:
        i = Indicator(indicator_types=["malicious-activity"],
                      pattern="[file:name='{}']".format(f),
                      pattern_type="stix")
        res.append(i)
        res.append(Relationship(i, 'indicates', malware))
示例#12
0
    type="threat-actor")

indicator = Indicator(
    id="indicator--1ed8caa7-a708-4706-b651-f1186ede6ca1",
    created="2017-04-27T16:18:24.318Z",
    modified="2017-04-27T16:18:24.318Z",
    created_by_ref="identity--b38dfe21-7477-40d1-aa90-5c8671ce51ca",
    name="Fake email address",
    description="Known to be used by The Joker.",
    indicator_types=["malicious-activity", "attribution"],
    pattern=
    "[email-message:from_ref.value MATCHES '.+\\\\banking@g0thamnatl\\\\.com$']",
    pattern_type="stix",
    valid_from="2017-04-27T16:18:24.318Z",
    granular_markings=[granular_red, granular_amber, granular_green],
    spec_version="2.1",
    type="indicator")

rel = Relationship(
    id="relationship--3d1dd3cc-eb47-4704-9c77-ceff2971b95c",
    created="2017-04-27T16:18:24.318Z",
    modified="2017-04-27T16:18:24.318Z",
    relationship_type='indicates',
    source_ref="indicator--1ed8caa7-a708-4706-b651-f1186ede6ca1",
    target_ref="threat-actor--8b6297fe-cae7-47c6-9256-5584b417849c",
    object_marking_refs=[TLP_RED],
    spec_version="2.1",
    type="relationship")

bundle = Bundle(objects=[identity, indicator, threat_actor, rel])
indicator = Indicator(
    id="indicator--d81f86b9-975b-4c0b-875e-810c5ad45a4f",
    created="2014-06-29T13:49:37.079Z",
    modified="2014-06-29T13:49:37.079Z",
    name="Malicious site hosting downloader",
    description=
    "This organized threat actor group operates to create profit from all types of crime.",
    indicator_types=["malicious-activity"],
    pattern="[url:value = 'http://x4z9arb.cn/4712/']",
    pattern_type="stix",
    valid_from="2014-06-29T13:49:37.079000Z")

foothold = KillChainPhase(kill_chain_name="mandiant-attack-lifecycle-model",
                          phase_name="establish-foothold")

malware = Malware(
    id="malware--162d917e-766f-4611-b5d6-652791454fca",
    created="2014-06-30T09:15:17.182Z",
    modified="2014-06-30T09:15:17.182Z",
    name="x4z9arb backdoor",
    malware_types=["backdoor", "remote-access-trojan"],
    description=
    "This malware attempts to download remote files after establishing a foothold as a backdoor.",
    kill_chain_phases=[foothold],
    is_family="false")

relationship = Relationship(indicator, 'indicates', malware)

bundle = Bundle(objects=[indicator, malware, relationship])