Suricata/Snort规则参考

Posted 神域序列

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Suricata/Snort规则参考相关的知识,希望对你有一定的参考价值。

Suricata/Snort规则参考

文章目录


Suricata是一款开源IDS/IPS/NSM引擎,兼容Snort规则

限制

截至Suricata 6.0.0

  • 不支持请求-响应双向匹配,单条规则只支持请求或者响应
  • 不支持复杂的逻辑运算,只支持并且

优势

  • 规则支持众多协议类型
  • 规则支持多种解码、编码匹配方式
  • 规则支持多种预定义函数转换方式

6. Suricata 规则

6.1. 规则格式

攻击特征在Suricata中扮演了一个非常重要的角色。在大多数场景下,使用现有的规则库即可满足大多数场景需求。

官方安装规则库的方式参照:Rule Management with Suricata-Update

Suricata规则文档解释了如何读懂规则、按需调整规则以及创建一个新规则等所有特征相关的方面。

一条规则/特征包括如下部分:

  1. 动作(action),用来决定当特征匹配成功后如何处理。
  2. 头信息(header),定义应用规则的协议、IP地址、端口和方向。
  3. 规则选项(rule options),定义规则的特征。

如下是一条规则示例:

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

将上面的示例拆解:

1. 动作     -> drop 
2. 头信息   -> tcp $HOME_NET any -> $EXTERNAL_NET any 
3. 规则选项 -> (msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

在本节中,我们将使用上述规则签名作为示例,突出解释签名的不同部分。它是从Emerging Threats数据库中提取的签名,这是一个开放数据库,具有许多规则,您可以免费下载并在您的Suricata实例中使用。

6.1.1. 动作(Action)

drop <————
tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

示例中为:drop

有效的动作取值为:

  • alert - 生成一条告警
  • pass - 停止对数据包的进一步检查
  • drop - 弃数据包并生成告警
  • reject - 发送RST/ICMP unreach 错误到匹配数据包的发送方。
  • rejectsrc - 与 reject 含义相同
  • rejectdst - 发送RST/ICMP错误数据包到匹配数据包的接收方。
  • rejectboth - 向对话双方发送RST/ICMP错误数据包。

!注意 在IPS模式中, 使用任何的reject动作,同时也会触发drop动作。

更多关于动作(Action)的详细信息请参阅:Action-order

6.1.2. 协议(Protocol)

drop
tcp <————
$HOME_NET any -> $EXTERNAL_NET any (msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

示例中为:tcp

规则中的协议关键词告诉Suricata该规则应该应用哪种协议。你可以在四个基础协议中选择:

  • tcp (for tcp-traffic)
  • udp
  • icmp
  • ip (ip stands for ‘all’ or ‘any’)

还有一些叫做应用层协议,或者7层协议的选择项:

  • http
  • ftp
  • tls (this includes ssl)
  • smb
  • dns
  • dcerpc
  • ssh
  • smtp
  • imap
  • modbus (disabled by default)
  • dnp3 (disabled by default)
  • enip (disabled by default)
  • nfs
  • ikev2
  • krb5
  • ntp
  • dhcp
  • rfb
  • rdp
  • snmp
  • tftp
  • sip
  • http2

这些协议的可用性取决于配置文件suricata.yaml中是否启用了该协议。

如果您有一个协议标记为http的规则,Suricata确保规则只有在涉及http流量时才能匹配。

6.1.3. 源和目的(Source and destination)

drop tcp
$HOME_NET <————
any -> 
$EXTERNAL_NET <————
any 
(msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

示例中为:$HOME_NET $EXTERNAL_NET

第一个强调的部分$HOME_NET是源,第二个是目的$EXTERNAL_NET(注意方向箭头的方向)。

通过设置源和目的,可以分别指定网络通信的源和目的。你可以为源和目的分配IP地址(IPv4和IPv6都支持)和IP地址段,并且可以通过操作符进行组合:

操作符描述示例
…/…IP段 (CIDR记号法)192.168.1.1/24
!除去/取反!192.168.1.125
[…, …]组合[192.168.1.2, 192.168.1.3]

你也可以使用变量来设置,例如:$HOME_NET$EXTERNAL_NET。这些变量表示预定义的IP地址,预定义的内容可以在suricata-yaml配置文件中修改。详情参考:Rule-vars

示例:

示例含义
!1.1.1.1除1.1.1.1之外的所有IP
![1.1.1.1, 1.1.1.2]除1.1.1.1 和 1.1.1.2之外的所有IP
$HOME_NET在yaml配置文件中配置的 HOME_NET 变量
[ E X T E R N A L N E T , ! EXTERNAL_NET, ! EXTERNALNET,!HOME_NET]EXTERNAL_NET 和 非 HOME_NET
[10.0.0.0/24, !10.0.0.5]除去10.0.0.5之外的10.0.0.0/24 IP段
[…, [….]]
[…, ![……]]

!警告
如何你的配置像这样:
HOME_NET: any
EXTERNAL_NET: ! $HOME_NET
您不能使用$EXTERNAL_NET编写签名,因为它代表“not any”。这是一个无效的设置。

6.1.4. 端口(Source and destination)

drop tcp $HOME_NET
any  <————
-> $EXTERNAL_NET
any  <————
(msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

第一个强调的部分是源端口,第二个是目的端口(注意方向箭头的方向)。

通信通过端口进出。不同的端口有不同的端口号。例如,HTTP的默认端口是80,而443通常是HTTPS的端口。但是请注意,端口并不规定在通信中使用哪个协议。相反,它确定哪个应用程序正在接收数据。

上述提到的端口通常是目的端口。源端口是应用程序用来发送数据的端口,一般由操作系统随机分配。当你需要为你的HTTP服务写一个规则时,你通常可以写any -> 80,它表示当任何源端口发送到80端口的数据才会进行规则匹配。

在设置端口时,你也可以操作符,如下所示:

操作符描述
:端口范围
!除去/取非
[…, …]组合

示例:

示例含义
[80, 81, 82]端口 80, 81 和 82
[80: 82]端口范围 80 到 82
[1024: ]从1024 到 最大的端口
!80除去80之外的所有端口
[80:100,!99]端口范围 80 到 100,除去 99
[1:80,![2,4]]端口范围 1-80, 除去 2 和 4
[…, […,…]]

6.1.5. 方向(Direction)

drop tcp $HOME_NET any
->   <————
$EXTERNAL_NET any (msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:"NICK "; pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

方向说明以何种方式匹配签名。几乎每个签名都有一个向右的箭头(->)。这意味着只有方向相同的数据包才能匹配。当然,也有一个规则匹配的两个方向(<>):

source -> destination
source <> destination  (both directions)

!警告
没有反方向的方向表示,也就是说,没有 <-

下面的示例说明了这一点。假设,有一个客户端,IP地址为1.2.3.4,端口为1024,还有一个服务器,IP地址为5.6.7.8,监听端口为80(通常是HTTP)。客户机向服务器发送一条消息,服务器返回了响应信息。

现在,假设我们有一个规则,它的头信息如下:

alert tcp 1.2.3.4 1024 -> 5.6.7.8 80

只有第一个数据包会被这个规则匹配,因为方向指定了,所有我们不匹配响应包。

6.1.6. 规则选项(Rule options)

规则的其余部分由选项组成。它们用圆括号括着,用分号分隔着。有些选项具有设置(如msg),由选项的关键字、冒号和设置指定。其他的没有设置,只是关键字(如nocase):

<keyword>: <settings>;
<keyword>;

规则选项具有特定的顺序,更改它们的顺序将改变规则的含义。

!注意

字符;"在Suricata规则语言中具有特殊意义,在规则选项值中使用时必须转义。例如:

msg:"Message with semicolon\\;";

因此,还必须转义反斜杠,因为它是转义字符。

本章的其余部分在文档中记录了各种关键字的使用。

下面是一些关于关键词的通用细节。

6.1.6.1. 修饰器关键词(Modifier Keywords)

一些关键字的功能作为修饰语。修饰语有两种类型。

  • 旧样式的“内容修饰符”在content:"";后面,例如:
alert http any any -> any any (content:"index.php"; http_uri; sid:1;)

在上面的例子中,模式'index.php'被修饰用来检测HTTP uri缓存区。

也就是说,当http数据包的uri部分包括index.php关键词时,才会触发告警。

  • 最近的一种被称为“粘性缓冲”。它将缓冲区名称放在首位,然后所有紧随它后面的关键字应用到该缓冲区,例如:
alert http any any -> any any (http_response_line; content:"403 Forbidden"; sid:1;)

在上面的例子中,当模式'403 Forbidden'在HTTP response line中出现时触发告警,因为它紧随http_response_line关键词。

6.1.6.2. 规范化的缓冲区(Normalized Buffers)

数据包由原始数据组成。HTTP和reassembly复制了这些类型的数据包数据。它们清除异常内容,组合数据包等等。剩下的就是所谓的“标准化缓冲区”:

因为数据被标准化了,它不再是以前的样子了;这是一种解释。规范化的缓冲区是:所有http关键字、重新组装的流、TLS-、SSL-、SSH-、FTP-和dcerpc-缓冲区。

注意有一些例外,例如http_raw_uri关键字。参见:http.uri and http.uri.raw获取更多信息。

6.2. Meta Keywords

Meta Keywords不会影响任何Suricata规则检测行为;它们只影响Suricata的告警事件输出格式。

6.2.1. msg (message)

关键字msg给出关于规则和告警的合理的文本信息。

msg的格式为:

msg: "some description";

例子:

msg:"ATTACK-RESPONSES 403 Forbidden";
msg:"ET EXPLOIT SMB-DS DCERPC PnP bind attempt";

继续上一章的例子,这是关键字在实际规则的行动:

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)
msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”;

惯例是将msg作为规则选项的第一个关键字,并且这部分以大写表示,突出显示签名的类别。

这些字符如出现在msg中必须进行转义:; \\ "

6.2.2. sid (签名ID)

关键字sid为每个签名提供自己的id。这个id规定使用数字进行声明。sid的格式如下:

sid:123;

sid在一个规则中的例子:

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

按照惯例,签名sid作为签名的最后一个关键字(如果有rev,则倒数第二)提供。

6.2.3. rev (版本)

sid关键字几乎每次都伴随着revrev代表签名的版本。如果签名被修改,rev的数量将由签名作者增加。rev格式为:

rev:123;

一个规则中包含rev的例子:

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

按照惯例,sid出现在rev之前,并且两者都是所有关键字中的最后一个。

6.2.4. gid (组ID)

gid关键字可用于提供另一个id值来表示不同的签名组(就像sid)。Suricata默认使用gid 1。这是可以修改的。通常情况下,它不会被改变,而且改变它没有技术含义。您只能在告警中观察到它的变化。

如下是一个有gid的告警示例,此告警打印在fast.log文件中。在[1:2008124:2]部分,1 是 gid,2008124是 sid,2 是 rev。

10/15/09-03:30:10.219671 [**] [1:2008124:2] ET TROJAN Likely Bot Nick in IRC (USA +..) [**] [Classification: A Network Trojan was Detected] [Priority: 3] {TCP} 192.168.1.42:1028 -> 72.184.196.31:6667

6.2.5. classtype (类别)

classtype关键字提供了关于规则和告警的分类信息。它包括一个短名称,一个长名称和一个优先级。它可以分辨出一个规则是仅仅提供信息还是匹配攻击行为等等。对于每个classtype,classification.config中有一个优先级可以在规则中被使用。

classtype定义示例:

config classification: web-application-attack,Web Application Attack,1
config classification: not-suspicious,Not Suspicious Traffic,3

现在当我们在配置中定义了如上配置之后,我们就可以在规则中使用这些classtype。一个使用web-application-attackclasstype的规则将被分配优先级1,并且告警将包含’Web Application Attack’:

classtypeAlertPriority
web-application-attackWeb Application Attack1
not-suspiciousNot Suspicious Traffic3

我们接下来的例子也有一个classtype,这个是trojan-activity:

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

按照惯例,classtype出现在sid和rev之前,并出现在其他关键字之后。

6.2.6. reference (引用/参考)

reference关键字指向可以找到关于签名和签名试图解决的问题的信息的位置。reference关键字可以在签名中出现多次。这个关键字是为研究签名匹配原因的签名作者和分析人员设计的。它的格式如下:

reference: type, reference

一个典型的指向www.info.com的reference可以这么写:

reference: url, www.info.com

但是,还有一些系统可以作为参考。一个常见的例子是CVE-database,它为漏洞分配了唯一的ID。为了防止你一遍又一遍地输入相同的URL,你可以使用这样的写法:

reference: cve, CVE-2014-1234

这种写法可以自动生成一个指向http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-1234的引用。所有的引用类型在reference.config配置文件中定义。

我们接下来的例子也有一个引用:

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

6.2.7. priority (优先级)

priority关键字的值必须使用数字,范围从1到255。数字1到4是最常用的。优先级较高的签名将首先被检查。最高优先级是1。通常,配置了classtype的签名已经有了优先级。但是我们可以用关键字priority来重新设置。优先级的形式是:

priority:1;

6.2.8. metadata (元数据)

元数据关键字允许将附加的、非功能的信息添加到签名中。尽管它的格式没有限制,但建议坚持使用键、值对,因为Suricata可以将它们包含在eve告警中。格式是:

metadata: key value;
metadata: key value, key value;

6.2.9. target (目标)

target关键字允许规则编写人员指定警报的哪一边是攻击的目标。如果指定,告警事件将增强为包含有关源和目标的信息。

格式是:

target:[src_ip|dest_ip]

如果值是src_ip,那么生成事件中的源IP (JSON格式的src_ip字段)就是攻击的目标。如果target被设置为dest_ip,那么目的IP就是生成事件中的目标IP。

6.3. IP Keywords

6.3.1. ttl

ttl关键字用于检查包头中的特定IP生存时间(time-to-live)值。格式是:

ttl:<number>

例如:

ttl:10;

在ttl关键字的末尾,您可以输入想要匹配的值。生存时间值决定了数据包在网络传输中可以存在的最大时间。如果该字段被设置为0,则必须销毁该数据包。生存时间基于跳数。数据包通过的每一跳/路由器减去一个数据包TTL计数器。这个机制的目的是限制数据包的存在,防止数据包不能在无限的路由循环中结束。

ttl关键字在规则中的例子:

alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL MISC 0 ttl”; ttl:0; reference:url,support.microsoft.com/default.aspx?scid=kb#-#-EN-US#-#-q138268; reference:url,www.isi.edu/in-notes/rfc1122.txt; classtype:misc-activity; sid:2101321; rev:9;)

6.3.2. ipopts

使用ipopts关键字,您可以检查是否设置了特定的IP选项。Ipopts必须在规则的开头使用。每个规则只能匹配一个选项。有几个选项可以匹配。它们是:

IP OptionDescription
rrRecord Route
eolEnd of List
nopNo Op
tsTime Stamp
secIP Security
esecIP Extended Security
lsrrLoose Source Routing
ssrrStrict Source Routing
satidStream Identifier
anyany IP options are set

ipopts关键词格式:

ipopts: <name>

例子:

ipopts: lsrr;

规则中的ipopts示例:

alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL MISC source route ssrr”; ipopts:ssrr; reference:arachnids,422; classtype:bad-unknown; sid:2100502; rev:3;)

6.3.3. sameip

每个包有一个源ip地址和一个目的ip地址。源IP可能与目标IP相同。使用sameip关键字,您可以检查源的IP地址是否与目标的IP地址相同。sameip关键字的格式为:

sameip;

规则中的sameip示例:

alert ip any any -> any any (msg:”GPL SCAN same SRC/DST”; sameip; reference:bugtraq,2666; reference:cve,1999-0016; reference:url,www.cert.org/advisories/CA-1997-28.html; classtype:bad-unknown; sid:2100527; rev:9;)

6.3.4. ip_proto

您可以使用关键字ip_proto匹配包头中的IP协议。您可以使用协议的名称或编号。例如,您可以匹配以下协议:

 1     ICMP        Internet Control Message
 6     TCP         Transmission Control Protocol
17     UDP         User Datagram
47     GRE         General Routing Encapsulation
50     ESP         Encap Security Payload for IPv6
51     AH          Authentication Header for Ipv6
58     IPv6-ICMP   ICMP for Ipv6

有关协议及其编号的完整列表,请参阅:http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers

规则中的ip_proto示例:

alert ip any any -> any any (msg:”GPL MISC IP Proto 103 PIM”; ip_proto:103; reference:bugtraq,8211; reference:cve,2003-0567; classtype:non-standard-protocol; sid:2102189; rev:4;)

该示例的ip_proto也可以使用名称表示为:

ip_proto:PIM

6.3.5. ipv4.hdr

匹配整个IPv4 header的Sticky buffer。

示例规则:

alert ip any any -> any any (ipv4.hdr; content:”|3A|”; offset:9; depth:1; sid:1234; rev:5;)

这个例子检查IPv4 header的第9个字节的值是否为3A。它表示IPv4 protocol是ICMPv6。

6.3.6. ipv6.hdr

匹配整个IPv6 header的Sticky buffer。

6.3.7. id

通过id关键词,你可以匹配一个特定的IP ID值。这个ID标识主机发送出去的每个packet,并且每次发送ID都递增1。IP ID可以用来作为碎片标识数字。每个packet都有一个IP ID,并且当一个packet在网络中传输变成一些碎片时,所有这个packet的碎片都有相同的ID。通过这种方式,packet的接收者可以知道哪些碎片属于相同的packet。(IP ID不关心顺序,这种情况需要使用offset,它可以帮助分清碎片的顺序。)

id的格式:

id:<number>;

规则中的id示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”ET DELETED F5 BIG-IP 3DNS TCP Probe 1”; id: 1; dsize: 24; flags: S,12; content:”|00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00|”; window: 2048; reference:url,www.f5.com/f5products/v9intro/index.html; reference:url,doc.emergingthreats.net/2001609; classtype:misc-activity; sid:2001609; rev:13;)

6.3.8. geoip

geoip关键字允许(您)匹配网络流量的源、目的地或源和目的地IPv4地址,并查看它属于哪个国家。为了能够做到这一点,Suricata使用MaxMind的GeoIP2 API。

geoip语法:

geoip: src,RU;
geoip: both,CN,RU;
geoip: dst,CN,RU,IR;
geoip: both,US,CA,UK;
geoip: any,CN,IR;

因此,您可以使用以下内容来明确您想要匹配的方向:

OptionDescription
bothBoth directions have to match with the given geoip(s)
anyOne of the directions has to match with the given geoip(s).
destIf the destination matches with the given geoip.
srcThe source matches with the given geoip.

关键字只支持IPv4。由于使用MaxMind的GeoIP2 API,libmaxminddb必须编译进来。您必须下载并安装所需的GeoIP2或GeoLite2数据库版本。访问MaxMind网站https://dev.maxmind.com/geoip/geoip2/geolite2/获取详细信息。

您还必须在本地yaml配置文件中提供GeoIP2或GeoLite2数据库文件的位置(例如):

geoip-database: /usr/local/share/GeoIP/GeoLite2-Country.mmdb

6.3.9. fragbits (IP fragmentation)

使用fragbits关键字,可以检查碎片和保留位是否在IP header中设置。fragbits关键字应该放在规则的开头。fragbits用于修饰碎片机制。在将消息从一个Internet模块路由到另一个Internet模块时,可能会出现包大于网络所能处理的最大包大小的情况。在这种情况下,数据包可以以片段的形式发送。这个数据包大小的最大值称为最大传输单元(MTU)。

你可以匹配以下位:

M - More Fragments
D - Do not Fragment
R - Reserved Bit

匹配在这个位可以更指定以下修饰器:

+         match on the specified bits, plus any others
*         match if any of the specified bits are set
!         match if the specified bits are not set

格式:

fragbits:[*+!]<[MDR]>;

规则中的fragbits示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”ET EXPLOIT Invalid non-fragmented packet with fragment offset>0”; fragbits: M; fragoffset: >0; reference:url,doc.emergingthreats.net/bin/view/Main/2001022; classtype:bad-unknown; sid:2001022; rev:5; metadata:created_at 2010_07_30, updated_at 2010_07_30;)

6.3.10. fragoffset

使用fragoffset关键字,您可以匹配IP片段偏移字段的特定十进制值。如果您想要检查会话的第一个片段,您必须结合fragoffset 0和More Fragment(fragbits: M)选项。碎片偏移量字段便于重新组装。id用于确定哪个片段属于哪个包,而碎片偏移字段澄清了片段的顺序。

你可以使用以下修饰词:

<       match if the value is smaller than the specified value
>       match if the value is greater than the specified value
!       match if the specified value is not present

fragoffset格式:

fragoffset:[!|<|>]<number>;

规则中的fragoffset示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”ET EXPLOIT Invalid non-fragmented packet with fragment offset>0”; fragbits: M; fragoffset: >0; reference:url,doc.emergingthreats.net/bin/view/Main/2001022; classtype:bad-unknown; sid:2001022; rev:5; metadata:created_at 2010_07_30, updated_at 2010_07_30;)

