Skip to content

Commit

Permalink
SYN-7261: Mitre datasources added to the model (#3732)
Browse files Browse the repository at this point in the history
feat: Add ``it:mitre:attack:datasource`` and ``it:mitre:attack:data:component`` forms.
feat: Add ``it:mitre:attack:tactic:data:components`` array to ``it:mitre:attack:technique``.
  • Loading branch information
MichaelSquires authored May 24, 2024
1 parent cab9421 commit 5562842
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 2 deletions.
32 changes: 32 additions & 0 deletions synapse/models/infotech.py
Original file line number Diff line number Diff line change
Expand Up @@ -713,6 +713,13 @@ def getModelDefs(self):
'doc': 'A MITRE ATT&CK Campaign ID.',
'ex': 'C0028',
}),
('it:mitre:attack:datasource', ('str', {'regex': r'^DS[0-9]{4}$'}), {
'doc': 'A MITRE ATT&CK Datasource ID.',
'ex': 'DS0026',
}),
('it:mitre:attack:data:component', ('guid', {}), {
'doc': 'A MITRE ATT&CK data component.',
}),
('it:mitre:attack:flow', ('guid', {}), {
'doc': 'A MITRE ATT&CK Flow diagram.',
}),
Expand Down Expand Up @@ -1517,6 +1524,10 @@ def getModelDefs(self):
'uniq': True, 'sorted': True, 'split': ','}), {
'doc': 'An array of ATT&CK tactics that include this technique.',
}),
('data:components', ('array', {'type': 'it:mitre:attack:data:component',
'uniq': True, 'sorted': True}), {
'doc': 'An array of MITRE ATT&CK data components that detect the ATT&CK technique.',
}),
)),
('it:mitre:attack:software', {}, (
('software', ('it:prod:soft', {}), {
Expand Down Expand Up @@ -1636,6 +1647,27 @@ def getModelDefs(self):
('author:contact', ('ps:contact', {}), {
'doc': 'The contact information for the author of the ATT&CK Flow diagram.'}),
)),
('it:mitre:attack:datasource', {}, (
('name', ('str', {'lower': True, 'onespace': True}), {
'doc': 'The name of the datasource.'}),
('description', ('str', {}), {
'disp': {'hint': 'text'},
'doc': 'A description of the datasource.'}),
('references', ('array', {'type': 'inet:url', 'uniq': True, 'sorted': True}), {
'doc': 'An array of URLs that document the datasource.',
}),
)),
('it:mitre:attack:data:component', {}, (
('name', ('str', {'lower': True, 'onespace': True}), {
'ro': True,
'doc': 'The name of the data component.'}),
('description', ('str', {}), {
'disp': {'hint': 'text'},
'doc': 'A description of the data component.'}),
('datasource', ('it:mitre:attack:datasource', {}), {
'ro': True,
'doc': 'The datasource this data component belongs to.'}),
)),
('it:dev:int', {}, ()),
('it:dev:pipe', {}, ()),
('it:dev:mutex', {}, ()),
Expand Down
44 changes: 42 additions & 2 deletions synapse/tests/test_model_infotech.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,42 @@ async def test_infotech_basics(self):
self.eq(nodes[0].get('techniques'), ('T0100', 'T0200'))
self.eq(nodes[0].get('isnow'), 'G0110')

desc = 'A database and set of services that allows administrators to manage permissions, access to network '
desc += 'resources, and stored data objects (user, group, application, or devices)(Citation: Microsoft AD '
desc += 'DS Getting Started)'
refs = (
'https://attack.mitre.org/datasources/DS0026',
'https://docs.microsoft.com/en-us/windows-server/identity/ad-ds/ad-ds-getting-started',
)
q = f'''
[ it:mitre:attack:datasource=DS0026
:name="Active Directory"
:description="{desc}"
:references=({",".join(refs)})
]
'''
nodes = await core.nodes(q)
self.len(1, nodes)
self.eq(nodes[0].ndef, ('it:mitre:attack:datasource', 'DS0026'))
self.eq(nodes[0].get('name'), 'active directory')
self.eq(nodes[0].get('description'), desc)
self.eq(nodes[0].get('references'), refs)

q = f'''
[ it:mitre:attack:data:component=(DS0026, "Active Directory Credential Request")
:name="Active Directory Credential Request"
:description="{desc}"
:datasource=DS0026
] -+> it:mitre:attack:datasource
'''
nodes = await core.nodes(q)
self.len(2, nodes)
self.eq(nodes[0].get('name'), 'active directory credential request')
self.eq(nodes[0].get('description'), desc)
self.eq(nodes[0].get('datasource'), 'DS0026')
self.eq(nodes[1].ndef, ('it:mitre:attack:datasource', 'DS0026'))
dcguid = nodes[0].ndef[1]

nodes = await core.nodes('''[
it:mitre:attack:tactic=TA0100
:name=tactilneck
Expand Down Expand Up @@ -88,8 +124,10 @@ async def test_infotech_basics(self):
:isnow=T1110
:tactics=(TA0200,TA0100,TA0100)
:matrix=enterprise
]''')
self.len(1, nodes)
:data:components+={ it:mitre:attack:data:component=(DS0026, "Active Directory Credential Request") }
] -+> it:mitre:attack:data:component
''')
self.len(2, nodes)
self.eq(nodes[0].ndef, ('it:mitre:attack:technique', 'T0100'))
self.eq(nodes[0].get('name'), 'lockpicking')
self.eq(nodes[0].get('desc'), 'speedhackers')
Expand All @@ -101,6 +139,8 @@ async def test_infotech_basics(self):
self.eq(nodes[0].get('status'), 'deprecated')
self.eq(nodes[0].get('isnow'), 'T1110')
self.eq(nodes[0].get('matrix'), 'enterprise')
self.eq(nodes[0].get('data:components'), [dcguid])
self.eq(nodes[1].ndef, ('it:mitre:attack:data:component', dcguid))

nodes = await core.nodes('''[
it:mitre:attack:software=S0100
Expand Down

0 comments on commit 5562842

Please sign in to comment.