6.11. 流程关键字

6.11.1. 流动钻头

流量钻头由两部分组成。第一部分描述它将要执行的操作,第二部分是流位的名称。

存在属于一个流的多个数据包。苏里卡将这些信息保存在记忆中。有关详细信息,请参阅 流量设置 .流位可以确保在例如两个不同的包匹配时生成警报。只有当两个数据包匹配时才会生成警报。因此,当第二个包匹配时,Suricata必须知道第一个包是否也是匹配的。如果一个包匹配,那么FlowBits会标记该流,因此当第二个包匹配时,它会生成一个警报。

流量钻头有不同的作用。这些是:

流位:集合,名称

将在流中设置条件/“name”(如果存在)。

流位:ISSET,名称

可以在规则中使用,以确保当规则匹配并且在流中设置了条件时,它会生成警报。

流位:切换,名称

反转当前设置。因此,例如,如果设置了某个条件,它将被取消设置,反之亦然。

流位:未设置,名称

可用于取消设置流中的条件。

流位:未设置,名称

可以在规则中使用,以确保它在匹配且流中未设置条件时生成警报。

流量:Noalert

此规则不会生成警报。

例子:

../_images/Flowbit_3.png

当您查看第一个规则时,您会注意到,如果它匹配,它将生成一个警报,如果它不符合规则末尾的“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,将在三路握手之后建立连接。

    ../_images/Flow1.png
  • 对于其他协议(例如UDP),在看到连接两侧的流量后,将认为连接已建立。

    ../_images/Flow2.png

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;)