def set_indicator(self, indicator: stix2.Indicator):
        if indicator:
            self.indicator = indicator
            self.buffer.name = f'Opinions: {self.indicator.name} ({self.indicator.id})'
            self.buffer.clearBuffer()

            opinions = self.store.query([
                stix2.Filter('type', '=', 'opinion'),
                stix2.Filter('object_refs', 'contains', self.indicator.id),
            ])
            opinions.sort(key=lambda opinion: opinion.created, reverse=True)

            for opinion in opinions:
                opinion: stix2.Opinion

                creator = self.store.creator_of(opinion)
                opinion_text = opinion.opinion.replace('-', ' ').title()
                evaluated_at = opinion.created.strftime('%Y-%m-%d %H:%M:%S')

                indent = '    '
                explanation = indent + '\n'.join(
                    indent + line for line in opinion.explanation.splitlines())

                self.buffer.buffer([
                    f'# {creator.name} ({creator.identity_class.title()})',
                    f'  Opinion on effectiveness: {opinion_text}',
                    f'  Evaluated at: {evaluated_at}',
                    f'',
                    f'{explanation}',
                    f'',
                    f'',
                ],
                                   scroll_end=False)
def test_environment_functions():
    env = stix2.Environment(stix2.ObjectFactory(created_by_ref=IDENTITY_ID),
                            stix2.MemoryStore())

    # Create a STIX object
    ind = env.create(stix2.Indicator, id=INDICATOR_ID, **INDICATOR_KWARGS)
    assert ind.created_by_ref == IDENTITY_ID

    # Add objects to datastore
    ind2 = ind.new_version(labels=['benign'])
    env.add([ind, ind2])

    # Get both versions of the object
    resp = env.all_versions(INDICATOR_ID)
    assert len(resp) == 1  # should be 2, but MemoryStore only keeps 1 version of objects

    # Get just the most recent version of the object
    resp = env.get(INDICATOR_ID)
    assert resp['labels'][0] == 'benign'

    # Search on something other than id
    query = [stix2.Filter('type', '=', 'vulnerability')]
    resp = env.query(query)
    assert len(resp) == 0

    # See different results after adding filters to the environment
    env.add_filters([stix2.Filter('type', '=', 'indicator'),
                    stix2.Filter('created_by_ref', '=', IDENTITY_ID)])
    env.add_filter(stix2.Filter('labels', '=', 'benign'))  # should be 'malicious-activity'
    resp = env.get(INDICATOR_ID)
    assert resp['labels'][0] == 'benign'  # should be 'malicious-activity'
Exemple #3
0
def get_examples(tech_stix_id, src):
    """Given a technique stix id, return a list of examples with their 
       external references.
    """

    examples = []
    ext_refs = []
    for r in src.relationships(tech_stix_id, 'uses', target_only=True):
        if stix2.utils.get_type_from_id(
                r.source_ref) in ['intrusion-set', 'tool', 'malware']:
            curr_refs = None
            attack_id = None
            if 'external_references' in r:
                curr_refs = r.external_references
            example = src.query([
                stix2.Filter('id', '=', r.source_ref),
                stix2.Filter('revoked', '=', False)
            ])[0]
            attack_id = buildhelpers.get_attack_id(example)
            examples.append({
                'name': example.name,
                'id': attack_id,
                'description': r.description,
                'ext_refs': curr_refs
            })

    examples = sorted(examples, key=lambda k: k['name'].lower())
    for example in examples:
        if example['ext_refs']:
            ext_refs += example['ext_refs']

    return examples, ext_refs
def get_all_techniques(src, source_name):
    """Filters data source by attack-pattern which extracts all ATT&CK Techniques"""
    filters = [
        stix2.Filter("type", "=", "attack-pattern"),
        stix2.Filter("external_references.source_name", "=", source_name),
    ]
    results = src.query(filters)
    return remove_deprecated(results)