6.3.11. tos

tos关键字可以匹配IP头tos字段的特定十进制值。tos关键字的值可以是0 - 255。IP报头的这个字段已经被rfc2474更新,以包含用于差异化服务功能。注意,字段的值被定义为最右边的2位的值为0。当为tos指定一个值时,确保该值符合这个规则。

例如,不是指定十进制值34(十六进制22),而是右移两次并使用十六进制88)。

可以用前导x指定十六进制值,例如x88。

tos的格式:

tos:[!]<number>;

规则中的tos示例:

alert ip any any -> any any (msg:”Differentiated Services Codepoint: Class Selector 1 (8)”; flow:established; tos:8; classtype:not-suspicious; sid:2600115; rev:1;)

带有否定值的tos示例:

alert ip any any -> any any (msg:”TGI HUNT non-DiffServ aware TOS setting”; flow:established,to_server; tos:!0; tos:!8; tos:!16; tos:!24; tos:!32; tos:!40; tos:!48; tos:!56; threshold:type limit, track by_src, seconds 60, count 1; classtype:bad-unknown; sid:2600124; rev:1;)

6.4. TCP Keywords

6.4.1. seq

seq关键字可以在签名中用于检查特定的TCP序列号。序列号是tcp连接的两个端点实际上随机生成的数字。客户端和服务器都创建一个序列号,序列号每发送一个字节就增加一个。所以两边的序号都不一样。这个序列号必须由连接的双方确认。通过序列号,TCP处理acknowledgement(确认), order(顺序)和 retransmission(重传)它的数字随着发送方发送的每一个数据字节而增加。seq帮助跟踪一个字节在数据流中的位置。如果SYN标志被设置为1,那么数据的第一个字节的序列号就是这个数字加上1(所以是2)。

