Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions changes/65d5b1092a529b30765cbf10acf0ef51.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
desc: Added ``it:app:suricata:rule`` and ``it:app:suricata:matched`` forms.
desc:literal: false
prs: []
type: model
...
61 changes: 61 additions & 0 deletions synapse/models/infotech.py
Original file line number Diff line number Diff line change
Expand Up @@ -1049,6 +1049,12 @@ def getModelDefs(self):
('it:app:snort:hit', ('guid', {}), {
'doc': 'An instance of a snort rule hit.',
}),
('it:app:suricata:rule', ('guid', {}), {
'doc': 'A suricata rule.',
}),
('it:app:suricata:matched', ('guid', {}), {
'doc': 'An instance of a suricata rule hit.',
}),
('it:reveng:function', ('guid', {}), {
'doc': 'A function inside an executable.',
}),
Expand Down Expand Up @@ -1119,6 +1125,8 @@ def getModelDefs(self):
'doc': 'The target node was returned as a result of running the query.'}),
(('it:app:snort:rule', 'detects', None), {
'doc': 'The snort rule is intended for use in detecting the target node.'}),
(('it:app:suricata:rule', 'detects', None), {
'doc': 'The suricata rule is intended for use in detecting the target node.'}),
(('it:app:yara:rule', 'detects', None), {
'doc': 'The YARA rule is intended for use in detecting the target node.'}),
(('it:dev:repo', 'has', 'inet:url'), {
Expand Down Expand Up @@ -3207,6 +3215,59 @@ def getModelDefs(self):
'doc': 'Set to true if the network traffic was dropped due to the match.'}),
)),

('it:app:suricata:rule', {}, (

('id', ('str', {}), {
'doc': 'The suricata rule id.'}),

('text', ('str', {}), {
'disp': {'hint': 'text'},
'doc': 'The suricata rule text.'}),

('name', ('str', {}), {
'doc': 'The name of the suricata rule.'}),

('desc', ('str', {}), {
'disp': {'hint': 'text'},
'doc': 'A brief description of the suricata rule.'}),

('version', ('it:semver', {}), {
'doc': 'The current version of the rule.'}),

('author', ('ps:contact', {}), {
'doc': 'Contact info for the author of the rule.'}),

('created', ('time', {}), {
'doc': 'The time the rule was created.'}),

('updated', ('time', {}), {
'doc': 'The time the rule was most recently modified.'}),

('enabled', ('bool', {}), {
'doc': 'The rule enabled status to be used for suricata evaluation engines.'}),
)),

('it:app:suricata:matched', {}, (

('rule', ('it:app:suricata:rule', {}), {
'doc': 'The suricata rule that matched the file.'}),

('target', ('inet:flow', {}), {
'doc': 'The inet:flow that matched the suricata rule.'}),

('time', ('time', {}), {
'doc': 'The time that the rule matched the network flow.'}),

('sensor', ('it:host', {}), {
'doc': 'The sensor host node that produced the hit.'}),

('version', ('it:semver', {}), {
'doc': 'The version of the rule at the time of match.'}),

('dropped', ('bool', {}), {
'doc': 'Set to true if the network traffic was dropped due to the match.'}),
)),

('it:sec:stix:bundle', {}, (
('id', ('str', {}), {
'doc': 'The id field from the STIX bundle.'}),
Expand Down
49 changes: 49 additions & 0 deletions synapse/tests/test_model_infotech.py
Original file line number Diff line number Diff line change
Expand Up @@ -1779,6 +1779,55 @@ async def test_it_app_snort(self):

self.eq(0x10000200003, nodes[0].get('version'))

async def test_it_app_suricata(self):

async with self.getTestCore() as core:

hit = s_common.guid()
rule = s_common.guid()
flow = s_common.guid()
host = s_common.guid()
opts = {'vars': {'rule': rule, 'flow': flow, 'host': host, 'hit': hit}}

nodes = await core.nodes('''
[ it:app:suricata:rule=$rule
:id=999
:text=gronk
:name=foo
:desc=bar
:author = {[ ps:contact=* :name=visi ]}
:created = 20120101
:updated = 20220101
:enabled=1
:version=1.2.3
+(detects)> {[ it:prod:softname=woot ]}
]
''', opts=opts)

self.len(1, nodes)
self.eq('999', nodes[0].get('id'))
self.eq('foo', nodes[0].get('name'))
self.eq('gronk', nodes[0].get('text'))
self.eq('bar', nodes[0].get('desc'))
self.eq(True, nodes[0].get('enabled'))
self.eq(0x10000200003, nodes[0].get('version'))
self.eq(1325376000000, nodes[0].get('created'))
self.eq(1640995200000, nodes[0].get('updated'))
self.nn(nodes[0].get('author'))

self.len(1, await core.nodes('it:app:suricata:rule -(detects)> it:prod:softname'))

nodes = await core.nodes('''[ it:app:suricata:matched=$hit
:rule=$rule :target=$flow :time=2015 :sensor=$host
:version=1.2.3 :dropped=true ]''', opts=opts)
self.len(1, nodes)
self.true(nodes[0].get('dropped'))
self.eq(rule, nodes[0].get('rule'))
self.eq(flow, nodes[0].get('target'))
self.eq(host, nodes[0].get('sensor'))
self.eq(1420070400000, nodes[0].get('time'))
self.eq(0x10000200003, nodes[0].get('version'))

async def test_it_reveng(self):

async with self.getTestCore() as core:
Expand Down
Loading