人类的stix2模式表达库
dendrol的Python项目详细描述
dendrol将stix2模式表达式解析为基本的python结构
这一标志性的可视化基于这个示例表达式:
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
使用正式的Stix2模式语法,该表达式将转换为此解析树:
Dendrol将把这个表达式(通过解析树)转换成一种更易于阅读和机器操作的形式:
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com
我怎么用?
Dendrol提供了一个接口,用于解析Stix2模式表达式,类似于CTI模式验证器rel="nofollow">CTI模式验证器,带有denrol.pattern
类。这个类有一个方法,将antlr解析树转换为基于dict的树结构patterntree。
fromdendrolimportPatternpattern=Pattern("[domain-name:value = 'http://xyz.com/download']")assertpattern.to_dict_tree()=={'pattern':{'observation':{'objects':{'domain-name'},'join':None,'qualifiers':None,'expressions':[{'comparison':{'object':'domain-name','path':['value'],'negated':None,'operator':'=','value':'http://xyz.com/download',}}]}}}
还提出了一种专门的yaml表示方法,使数据的可视化变得更加简单:
fromdendrolimportPatternpattern=Pattern("[domain-name:value = 'http://xyz.com/download']")assertstr(pattern.to_dict_tree())=='''\pattern: observation: objects: {domain-name} join: qualifiers: expressions: - comparison: object: domain-name path: [value] negated: operator: '=' value: http://xyz.com/download'''
有关详细信息,请阅读下面的规范退出测试。
开发
要开发树胶并进行测试,首先要克隆repo。然后安装开发和测试依赖项:
pip install .[dev] .[test]
pytest用于测试:
py.test
欢迎报告问题和请求拉!从新的功能和建议到排版和糟糕的命名选择,全新的视角支持了软件的开发。
如果提交一个拉请求,请添加自己的贡献者文件,为一块甜蜜,甜蜜的街道信条!
规范
简介
模式树以'pattern'
键开始。下面是一个观察表达式,带有一个'observation'
或'expression'
键(其中可能包含更多由and/or/followedby连接的观察表达式)。下面的'observation'
键是比较表达式,用'comparison'
或'expression'
键标记(其中可能包含更多由and/or连接的比较表达式)。"比较"
键表示对象属性和文本值之间的单个比较。
模式
{'pattern':{...}}
pattern:...
patternTree是一个带有一个顶级键的dict,"pattern"
。这是一个dict的范例,只有一个键来标识它的内容,可以在整个规范中看到。
这个'pattern'
键的值是一个观察表达式
观察表达式
观察表达式是一个dict,其单个键为'expression'
或'observation'
。'expression'
应包含两个或多个由and/or/followedby连接的观察表达式,而'observation'
应仅包含比较表达式。
表达式
{'expression':{'join':oneOf('AND','OR','FOLLOWEDBY'),'qualifiers':[...],'expressions':[...],}}
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
0
'expression'
是其他观察表达式的容器,由'join'
中的观察运算符连接。它可能在'qualifiers'
键中有一个限定符列表,如果没有,则为none
。
其子项位于'expressions'
中,其值应为单键听写(可以是'observation'
或'expression'
)。
观察
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
1
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
2
'observation'
类似于stix2模式表达式中的方括号,例如:[ipv4 addr:value='1.2.3.4']
。观察结果的子项(在'expressions'
键中)只能是比较或比较表达式。
"观察"可能有限定符,但其子项不能有限定符。
'observation'
可能有一个join方法,该方法指示如何联接其子比较表达式。此方法可以是and或or,但不能是followedby,因为join方法应用于比较表达式,而不是观察表达式。如果只有一个子比较表达式,'join'
可以是none
"观察"应包含其子比较表达式的所有对象类型的集合。这主要是供人食用的。Stix2观测允许包含不同对象类型的比较,前提是它们由或连接-这就是为什么'objects'
是一个集合,而不是单个字符串。
如果'objects'
只包含一个对象类型,则可以将其压缩为set literal form:
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
3
限定符
限定符是一个dict,它有一个键来标识它的限定符类型。目前,这应该是以下之一:
开始/停止限定符
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
4
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
5
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
'start_stop'
限定符约束其关联的观察表达式必须出现在其中才能求值true的时间范围。与中的不同,
开始…停止…
使用日期时间文本表示绝对时间点。
Stix2表达式示例:
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
6
在Stix2模式表达式中,所有日期时间都必须采用RFC3339格式,并且必须采用UTC时区。日期时间文本类似于python字符串,其修改字符是t
(类似于f-string或bytestring)。因为它们必须在UTC时区中,日期时间文本必须以z
char结尾。
当解析为python时,它们应该有一个tzinfo
对象,其dstoffset
值为0。
内指定观察表达式限定符
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
7
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
8
'within'
限定符约束其关联的观察表达式必须出现在其中才能求值true的时间范围。不像start…stop…
,within
表示相对时间范围,其中最新的观测表达式必须在最早观测表达式的指定秒数内出现。
Stix2表达式示例:
(
[ipv4-addr:value = '198.51.100.1/32' OR
ipv4-addr:value = '203.0.113.33/32' OR
ipv6-addr:value = '2001:0db8:dead:beef:dead:beef:dead:0001/128']
FOLLOWEDBY [
domain-name:value = 'example.com']
) WITHIN 600 SECONDS
9
seconds
硬编码到Stix2模式表达式语法中,并且必须包含在模式表达式中。但是,为了避免读者产生歧义,并允许将来更改Stix2规格,该单元也包含在模式树中。
重复限定符
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com
0
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com
1
""repeats"
限定符要求其关联的观察表达式在指定次数的不同情况下求值为真。"
Stix2表达式示例:
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com2
times
硬编码到Stix2模式表达式语法中,并且必须包含在模式表达式中。然而,由于除了"x次"之外没有任何其他明显的多重性单位,因此在模式树输出中省略了它-与秒的
不同
在内
比较表达式
比较表达式是一个dict,其单个键为'expression'
或'comparison'
。'expression'
应包含两个或多个由and/or连接的比较表达式,而a'comparison'
不包含子项,且仅y标记一个变量与一个文本值的比较。
表达式
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com3
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com4
'expression'
是其他比较表达式的容器,由and或or连接在'join'
中-比较表达式没有后续功能,因为它们打算在单个时间点引用单个对象。
表达式不能有限定符。
其子项位于表达式中,其值应为d带单键的ICT(可以是'comparison'
或'expression'
)。
比较
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com5
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com6
'comparison'
表示Stix2对象属性和文本值之间的单个比较。单个字符串对象类型应放在'object'
键中。
'path'
应该是一个列表,以'object'
中表示的对象类型的顶级属性作为字符串开头。之后可以是任意数量的子属性,如字符串或列表索引组件/解引用,表示为pythonslice()
对象,其中[1]
相当于slice(start=none,stop=1,step=none)
。来自Stix2的特殊匹配任何列表索引(例如文件:sections[*]
)相当于切片(start=none,stop='*',step=none)
'negated'
应为bool,表示在计算期间是否应否定运算符。stix2允许在运算符:file:name与"james.*"不匹配之前使用
not
关键字。如果运算符未取反,则'negated'
可能是none
。(这允许更紧凑的yaml表示,其中可以简单地省略该值。)
'operator'
应是表示运算符的字符串,例如'>;'
,'like'
,或'='
"value"
可以是任何静态python值。目前,只输出字符串、bools、int、float、datetimes和bytes,但这在将来可能会改变(例如,如果编译的正则表达式被认为是有用的话)。
如果'path'
只包含一个属性,则可以将其压缩为列表文字形式:
pattern:expression:join:FOLLOWEDBYqualifiers:-within:value:600unit:SECONDSexpressions:-observation:objects:?ipv4-addr?ipv6-addrjoin:ORqualifiers:expressions:-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:198.51.100.1/32-comparison:object:ipv4-addrpath:[value]negated:operator:'='value:203.0.113.33/32-comparison:object:ipv6-addrpath:[value]negated:operator:'='value:2001:0db8:dead:beef:dead:beef:dead:0001/128-observation:objects:{domain-name}join:qualifiers:expressions:-comparison:object:domain-namepath:[value]negated:operator:'='value:example.com7