例子:

seq:0;

签名中的seq示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL SCAN NULL”; flow:stateless; ack:0; flags:0; seq:0; reference:arachnids,4; classtype:attempted-recon; sid:2100623; rev:7;)

数据包中的seq示例(Wireshark):

6.4.2. ack

ack是tcp连接的另一端收到之前发送的所有(数据)字节的确认。在大多数情况下,TCP连接的每个包在第一个SYN之后都有一个ACK标志,并且ack-number随着每个新数据字节的接收而增加。ack关键字可以在签名中用于检查特定的TCP确认号。

ack的格式:

ack:1;

签名中的ack示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL SCAN NULL”; flow:stateless; ack:0; flags:0; seq:0; reference:arachnids,4; classtype:attempted-recon; sid:2100623; rev:7;)

包中的ack的例子(Wireshark):

6.4.3. window

window关键词用来指定TCP窗口大小。TCP窗口大小是一个用来控制数据流的机制。这个窗口大小由接收者设定(receiver advertised window size),并且表明了它可以接收的字节数量。在发送方可以发送相同数量的新数据之前,接收方必须首先确认此数据量。这种机制是用来防止接收器被数据溢出。窗口大小的值被限制在2到65.535字节。为了更好地利用带宽,可以使用更大的TCP窗口。

