Skip to content

Commit ac33e6e

Browse files
Caleb R LittleCaleb R Little
authored andcommitted
Merge branch 'develop'
# Conflicts: # setup.py
2 parents 0b8f0d9 + 077ae4f commit ac33e6e

File tree

16 files changed

+686
-30
lines changed

16 files changed

+686
-30
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
# Staged in Develop
2+
## Fixes
3+
- Updated stix2 and taxii2-client module version requirements to avoid potential bug
4+
## Improvements
5+
- Created Collections module
6+
- Added method and cli to turn a collection index into a markdown file for human readability
7+
- Added method and cli to turn a collection into a collection index for summary purposes
8+
- Added method and cli to turn raw stix data into a collection
9+
- Added method and cli to allow for bulk layer generation (expands generator module)
10+
- Added Data Sources and Data Components support to attackToExcel
11+
112
# v1.3.0 - 8/20/2021
213
This release introduces generator functionality to the library, as well as some improvements to excel matrix generation
314
through attackToExcel.

README.md

Lines changed: 86 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
This repository contains a library of Python-based tools and utilities for working with ATT&CK content.
44
- the [navlayers](https://github.com/mitre-attack/mitreattack-python/tree/master/mitreattack/navlayers) module contains a collection of utilities for working with [ATT&CK Navigator](https://github.com/mitre-attack/attack-navigator) layers.
55
- the [attackToExcel](https://github.com/mitre-attack/mitreattack-python/tree/master/mitreattack/attackToExcel) module provides utilities for converting [ATT&CK STIX data](https://github.com/mitre/cti) to Excel spreadsheets. It also provides access to [Pandas](https://pandas.pydata.org/) DataFrames representing the dataset for use in data analysis.
6+
- the [collections](https://github.com/mitre-attack/mitreattack-python/tree/master/mitreattack/collections) module contains a set of utilities for working with [ATT&CK Collections and Collection Indexes](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/collections.md).
67

78
## Requirements
89
- [python3](https://www.python.org/)
@@ -20,6 +21,7 @@ Some simple examples are provided here to get you started on using this library.
2021
|:------------|:------------|:--------------|
2122
| navlayers | Provides a means by which to import, export, and manipulate [ATT&CK Navigator](https://github.com/mitre-attack/attack-navigator) layers. These layers can be read in from the filesystem or python dictionaries, combined and edited, and then exported to excel or SVG images as users desire. | Further documentation for the navlayers module can be found [here](https://github.com/mitre-attack/mitreattack-python/blob/master/mitreattack/navlayers/README.md).|
2223
| attackToExcel | Provides functionalities for exporting the ATT&CK dataset into Excel Spreadsheets. It also provides programmatic access to the dataset as [Pandas](https://pandas.pydata.org/) DataFrames to enable data analysis using that library. | Further documentation for the attackToExcel module can be found [here](https://github.com/mitre-attack/mitreattack-python/blob/master/mitreattack/attackToExcel/README.md).|
24+
| collections | Provides functionalities for converting and summarizing data in collections and collection indexes. It also provides a means by which to generate a collection from a raw stix bundle input. | Further documentation for the collections module can be found [here](https://github.com/mitre-attack/mitreattack-python/blob/master/mitreattack/collections/README.md).|
2325
### Usage Examples
2426
#### navlayers
2527
```python
@@ -145,8 +147,9 @@ mapping to all associated groups, software, or mitigations across the techniques
145147
```
146148
C:\Users\attack>layerGenerator_cli -h
147149
usage: layerGenerator_cli.py [-h]
148-
(--overview-type {group,software,mitigation} | --mapped-to MAPPED_TO)
149-
[-o OUTPUT] [--domain {enterprise,mobile,ics}]
150+
(--overview-type {group,software,mitigation} | --mapped-to MAPPED_TO | --mass-type {group,software,mitigation})
151+
[-p PATH] [-o OUTPUT]
152+
[--domain {enterprise,mobile,ics}]
150153
[--source {taxii,local}] [--local LOCAL]
151154
152155
Generate an ATT&CK Navigator layer
@@ -160,17 +163,97 @@ optional arguments:
160163
Output techniques mapped to the given group, software,
161164
or mitigation. Argument can be name, associated
162165
group/software, or ATT&CK ID.
166+
--mass-type {group,software,mitigation}
167+
Output a collection of matrices to the specified
168+
folder, each one representing a different instance of
169+
the target type.
170+
-p PATH, --path PATH Path to the output layer directory (mass-type)
163171
-o OUTPUT, --output OUTPUT
164-
Path to the output layer file
172+
Path to the output layer file (output)
165173
--domain {enterprise,mobile,ics}
166174
Which domain to build off of
167175
--source {taxii,local}
168176
What source to utilize when building the matrix
169177
--local LOCAL Path to the local resource if --source=local
170178
171179
C:\Users\attack>layerGenerator_cli --domain enterprise --source taxii --mapped-to S0065 --output generated_layer.json
180+
C:\Users\attack>layerGenerator_cli --domain mobile --source taxii --overview-type mitigation --output generated_layer2.json
181+
C:\Users\attack>layerGenerator_cli --domain ics --source taxii --mass-type software
172182
```
173183

184+
##### IndexToMarkdown_cli
185+
This command line tool allows users to transform a
186+
[ATT&CK collection index file](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/collections.md#collection-indexes)
187+
into a [human-readable markdown file](https://github.com/mitre-attack/attack-stix-data/blob/master/index.md) that
188+
documents the contents of said collections.
189+
```commandline
190+
C:\Users\attack>indexToMarkdown_cli -h
191+
usage: index_to_markdown.py [-h] [-index INDEX] [-output OUTPUT]
192+
193+
Print a markdown string to std-out representing a collection index
194+
195+
optional arguments:
196+
-h, --help show this help message and exit
197+
-i INDEX, --index INDEX the collection index file to convert to markdown
198+
-o output, --output OUTPUT markdown output file
199+
C:\Users\attack>indexToMarkdown_cli --index C:\Users\attack\examples\index.json --output example.md
200+
```
201+
##### CollectionToIndex_cli
202+
This command line tool allows users to transform [ATT&CK collections](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/collections.md#collections)
203+
into an [ATT&CK collection index](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/collections.md#collection-indexes)
204+
that summarizes the contents of the linked collections.
205+
```commandline
206+
C:\Users\attack>collectionToIndex_cli -h
207+
usage: collection_to_index.py [-h] [-output OUTPUT]
208+
(-files collection1 [collection2 ...] | -folders FOLDERS [FOLDERS ...])
209+
name description root_url
210+
211+
Create a collection index from a set of collections
212+
213+
positional arguments:
214+
name name of the collection index. If omitted a placeholder
215+
will be used
216+
description description of the collection index. If omitted a
217+
placeholder will be used
218+
root_url the root URL where the collections can be found.
219+
Specified collection paths will be appended to this
220+
for the collection URL
221+
222+
optional arguments:
223+
-h, --help show this help message and exit
224+
-output OUTPUT filename for the output collection index file
225+
-files collection1 [collection2 ...]
226+
list of collections to include in the index
227+
-folders FOLDERS [FOLDERS ...]
228+
folder of JSON files to treat as collections
229+
C:\Users\attack>collectionToIndex_cli test_index "a layer created as a demo" www.example.com -files C:\Users\attack\examples\collection.json -output C:\Users\attack\examples\index.json
230+
```
231+
##### StixToCollection_cli
232+
This command line tool allows users to transform raw stix bundle files into versions featuring [collection](https://github.com/center-for-threat-informed-defense/attack-workbench-frontend/blob/master/docs/collections.md#collections) objects.
233+
It is compatible with both STIX 2.0 and STIX 2.1 bundles.
234+
```commandline
235+
C:\Users\attack>stixToCollection_cli -h
236+
usage: stix_to_collection.py [-h] [-input INPUT] [-output OUTPUT]
237+
[-description DESCRIPTION]
238+
name version
239+
240+
Update a STIX 2.0 or 2.1 bundle to include a collection object referencing the
241+
contents of the bundle.
242+
243+
positional arguments:
244+
name the name for the generated collection object
245+
version the ATT&CK version for the generated collection object
246+
247+
optional arguments:
248+
-h, --help show this help message and exit
249+
-input INPUT the input bundle file
250+
-output OUTPUT the output bundle file
251+
-description DESCRIPTION
252+
description to use for the generated collection
253+
254+
C:\Users\attack>stixToCollection "2.0 demo bundle" 9.1 -input C:\Users\bundles\enterprise-bundle-2_0.json
255+
C:\Users\attack>stixToCollection "2.1 demo bundle" 9.1 -input C:\Users\bundles\enterprise-bundle-2_1.json
256+
```
174257
## Related MITRE Work
175258
#### CTI
176259
[Cyber Threat Intelligence repository](https://github.com/mitre/cti) of the ATT&CK catalog expressed in STIX 2.0 JSON. This repository also contains [our USAGE document](https://github.com/mitre/cti/blob/master/USAGE.md) which includes additional examples of accessing and parsing our dataset in Python.

mitreattack/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from .attackToExcel import *
22
from .navlayers import *
3+
from .collections import *

mitreattack/attackToExcel/attackToExcel.py

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,19 @@ def build_dataframes(src, domain):
3434
:param domain: domain of ATT&CK src corresponds to, e.g "enterprise-attack"
3535
:returns: a dict lookup of each ATT&CK type to dataframes for the given type to be ingested by write_excel
3636
"""
37+
df = {
38+
"techniques": stixToDf.techniquesToDf(src, domain),
39+
"tactics": stixToDf.tacticsToDf(src, domain),
40+
"software": stixToDf.softwareToDf(src, domain),
41+
"groups": stixToDf.groupsToDf(src, domain),
42+
"mitigations": stixToDf.mitigationsToDf(src, domain),
43+
"matrices": stixToDf.matricesToDf(src, domain),
44+
"relationships": stixToDf.relationshipsToDf(src)
45+
}
3746
# get each ATT&CK type
38-
return {
39-
"techniques": stixToDf.techniquesToDf(src, domain),
40-
"tactics": stixToDf.tacticsToDf(src, domain),
41-
"software": stixToDf.softwareToDf(src, domain),
42-
"groups": stixToDf.groupsToDf(src, domain),
43-
"mitigations": stixToDf.mitigationsToDf(src, domain),
44-
"matrices": stixToDf.matricesToDf(src, domain),
45-
"relationships": stixToDf.relationshipsToDf(src)
46-
}
47+
if domain == 'enterprise-attack':
48+
df["datasources"] = stixToDf.sourcesToDf(src, domain)
49+
return df
4750

4851

4952
def write_excel(dataframes, domain, version=None, outputDir="."):

mitreattack/attackToExcel/stixToDf.py

Lines changed: 62 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,62 @@ def tacticsToDf(src, domain):
214214
return dataframes
215215

216216

217+
def sourcesToDf(src, domain):
218+
"""
219+
Parse STIX Data Sources and their Data components from the given data and return corresponding pandas dataframes.
220+
:param src: MemoryStore or other stix2 DataSource object holding the domain data
221+
:param domain: domain of ATT&CK src corresponds to, e.g "enterprise-attack"
222+
:returns: a lookup of labels (descriptors/names) to dataframes
223+
"""
224+
data = list(chain.from_iterable( # software are the union of the tool and malware types
225+
src.query(f) for f in [Filter("type", "=", "x-mitre-data-component"),
226+
Filter("type", "=", "x-mitre-data-source")]
227+
))
228+
refined = remove_revoked_deprecated(data)
229+
data_object_rows = []
230+
source_lookup = dict()
231+
for x in refined:
232+
if x['type'] == 'x-mitre-data-source':
233+
source_lookup[x['id']] = x['name']
234+
for data_object in tqdm(refined, desc="parsing data sources"):
235+
# add common STIx fields
236+
row = parseBaseStix(data_object)
237+
# add software-specific fields
238+
if "x_mitre_platforms" in data_object:
239+
row["platforms"] = ", ".join(sorted(data_object["x_mitre_platforms"]))
240+
if "x_mitre_collection_layers" in data_object:
241+
row["collection layers"] = ', '.join(sorted(data_object["x_mitre_collection_layers"]))
242+
if "x_mitre_aliases" in data_object:
243+
row["aliases"] = ", ".join(sorted(data_object["x_mitre_aliases"][1:]))
244+
if data_object["type"] == "x-mitre-data-component":
245+
row["name"] = f"{data_object['name']}: {source_lookup[data_object['x_mitre_data_source_ref']]}"
246+
row["type"] = "datacomponent"
247+
else:
248+
row["type"] = "datasource"
249+
if "description" in data_object:
250+
row['description'] = data_object['description']
251+
data_object_rows.append(row)
252+
253+
citations = get_citations(refined)
254+
tempa = pd.DataFrame(data_object_rows).sort_values("name")
255+
dataframes = {
256+
"datasources": tempa.reindex(columns=["name", "ID", "description", "collection layers", "platforms", "created",
257+
"modified", "type", "version", "url", "contributors"]),
258+
}
259+
# add relationships
260+
dataframes.update(relationshipsToDf(src, relatedType="datasource"))
261+
# add/merge citations
262+
if not citations.empty:
263+
if "citations" in dataframes: # append to existing citations from references
264+
dataframes["citations"] = dataframes["citations"].append(citations)
265+
else: # add citations
266+
dataframes["citations"] = citations
267+
268+
dataframes["citations"].sort_values("reference")
269+
270+
return dataframes
271+
272+
217273
def softwareToDf(src, domain):
218274
"""
219275
Parse STIX software from the given data and return corresponding pandas dataframes.
@@ -584,6 +640,7 @@ def relationshipsToDf(src, relatedType=None):
584640
"group": ["intrusion-set"],
585641
"mitigation": ["course-of-action"],
586642
"matrix": ["x-mitre-matrix"],
643+
"datasource": ["x-mitre-data-component"],
587644
}
588645
stixToAttackTerm = {
589646
"attack-pattern": "technique",
@@ -592,7 +649,9 @@ def relationshipsToDf(src, relatedType=None):
592649
"malware": "software",
593650
"intrusion-set": "group",
594651
"course-of-action": "mitigation",
595-
"x-mitre-matrix": "matrix"
652+
"x-mitre-matrix": "matrix",
653+
"x-mitre-data-component": "datacomponent",
654+
"x-mitre-data-source": "datasource"
596655
}
597656

598657
# get master list of relationships
@@ -625,7 +684,8 @@ def relationshipsToDf(src, relatedType=None):
625684
target["type"] == stixTerm): # if any stix type is part of the relationship
626685
related = True
627686
break
628-
if not related: continue # skip this relationship if the types don't match
687+
if not related:
688+
continue # skip this relationship if the types don't match
629689

630690
# add mapping data
631691
row = {}

0 commit comments

Comments
 (0)