def filter_by_type_and_id(src, object_type, object_id, source_name):
    """Filters data source by id and type"""
    filters = [
        stix2.Filter("type", "=", object_type),
        stix2.Filter("id", "=", object_id),
        stix2.Filter("external_references.source_name", "=", source_name),
    ]
    results = src.query(filters)
    return remove_deprecated(results)
Exemple #6
0
def get_techniques(src):
    """Reads the STIX and returns a list of all techniques in the STIX"""

    tech_list = src.query([
        stix2.Filter('type', '=', 'attack-pattern'),
        stix2.Filter('revoked', '=', False)
    ])

    tech_list = sorted(tech_list, key=lambda k: k['name'].lower())
    return tech_list
def test_optimize_types6():
    filters = [
        stix2.Filter("type", "!=", "foo"),
        stix2.Filter("type", "!=", "bar"),
    ]

    auth_types, auth_ids = _find_search_optimizations(filters)

    assert auth_types.auth_type == AuthSet.BLACK
    assert auth_types.values == {"foo", "bar"}
    assert auth_ids.auth_type == AuthSet.BLACK
    assert len(auth_ids.values) == 0
def test_optimize_types4():
    filters = [
        stix2.Filter("type", "in", ["A", "B", "C"]),
        stix2.Filter("type", "in", ["D", "E", "F"]),
    ]

    auth_types, auth_ids = _find_search_optimizations(filters)

    assert auth_types.auth_type == AuthSet.WHITE
    assert len(auth_types.values) == 0
    assert auth_ids.auth_type == AuthSet.BLACK
    assert len(auth_ids.values) == 0
def test_optimize_types_ids3():
    filters = [
        stix2.Filter("type", "in", ["foo", "bar"]),
        stix2.Filter("id", "!=", "bar--00000000-0000-0000-0000-000000000000"),
    ]

    auth_types, auth_ids = _find_search_optimizations(filters)

    assert auth_types.auth_type == AuthSet.WHITE
    assert auth_types.values == {"foo", "bar"}
    assert auth_ids.auth_type == AuthSet.BLACK
    assert auth_ids.values == {"bar--00000000-0000-0000-0000-000000000000"}
def get_mitigation_list(src):
    """Reads the STIX and returns a list of all mitigations in the STIX"""

    mitigations = src.query([
        stix2.Filter('type', '=', 'course-of-action'),
        stix2.Filter('revoked', '=', False)
    ])

    #Filter out deprecated objects for mitigation pages
    mitigations = [x for x in mitigations if not hasattr(x, 'x_mitre_deprecated') or x.x_mitre_deprecated == False]
    
    return sorted(mitigations, key=lambda k: k['name'].lower())
def test_optimize_types_ids2():
    filters = [
        stix2.Filter("type", "=", "foo"),
        stix2.Filter("id", "=", "bar--00000000-0000-0000-0000-000000000000"),
    ]

    auth_types, auth_ids = _find_search_optimizations(filters)

    assert auth_types.auth_type == AuthSet.WHITE
    assert len(auth_types.values) == 0
    assert auth_ids.auth_type == AuthSet.WHITE
    assert len(auth_ids.values) == 0
Exemple #12
0
def retrieve_collection(collection_id):
    # Initialize dictionary to hold Enterprise ATT&CK content
    attack = {}

    # Establish TAXII2 Collection instance for Enterprise ATT&CK collection
    collection_url = STIX_URL + "/stix/collections/{}/".format(collection_id)
    collection = taxii2client.Collection(collection_url,
                                         verify=False)  #,proxies=PROXIES)

    # Supply the collection to TAXIICollection
    tc_source = stix2.TAXIICollectionSource(collection)

    # Create filters to retrieve content from Enterprise ATT&CK based on type
    taxii_filters = {
        "techniques": stix2.Filter("type", "=", "attack-pattern"),
        "mitigations": stix2.Filter("type", "=", "course-of-action"),
        "groups": stix2.Filter("type", "=", "intrusion-set"),
        "malware": stix2.Filter("type", "=", "malware"),
        "tools": stix2.Filter("type", "=", "tool"),
        "relationships": stix2.Filter("type", "=", "relationship"),
        "tactic": stix2.Filter("type", "=", "x-mitre-tactic"),
        "matrix": stix2.Filter("type", "=", "x-mitre-matrix")
    }

    # Retrieve all Enterprise ATT&CK content
    for field in taxii_filters:
        attack[field] = tc_source.query(taxii_filters[field])

    return attack