窗口关键字的格式:

window:[!]<number>;

一个规则中的窗口的例子:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL DELETED typot trojan traffic”; flow:stateless; flags:S,12; window:55808; reference:mcafee,100406; classtype:trojan-activity; sid:2182; rev:8;)

以上规则用于病毒检测:参考https://blog.csdn.net/richerg85/article/details/25079865

病毒名称:Trojan.Linux.Typot.a
类别: 木马病毒
破坏方法: 
  该病毒是在Linux操作系统下的木马,木马运行后每隔几秒就发送一个TCP包,其目的IP和源IP地址是随机的,这个包中存在固定的特征,包括 TCP window size等<在这里为55808>,同时,病毒会嗅探网络,如果发现TCP包的window size等于55808,就会在当前目录下生成一个文件<文件名为:r>,每隔24小时,病毒检测是否存在文件 “r”,如果存在,就会试图连接固定的IP地址<可能为木马的客户端>,如果连接成功,病毒就会删除文件:/tmp/……/a并退出

6.4.4 tcp.mss

匹配TCP MSS选项值。如果选项不存在,将不匹配。

关键字格式:

tcp.mss:<min>-<max>;
tcp.mss:[<|>]<number>;
tcp.mss:<value>;

示例规则:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (flow:stateless; flags:S,12; tcp.mss:<536; sid:1234; rev:5;)

