6.11. 流程关键字¶
6.11.1. 流动钻头¶
流量钻头由两部分组成。第一部分描述它将要执行的操作,第二部分是流位的名称。
存在属于一个流的多个数据包。苏里卡将这些信息保存在记忆中。有关详细信息,请参阅 流量设置 .流位可以确保在例如两个不同的包匹配时生成警报。只有当两个数据包匹配时才会生成警报。因此,当第二个包匹配时,Suricata必须知道第一个包是否也是匹配的。如果一个包匹配,那么FlowBits会标记该流,因此当第二个包匹配时,它会生成一个警报。
流量钻头有不同的作用。这些是:
- 流位:集合,名称
将在流中设置条件/“name”(如果存在)。
- 流位:ISSET,名称
可以在规则中使用,以确保当规则匹配并且在流中设置了条件时,它会生成警报。
- 流位:切换,名称
反转当前设置。因此,例如,如果设置了某个条件,它将被取消设置,反之亦然。
- 流位:未设置,名称
可用于取消设置流中的条件。
- 流位:未设置,名称
可以在规则中使用,以确保它在匹配且流中未设置条件时生成警报。
- 流量:Noalert
此规则不会生成警报。
例子:
当您查看第一个规则时,您会注意到,如果它匹配,它将生成一个警报,如果它不符合规则末尾的“flowbits:noalert”。此规则的目的是检查“userlogin”是否匹配,并在流中标记该匹配。因此,不需要生成警报。第二条规则没有第一条规则无效。如果第一个规则匹配,那么流位将设置流中存在的特定条件。现在,通过第二条规则,可以检查前一个包是否满足第一个条件。如果此时第二个规则匹配,将生成警报。
可以在规则中多次使用流位并组合不同的函数。
6.11.2. 流¶
Flow关键字可用于匹配流的方向,例如到/从客户端或到/从服务器。它还可以匹配是否建立了流。流关键字还可以用来表示签名必须只在流上匹配(只在流上匹配)或只在包上匹配(不在流上匹配)。
因此,使用Flow关键字可以匹配:
- to_client
在从服务器到客户端的数据包上匹配。
- to_server
在从客户端到服务器的数据包上匹配。
- from_client
在从客户机到服务器的数据包上匹配(与到服务器相同)。
- from_server
在从服务器到客户机的数据包上进行匹配(与“客户机”相同)。
- 已建立
匹配已建立的连接。
- not_established
匹配不属于已建立连接的数据包。
- 无状态
匹配属于或不属于已建立连接的数据包。
- only_stream
匹配流引擎重新组装的数据包。
- no_stream
匹配流引擎未重新组装的数据包。与重新组装的数据包不匹配。
- only_frag
匹配从片段中重新组装的数据包。
- no_frag
匹配未从片段重新组合的数据包。
可以组合多个流选项,例如:
flow:to_client, established
flow:to_server, established, only_stream
flow:to_server, not_established, no_frag
决定 已建立 取决于协议:
对于TCP,将在三路握手之后建立连接。
对于其他协议(例如UDP),在看到连接两侧的流量后,将认为连接已建立。
6.11.3. 流动¶
flowint允许使用变量进行存储和数学运算。它的操作与流位非常相似,但是它添加了数学功能,并且整数可以被存储和操作,而不仅仅是一个标志集。我们可以将其用于许多非常有用的事情,例如计算发生次数、增加或减少发生次数,或者在流中针对多个因素执行阈值。这将很快扩展到全局上下文,因此用户可以在流之间执行这些操作。
语法如下:
flowint: name, modifier[, value];
定义一个变量(不需要),或者检查是否设置了一个变量。
flowint: name, < +,-,=,>,<,>=,<=,==, != >, value;
flowint: name, (isset|isnotset);
比较或改变变量。加、减、比较大于或小于、大于或等于、小于或等于都可用。要比较的项可以是整数或其他变量。
例如,如果要计算在特定流中看到用户名的次数,并在用户名超过5时发出警报。
alert tcp any any -> any any (msg:"Counting Usernames"; content:"jonkman"; \
flowint: usernamecount, +, 1; noalert;)
这将统计每个事件并增加var usernamecount,而不会为每个事件生成警报。
现在假设我们想要在流中有超过五个点击时生成一个警报。
alert tcp any any -> any any (msg:"More than Five Usernames!"; content:"jonkman"; \
flowint: usernamecount, +, 1; flowint:usernamecount, >, 5;)
所以只有当用户名数超过5时,我们才会收到警报。
所以现在假设我们想要得到一个如上所述的警报,但是如果有更多的用户名注销事件发生,我们就不想得到。假设此特定协议指示使用“jonkman log out”注销,让我们尝试:
alert tcp any any -> any any (msg:"Username Logged out"; content:"logout jonkman"; \
flowint: usernamecount, -, 1; flowint:usernamecount, >, 5;)
所以现在,只有当这个特定用户名有五个以上的活动登录名时,我们才会收到警报。
这是一个相当简单的例子,但我相信它显示了这样一个简单函数对规则编写的作用。我在登录跟踪、IRC状态机、恶意软件跟踪和强力登录检测等方面看到了很多应用程序。
假设我们正在跟踪一个协议,该协议通常允许每个连接有五次登录失败,但是我们有一个漏洞,在这五次尝试之后,攻击者可以继续登录,我们需要了解它。
alert tcp any any -> any any (msg:"Start a login count"; content:"login failed"; \
flowint:loginfail, notset; flowint:loginfail, =, 1; noalert;)
因此,如果变量尚未设置,我们会检测到初始失败,如果设置了,则将其设置为1。我们的第一次成功。
alert tcp any any -> any any (msg:"Counting Logins"; content:"login failed"; \
flowint:loginfail, isset; flowint:loginfail, +, 1; noalert;)
如果计数器设置好了,我们现在就增加它。
alert tcp any any -> any any (msg:"More than Five login fails in a Stream"; \
content:"login failed"; flowint:loginfail, isset; flowint:loginfail, >, 5;)
现在,如果在同一个流中跨五次登录失败,我们将生成一个警报。
但我们也要说,如果有两个成功的登录和一个失败的登录之后,我们还需要警报。
alert tcp any any -> any any (msg:"Counting Good Logins"; \
content:"login successful"; flowint:loginsuccess, +, 1; noalert;)
这里我们要计算好的登录名,所以现在我们要计算与失败相关的好的登录名:
alert tcp any any -> any any (msg:"Login fail after two successes"; \
content:"login failed"; flowint:loginsuccess, isset; \
flowint:loginsuccess, =, 2;)
以下是一些其他的一般例子:
alert tcp any any -> any any (msg:"Setting a flowint counter"; content:"GET"; \
flowint:myvar, notset; flowint:maxvar,notset; \
flowint:myvar,=,1; flowint: maxvar,=,6;)
alert tcp any any -> any any (msg:"Adding to flowint counter"; \
content:"Unauthorized"; flowint:myvar,isset; flowint: myvar,+,2;)
alert tcp any any -> any any (msg:"when flowint counter is 3 create new counter"; \
content:"Unauthorized"; flowint:myvar, isset; flowint:myvar,==,3; \
flowint:cntpackets,notset; flowint:cntpackets, =, 0;)
alert tcp any any -> any any (msg:"count the rest without generating alerts"; \
flowint:cntpackets,isset; flowint:cntpackets, +, 1; noalert;)
alert tcp any any -> any any (msg:"fire this when it reach 6"; \
flowint: cntpackets, isset; \
flowint: maxvar,isset; flowint: cntpackets, ==, maxvar;)
6.11.4. stream_size¶
流大小选项根据序列号注册的字节数匹配流量。此关键字有几个修饰符:
> greater than
< less than
= equal
!= not equal
>= greater than or equal
<= less than or equal
格式
stream_size:<server|client|both|either>, <modifier>, <number>;
规则中的stream size关键字示例:
alert tcp any any -> any any (stream_size:both, >, 5000; sid:1;)