def test_filesystem_source_backward_compatible(fs_source):
    # this specific object is outside an "ID" directory; make sure we can get
    # it.
    modified = datetime.datetime(2018, 11, 16, 22, 54, 20, 390000, pytz.utc)
    results = fs_source.query([
        stix2.Filter("type", "=", "malware"),
        stix2.Filter("id", "=", "malware--6b616fc1-1505-48e3-8b2c-0d19337bff38"),
        stix2.Filter("modified", "=", modified),
    ])

    assert len(results) == 1
    result = results[0]
    assert result.type == "malware"
    assert result.id == "malware--6b616fc1-1505-48e3-8b2c-0d19337bff38"
    assert result.modified == modified
    assert result.malware_types == ["version four"]
Exemple #14
0
def test_get_object_found(collection):
    tc_source = stix2.TAXIICollectionSource(collection)
    result = tc_source.query([
        stix2.Filter("id", "=",
                     "indicator--00000000-0000-4000-8000-000000000001"),
    ])
    assert result
def filter_for_term_relationships(src,
                                  relationship_type,
                                  object_id,
                                  target=True):
    """Filters data source by type, relationship_type and source or target"""
    filters = [
        stix2.Filter("type", "=", "relationship"),
        stix2.Filter("relationship_type", "=", relationship_type),
    ]
    if target:
        filters.append(stix2.Filter("target_ref", "=", object_id))
    else:
        filters.append(stix2.Filter("source_ref", "=", object_id))

    results = src.query(filters)
    return remove_deprecated(results)
def main():
    collection = Collection(
        "http://127.0.0.1:5000/trustgroup1/collections/52892447-4d7e-4f70-b94d-d7f22742ff63/",
        user="******",
        password="******")

    # instantiate TAXII data source
    taxii = stix2.TAXIICollectionSource(collection)

    # get (url watch indicator)
    indicator_fw = taxii.get("indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f")
    print("\n\n-------Queried for Indicator - got:")
    print(indicator_fw.serialize(indent=4))

    # all versions (url watch indicator - currently two)
    indicator_fw_versions = taxii.all_versions(
        "indicator--d81f86b9-975b-bc0b-775e-810c5ad45a4f")
    print("\n\n------Queried for indicator (all_versions()) - got:")
    for indicator in indicator_fw_versions:
        print(indicator.serialize(indent=4))

    # add TAXII filter (ie filter should be passed to TAXII)
    query_filter = stix2.Filter("type", "in", "malware")

    # query() - but with filter attached. There are no malware objects in this collection
    malwares = taxii.query(query=query_filter)
    print(
        "\n\n\n--------Queried for Malware string (with above filter attached) - got:"
    )
    for malware in malwares:
        print(malware.serialize(indent=4))
    if not malwares:
        print(malwares)
Exemple #17
0
def generate():
    """parse the STIX on MITRE/CTI and return a layer dict with techniques with randomized scores"""
    # import the STIX data from MITRE/CTI
    stix = requests.get("https://raw.githubusercontent.com/mitre/cti/master/enterprise-attack/enterprise-attack.json").json()
    ms = stix2.MemoryStore(stix_data=stix["objects"])
    # get all techniques in STIX
    techniques = ms.query([
        stix2.Filter("type", "=", "attack-pattern")
    ])
    # parse techniques into layer format
    techniques_list = []
    for technique in techniques:
        # skip deprecated and revoked
        if ("x_mitre_deprecated" in technique and technique["x_mitre_deprecated"]) or ("revoked" in technique and technique["revoked"]): continue
        techniqueID = technique["external_references"][0]["external_id"] # get the attackID
        techniques_list.append({
            "techniqueID": techniqueID,
            "score": random.randint(1,100) # random score
        })
    # return the techniques in a layer dict
    return {
        "name": "heatmap example",
        "version": "3.0",
        "sorting": 3, # descending order of score
        "description": "An example layer where all techniques have a randomized score",
        "domain": "mitre-enterprise",
        "techniques": techniques_list,
    }