6.4.5 tcp.hdr

粘贴缓冲区来匹配整个TCP报头。

示例规则:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (flags:S,12; tcp.hdr; content:”|02 04|”; offset:20; byte_test:2,<,536,0,big,relative; sid:1234; rev:5;)

This example starts looking after the fixed portion of the header, so into the variable sized options. There it will look for the MSS option (type 2, option len 4) and using a byte_test determine if the value of the option is lower than 536. The tcp.mss option will be more efficient, so this keyword is meant to be used in cases where no specific keyword is available.

6.5. UDP Keywords

6.5.1. udp.hdr

粘贴缓冲区匹配整个UDP头。

示例规则:

alert udp any any -> any any (udp.hdr; content:”|00 08|”; offset:4; depth:2; sid:1234; rev:5;)

这个例子匹配UDP头部的length字段。在这里length字段的值是8,意思是没有payload。也可以使用dsize:0;来达到同样的效果。

6.6. ICMP Keywords

ICMP (Internet Control Message Protocol) 是IP的一部分。在传输数据时,IP本身并不可靠(datagram数据报)。ICMP在出现问题时给予反馈。它不能阻止问题的发生,但是可以帮助搞清楚何时发生了什么问题。如果可靠性是必须的,那么建立在IP之上的协议就得自己考虑可靠性。ICMP消息被发送的情况有多种。例如,当目的不可达时,当没有足够的缓存去转发数据时,或者当一个数据报被分片发送但是不应该被分片发送时,等等,更多请参见message-types列表。

ICMP消息中有4个重要内容可以与对应的ICMP关键字进行匹配。它们是:type,code,id和sequence。

6.6.1. itype

itype关键字用于匹配特定的ICMP类型(数字)。ICMP有几种类型的消息,并且使用编号来表示每种消息。不同的消息因不同的名称而不同,但更重要的是数字值。有关更多信息,请参见带有消息类型和代码的表。

itype关键词的格式:

itype:min<>max;
itype:[<|>]<number>;

例子:(这个例子寻找一个大于10的ICMP类型)

itype:>10;

规则实例(Smurf攻击):

alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL SCAN Broadscan Smurf Scanner”; dsize:4; icmp_id:0; icmp_seq:0; itype:8; classtype:attempted-recon; sid:2100478; rev:4;)

以上规则用于病毒检测,参考:https://baike.baidu.com/item/Smurf%E6%94%BB%E5%87%BB/9112141?fr=aladdin

下面列出了撰写本文时已知的所有ICMP类型。最新的表格可以在IANA的网站上找到。

ICMP TypeName
0Echo Reply
3Destination Unreachable
4Source Quench
5Redirect
6Alternate Host Address
8Echo
9Router Advertisement
10Router Solicitation
11Time Exceeded
12Parameter Problem
13Timestamp
14Timestamp Reply
15Information Request
16Information Reply
17Address Mask Request
18Address Mask Reply
30Traceroute
31Datagram Conversion Error
32Mobile Host Redirect
33IPv6 Where-Are-You
34IPv6 I-Am-Here
35Mobile Registration Request
36Mobile Registration Reply
37Domain Name Request
38Domain Name Reply
39SKIP
40Photuris
41Experimental mobility protocols such as Seamoby