Exemple #18
0
def get_technique_id_domain_map(ms):
    """Create map from technique_id to domain"""

    tech_list = {}

    for domain in site_config.domains:
        curr_list = ms[domain].query([
            stix2.Filter('type', '=', 'attack-pattern'),
            stix2.Filter('revoked', '=', False)
        ])
        for val in curr_list:
            technique_id = buildhelpers.get_attack_id(val)
            if technique_id:
                tech_list[technique_id] = domain

    return tech_list
def main():
    collection = Collection(
        "http://127.0.0.1:5000/trustgroup1/collections/91a7b528-80eb-42ed-a74d-c6fbd5a26116/",
        user="******",
        password="******",
    )

    # instantiate TAXII data source
    taxii = stix2.TAXIICollectionSource(collection)

    # get (url watch indicator)
    indicator_fw = taxii.get("indicator--6770298f-0fd8-471a-ab8c-1c658a46574e")
    print("\n\n-------Queried for Indicator - got:")
    print(indicator_fw.serialize(indent=4))

    # all versions (url watch indicator - currently two)
    indicator_fw_versions = taxii.all_versions(
        "indicator--6770298f-0fd8-471a-ab8c-1c658a46574e")
    print("\n\n------Queried for indicator (all_versions()) - got:")
    for indicator in indicator_fw_versions:
        print(indicator.serialize(indent=4))

    # add TAXII filter (ie filter should be passed to TAXII)
    query_filter = stix2.Filter("type", "in", "malware")

    # query() - but with filter attached. There are no malware objects in this collection
    malwares = taxii.query(query=query_filter)
    print(
        "\n\n\n--------Queried for Malware string (with above filter attached) - got:"
    )
    for malware in malwares:
        print(malware.serialize(indent=4))
    if not malwares:
        print(malwares)
def test_filesystem_source_sco(fs_source):
    results = fs_source.query([stix2.Filter("type", "=", "directory")])

    assert len(results) == 1
    result = results[0]
    assert result["type"] == "directory"
    assert result["id"] == "directory--572827aa-e0cd-44fd-afd5-a717a7585f39"
    assert result["path"] == "/performance/Democrat.gif"
Exemple #21
0
def get_matrices(src):
    """Reads the STIX and returns a list of all matrices in the STIX"""

    matrices = src.query([
        stix2.Filter('type', '=', 'x-mitre-matrix'),
    ])

    return matrices
def test_filesystem_source_query_single(fs_source):
    # query2
    is_2 = fs_source.query([stix2.Filter("external_references.external_id", '=', "T1027")])
    assert len(is_2) == 1

    is_2 = is_2[0]
    assert is_2.id == "attack-pattern--b3d682b6-98f2-4fb0-aa3b-b4df007ca70a"
    assert is_2.type == "attack-pattern"
Exemple #23
0
def get_revoked_by(stix_id, src):
    """Given a stix_id, return an object that revokes it,
       if no object is found, return None
    """

    relations = src.relationships(stix_id, 'revoked-by', source_only=True)
    revoked_by = src.query([
        stix2.Filter('id', 'in', [r.target_ref for r in relations]),
        stix2.Filter('revoked', '=', False)
    ])
    if revoked_by:
        try:
            revoked_by = revoked_by[0]
        except IndexError:
            print("Malformed STIX content detected")
            print(stix_id)
            revoked_by = revoked_by[0]
    return revoked_by