6.6.2. icode

你可以使用icode关键字匹配特定的ICMP code。ICMP消息的code阐明了该消息。它与icmp类型一起指示您正在处理的问题类型。每个icmp类型的代码都有不同的用途。

icode关键字格式:

icode:min<>max;
icode:[<|>]<number>;

示例:本示例查找大于5的ICMP code:

icode:>5;

规则中的icode关键字示例:

alert icmp $HOME_NET any -> $EXTERNAL_NET any (msg:”GPL MISC Time-To-Live Exceeded in Transit”; icode:0; itype:11; classtype:misc-activity; sid:2100449; rev:7;)

下面列出了所有ICMP类型的含义。表格中没有列举的ICMP code,表示只有一种ICMP type是0,它的含义如上表定义,意思是Echo Reply。最新的表格可以在IANA的网站上找到。

ICMP CodeICMP TypeDescription
30Net Unreachable
31Host Unreachable
32Protocol Unreachable
33Port Unreachable
34Fragmentation Needed and Don’t Fragment was Set
35Source Route Failed
36Destination Network Unknown
37Destination Host Unknown
38Source Host Isolated
39Communication with Destination Network is Administratively Prohibited
310Communication with Destination Host is Administratively Prohibited
311Destination Network Unreachable for Type of Service
312Destination Host Unreachable for Type of Service
313Communication Administratively Prohibited
314Host Precedence Violation
315Precedence cutoff in effect
50Redirect Datagram for the Network (or subnet)
51Redirect Datagram for the Host
52Redirect Datagram for the Type of Service and Network
53Redirect Datagram for the Type of Service and Host
90Normal router advertisement
916Doesn’t route common traffic
110Time to Live exceeded in Transit
111Fragment Reassembly Time Exceeded
120Pointer indicates the error
121Missing a Required Option
122Bad Length
400Bad SPI
401Authentication Failed
402Decompression Failed
403Decryption Failed
404Need Authentication
405Need Authorization

6.6.3. icmp_id

你可以使用icmp_id关键字匹配特定的ICMP id值。每个icmp包在发送时都得到一个id。在接收方收到数据包的那一刻,它将使用相同的id发送回复,以便发送方能够识别它并将其与正确的icmp请求连接起来。

icmp_id关键字的格式:

icmp_id:<number>;

示例:这个示例查找ICMP ID为0:

icmp_id:0;

规则中的icmp_id关键字示例:

alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL SCAN Broadscan Smurf Scanner”; dsize:4; icmp_id:0; icmp_seq:0; itype:8; classtype:attempted-recon; sid:2100478; rev:4;)

6.6.4. icmp_seq

你可以使用icmp_seq关键字检查ICMP序列号。ICMP消息都有序列号。这对于检查哪条回复消息属于哪条请求消息非常有用(与id一起)。

icmp_seq关键字的格式:

icmp_seq:<number>;

示例:这个示例查找ICMP序列为0:

icmp_seq:0;

规则中的icmp_seq示例:

alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:”GPL SCAN Broadscan Smurf Scanner”; dsize:4; icmp_id:0; icmp_seq:0; itype:8; classtype:attempted-recon; sid:2100478; rev:4;)

6.6.5. icmpv6.hdr

粘贴缓冲区,以匹配整个ICMPv6报头。

6.6.6. icmpv6.mtu

匹配ICMPv6 MTU可选值。如果MTU不存在,将不匹配。

关键字格式:

icmpv6.mtu:<min>-<max>;
icmpv6.mtu:[<|>]<number>;
icmpv6.mtu:<value>;

示例规则:

alert ip $EXTERNAL_NET any -> $HOME_NET any (icmpv6.mtu:<1280; sid:1234; rev:5;)

6.7. Payload Keywords

Payload关键词检查一个包或流的payload内容。

6.7.1. content

content关键字在签名中非常重要。在引号之间,你可以写上你希望签名匹配的内容。最简单的内容格式是:

content: "............";

可以在签名中使用多个content。

内容在字节上匹配。一个字节有256个不同的值(0-255)。你可以匹配所有字符; 从a到z,大写和小写以及所有特殊符号。但并不是所有的字节都是可打印字符。对于这些字节,可以使用十六进制表示法。许多编程语言使用0x00作为符号,其中0x表示它与二进制值有关,但是我们的规则语言使用|00|作为符号。这种表示法也可用于可打印字符。