def get_tactic_list(src, matrix_id=None):
    """Reads the STIX and returns a list of all tactics in the STIX"""

    tactics = []
    matrix = src.query([
        stix2.Filter('type', '=', 'x-mitre-matrix'),
    ])

    if matrix_id:
        for curr_matrix in matrix:
            if curr_matrix['id'] == matrix_id:
                for tactic_id in curr_matrix['tactic_refs']:
                    tactics.append(src.query([stix2.Filter('id', '=', tactic_id)])[0])    
    else:
        for i in range(len(matrix)):
            for tactic_id in matrix[i]['tactic_refs']:
                tactics.append(src.query([stix2.Filter('id', '=', tactic_id)])[0])    
    
    return tactics
def test_filesystem_store_query(fs_store):
    # query()
    tools = fs_store.query([stix2.Filter("tool_types", "in", "tool")])
    assert len(tools) == 2
    assert "tool--242f3da3-4425-4d11-8f5c-b842886da966" in [
        tool.id for tool in tools
    ]
    assert "tool--03342581-f790-4f03-ba41-e82e67392e23" in [
        tool.id for tool in tools
    ]
Exemple #26
0
def test_filesystem_store_query_single_filter(fs_store):
    query = stix2.Filter("labels", "in", "tool")
    tools = fs_store.query(query)
    assert len(tools) == 2
    assert "tool--242f3da3-4425-4d11-8f5c-b842886da966" in [
        tool.id for tool in tools
    ]
    assert "tool--03342581-f790-4f03-ba41-e82e67392e23" in [
        tool.id for tool in tools
    ]
def test_filesystem_source_query_multiple(fs_source):
    # query
    intrusion_sets = fs_source.query([stix2.Filter("type", '=', "intrusion-set")])
    assert len(intrusion_sets) == 2
    assert "intrusion-set--a653431d-6a5e-4600-8ad3-609b5af57064" in [is_.id for is_ in intrusion_sets]
    assert "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a" in [is_.id for is_ in intrusion_sets]

    is_1 = [is_ for is_ in intrusion_sets if is_.id == "intrusion-set--f3bdec95-3d62-42d9-a840-29630f6cdc1a"][0]
    assert "DragonOK" in is_1.aliases
    assert len(is_1.external_references) == 4
def test_optimize_types_ids6():
    filters = [
        stix2.Filter("id", "=", "A--00000000-0000-0000-0000-000000000000"),
    ]

    auth_types, auth_ids = _find_search_optimizations(filters)

    assert auth_types.auth_type == AuthSet.WHITE
    assert auth_types.values == {"A"}
    assert auth_ids.auth_type == AuthSet.WHITE
    assert auth_ids.values == {"A--00000000-0000-0000-0000-000000000000"}
def test_optimize_types_ids5():
    filters = [
        stix2.Filter("type", "in", ["A", "B", "C"]),
        stix2.Filter("type", "!=", "C"),
        stix2.Filter(
            "id", "in", [
                "B--00000000-0000-0000-0000-000000000000",
                "C--00000000-0000-0000-0000-000000000000",
                "D--00000000-0000-0000-0000-000000000000",
            ],
        ),
        stix2.Filter("id", "!=", "D--00000000-0000-0000-0000-000000000000"),
    ]

    auth_types, auth_ids = _find_search_optimizations(filters)

    assert auth_types.auth_type == AuthSet.WHITE
    assert auth_types.values == {"B"}
    assert auth_ids.auth_type == AuthSet.WHITE
    assert auth_ids.values == {"B--00000000-0000-0000-0000-000000000000"}
 def __init__(self,
              name=None,
              parentApp=None,
              framed=None,
              help=None,
              color='FORMDEFAULT',
              widget_list=None,
              cycle_widgets=False,
              *args,
              store: stix2.MemoryStore,
              **keywords):
     indicators = store.query([stix2.Filter('type', '=', 'indicator')])
     self._provided_indicators = tuple(indicators)
     super().__init__(name, parentApp, framed, help, color, widget_list,
                      cycle_widgets, *args, **keywords)