例子:

|61| is a
|61 61| is aa
|41| is A
|21| is !
|0D| is carriage return
|0A| is line feed

有些字符不能在内容中使用,因为它们在签名中已经作为重要的标识符了。为了匹配这些字符,应该使用十六进制表示法。这些是:

"     |22|
;     |3B|
:     |3A|
|     |7C|

用大写字母书写十六进制表示法是一种惯例。

例如,要在签名的内容中写http://,你应该这样写:content:“http|3A|//”; 如果在签名中使用十六进制表示法,请确保始终将其放在管道符(|)之间。否则,符号将被视为内容的一部分。

举例:

content:"a|0D|bc";
content:"|61 0D 62 63|";
content:"a|0D|b|63|";

可以让签名检查整个有效负载是否与内容匹配,或者让签名检查有效负载的特定部分。这种情况我们稍后再谈。如果没有向签名添加任何特殊内容,它将尝试在有效负载的所有字节中查找匹配项。

drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:”ET TROJAN Likely Bot Nick in IRC (USA +..)”; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK “; pcre:”/NICK .*USA.*[0-9]{3,}/i”; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

默认情况下,模式匹配是区分大小写的。内容必须准确,否则将没有匹配。

图例:

可以使用!除去content的例外情况:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"Outdated Firefox on
Windows"; content:"User-Agent|3A| Mozilla/5.0 |28|Windows|3B| ";
content:"Firefox/3."; distance:0; content:!"Firefox/3.6.13";
distance:-10; sid:9000000; rev:1;)

可以看到以上例子中的content:!"Firefox/3.6.13";。它表示匹配到Firefox/3.但不包括Firefox/3.6.13时告警。

!注意:必须在内容中对下列字符进行转义:; \\ "

6.7.2. nocase

如果不想区分大写和小写字符,可以使用nocase。关键字nocase是一个content修饰符。

这个关键字的格式是:

nocase;

你必须把它放在你想修改的内容之后,比如:

content: "abc"; nocase;

nocase示例:

对签名中的其他content不产生影响。

6.7.3. depth

depth关键词是一个绝对位置content修饰符。它在content之后出现。depth修饰符的值强制使用数字类型,例如:

depth:12;

depth之后的数字指定了从有效负载开始检查的字节数。

例子:

6.7.4. startsWith

关键字startswith类似于depth。它不接受参数,并且必须紧随content关键字。它修饰content,以精确匹配缓冲区的开始位置。

例子:

content:"GET|20|"; startswith;

startswith是一个简写符号,等同于:

content:"GET|20|"; depth:4; offset:0;

startswith不能与depth,offset,within或者distance在同一pattern中混用。

6.7.5. endswith

endswith关键字类似于isdataat:!1,relative;。它不接受参数,并且必须跟在content关键字之后。它修饰content以精确匹配缓冲区的末尾。

例子:

content:".php"; endswith;

endswith是一个简写符号,等同于:

content:".php"; isdatat:!1,relative;

endswith不能和offset, within 或者 distance 在同一pattern中混用。

6.7.6. offset

offset关键字指定将从哪个字节检查有效负载以查找匹配。例如:offset:3; 检查第四个以及之后的字节。

关键字偏移和深度可以结合使用,经常一起使用。

例如:

content:"def"; offset:3; depth:3;

如果在签名中使用了它,它将检查从第3字节到第6字节的有效负载。

6.7.7. distance

TODO

6.7.8. within

TODO

6.7.9. isdataat

TODO

6.7.10. bsize

TODO

6.7.11. dsize

使用dsize关键字,你可以匹配数据包有效负载的大小。例如,你可以使用关键字来查找有效载荷的异常大小。这可以方便地检测缓冲区溢出。

格式:

dsize:<number>;

规则中dsize的例子:

alert udp $EXTERNAL_NET any -> $HOME_NET 65535 (msg:”GPL DELETED EXPLOIT LANDesk Management Suite Alerting Service buffer overflow”; dsize:>268; reference: bugtraq,23483; reference: cve,2007-1674; classtype: attempted-admin; sid:100000928; rev:1;)

6.7.12. byte_test

TODO

6.7.13. byte_math

TODO

6.7.14. byte_jump

TODO

6.7.15.

以上是关于Suricata/Snort规则参考的主要内容,如果未能解决你的问题,请参考以下文章

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

Android 逆向ART 脱壳 ( DexClassLoader 脱壳 | DexClassLoader 构造函数 | 参考 Dalvik 的 DexClassLoader 类加载流程 )(代码片段

与另一个片段通信的片段接口

如何从活动中更改片段中视图的可见性

如何通过代码设置片段标签?

Prometheus配置文件