.. role:: example-rule-emphasis

10.3. IP 关键字

10.3.1. ttl

ttl 关键字用于检查数据包头部中的特定 IP 生存时间值。格式如下:

ttl:<数字>;

例如:

ttl:10;

ttl 使用 无符号8位整数

在 ttl 关键字末尾可以输入要匹配的值。生存时间值决定了数据包在互联网系统中存在的最大时间。如果该字段设为0,则数据包必须被销毁。生存时间基于跳数计算。数据包每经过一个跳点/路由器,其 TTL 计数器就会减1。该机制的目的是限制数据包的存在时间,防止数据包陷入无限路由循环。

规则中使用 ttl 关键字的示例:

alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"TTL为0的IP数据包"; ttl:0; classtype:misc-activity; sid:1; rev:1;)

10.3.2. ipopts

ipopts 关键字用于检查是否设置了特定的 IP 选项。ipopts 必须用在规则开头。每条规则只能匹配一个选项。可匹配的选项包括:

IP 选项

描述

rr

记录路由

eol

列表结束

nop

无操作

ts

时间戳

sec

IP安全

esec

IP扩展安全

lsrr

松散源路由

ssrr

严格源路由

satid

流标识符

any

任意IP选项被设置

ipopts 关键字的格式:

ipopts: <名称>;

例如:

ipopts: ts;

规则中使用 ipopts 的示例:

alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"带时间戳选项的IP数据包"; ipopts:ts; classtype:misc-activity; sid:2; rev:1;)

10.3.3. sameip

每个数据包都有源IP地址和目标IP地址。有时源IP可能与目标IP相同。sameip 关键字可以检查源IP地址是否与目标IP地址相同。sameip 关键字的格式是:

sameip;

规则中使用 sameip 的示例:

alert ip any any -> any any (msg:"源和目标IP相同的IP数据包"; sameip; classtype:bad-unknown; sid:3; rev:1;)

10.3.4. ip_proto

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

 1     ICMP        互联网控制报文
 6     TCP         传输控制协议
17     UDP         用户数据报
47     GRE         通用路由封装
50     ESP         IPv6封装安全载荷
51     AH          IPv6认证头
58     IPv6-ICMP   IPv6的ICMP

完整协议列表及编号参见 http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers

规则中使用 ip_proto 的示例:

alert ip any any -> any any (msg:"协议为1的IP数据包"; ip_proto:1; classtype:bad-unknown; sid:5; rev:1;)

命名形式的示例:

ip_proto:ICMP;

10.3.5. ipv4.hdr

粘性缓冲区,用于匹配IPv4头部中包含的内容。

示例规则:

alert ip any any -> any any (msg:"IPv4头部关键字示例"; ipv4.hdr; content:"|06|"; offset:9; depth:1; sid:1; rev:1;)

此示例检查IPv4头部第10字节是否为06值,表示IPv4协议是TCP。

10.3.6. ipv6.hdr

粘性缓冲区,用于匹配IPv6头部中包含的内容。

示例规则:

alert ip any any -> any any (msg:"IPv6头部关键字示例"; ipv6.hdr; content:"|06|"; offset:6; depth:1; sid:1; rev:1;)

此示例检查IP64头部第7字节是否为06值,表示IPv6协议是TCP。

10.3.7. id

id 关键字可以匹配特定的IP ID值。ID用于标识主机发送的每个数据包,通常每发送一个数据包就递增1。IP ID用作分片标识号。每个数据包都有一个IP ID,当数据包被分片时,该数据包的所有分片都具有相同的ID。这样,数据包的接收方就知道哪些分片属于同一个数据包。(IP ID不负责顺序,这时会使用偏移量来明确分片的顺序。)

id 的格式:

id:<数字>;

规则中使用 id 的示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"id关键字示例"; id:1; content:"content|3a 20|"; fast_pattern; classtype:misc-activity; sid:12; rev:1;)

10.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;

选项

描述

both

源和目标都必须匹配给定的geoip

any

源或目标必须匹配给定的geoip

dest

目标匹配给定的geoip

src

源匹配给定的geoip

geoip 目前仅支持IPv4。由于它使用MaxMind的GeoIP2 API,必须编译libmaxminddb。您需要下载并安装所需的GeoIP2或GeoLite2数据库版本。访问MaxMind网站https://dev.maxmind.com/geoip/geolite2-free-geolocation-data获取详情。

还需要在YAML配置文件中提供GeoIP2或GeoLite2数据库文件的本地路径,例如:

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

10.3.9. fragbits (IP分片)

fragbits 关键字可以检查IP头部中的分片和保留位是否设置。fragbits 关键字应放在规则开头。fragbits 用于修改分片机制。在从一个互联网模块路由消息到另一个模块时,可能会遇到数据包大于网络能处理的最大数据包大小的情况。这时,数据包可以分片发送。这个最大数据包大小称为最大传输单元(MTU)。

可以匹配以下位:

M - 更多分片
D - 不分片
R - 保留位

可以使用以下修饰符更精确地匹配这些位:

+         匹配指定的位及其他位
*         匹配任何指定的位
!         匹配未设置指定的位

格式:

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

规则中使用 fragbits 的示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"fragbits关键字示例 分片偏移>0的非分片数据包"; fragbits:M; fragoffset:>0; classtype:bad-unknown; sid:123; rev:1;)

10.3.10. fragoffset

fragoffset 关键字可以匹配IP分片偏移字段的特定十进制值。如果要检查会话的第一个分片,需要将fragoffset 0与More Fragment选项结合使用。分片偏移字段便于重组。id用于确定哪些分片属于哪个数据包,分片偏移字段则明确分片的顺序。

可以使用以下修饰符:

<       如果值小于指定值则匹配
>       如果值大于指定值则匹配
!       如果不存在指定值则匹配

fragoffset 的格式:

fragoffset:[!|<|>]<数字>;

规则中使用 fragoffset 的示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"fragoffset关键字示例 分片偏移>0的无效非分片数据包"; fragbits:M; fragoffset:>0; classtype:bad-unknown; sid:13; rev:1;)

10.3.11. tos

tos 关键字可以匹配IP头部TOS字段的特定十进制值。tos 关键字的值为0-255。IP头部的这个字段已被 rfc2474 更新,以支持 差分服务 功能。注意该字段的值定义时最右2位为0。指定tos值时,请确保值符合这一点。

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

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

tos 的格式:

tos:[!]<数字>;

规则中使用 tos 的示例:

alert ip any any -> any any (msg:"tos关键字示例 tos值8"; flow:established; tos:8; classtype:not-suspicious; sid:123; rev:1;)

使用否定值的 tos 示例:

alert ip any any -> any any (msg:"带否定内容的tos关键字示例"; flow:established,to_server; tos:!8; classtype:bad-unknown; sid:14; rev:1;)

10.4. TCP 关键字

10.4.1. tcp.flags

tcp.flags 关键字检查特定的 TCP标志位

可以检查以下标志位:

标志

描述

F

FIN - 结束

S

SYN - 同步序列号

R

RST - 重置

P

PSH - 推送

A

ACK - 确认

U

URG - 紧急

C

CWR - 拥塞窗口减少

E

ECE - ECN回显

0

无TCP标志设置

可以设置以下修饰符来改变匹配条件:

修饰符

描述

+

匹配这些位及其他位

*

匹配任何这些位

!

匹配未设置这些位

为了处理如ECN这样的会话初始化数据包的规则编写,其中SYN数据包发送时设置了CWR和ECE标志,可以使用选项掩码,通过附加逗号和掩码值。例如,检查SYN标志而不考虑保留位值的规则是 tcp.flags:S,CE;

tcp.flags 的格式:

tcp.flags:[modifier]<测试标志>[,<忽略标志>];
tcp.flags:[!|*|+]<FSRPAUCE0>[,<FSRPAUCE>];

示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"tcp.flags签名示例"; tcp.flags:FPU,CE; classtype:misc-activity; sid:1; rev:1;)

也可以通过使用 prefilter 关键字将 tcp.flags 内容用作 fast_pattern。有关 prefilter 使用的更多信息,请参阅 fast_pattern。 示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"tcp.flags签名示例"; tcp.flags:FPU,CE; prefilter; classtype:misc-activity; sid:1; rev:1;)

10.4.2. seq

seq 关键字可用于签名中检查特定的TCP序列号。序列号是TCP连接两端几乎随机生成的数字。客户端和服务器都创建一个序列号,每发送一个字节就增加1。因此双方的序列号是不同的。这个序列号必须被连接双方确认。

通过序列号,TCP处理确认、顺序和重传。其数值随发送方发送的每个数据字节而增加。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):

../_images/Wireshark_seq.png

10.4.3. ack

ack 关键字可用于签名中检查特定的TCP确认号。

ack 是对TCP连接另一方发送的所有先前(数据)字节接收的确认。在大多数情况下,TCP连接的每个数据包在第一个SYN之后都有一个ACK标志和一个ack-number,随着每个新数据字节的接收而增加。

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

../_images/Wireshark_ack.png

10.4.4. window

window 关键字用于检查特定的TCP窗口大小。

TCP窗口大小是控制数据流的机制。窗口由接收方设置(接收方通告窗口大小),表示可以接收的字节数。这些数据必须先被接收方确认,发送方才能发送相同数量的新数据。

该机制用于防止接收方被数据淹没。窗口大小的值有限,可以是2到65,535字节。要更好地利用带宽,可以使用更大的TCP窗口。

window 关键字的格式:

window:[!]<数字>;

规则中使用 window 的示例:

alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL DELETED typot特洛伊木马流量"; flow:stateless; flags:S,12; window:55808; reference:mcafee,100406; classtype:trojan-activity; sid:2182; rev:8;)

10.4.5. tcp.mss

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

tcp.mss 使用 无符号16位整数

关键字的格式:

tcp.mss:<最小>-<最大>;
tcp.mss:[<|>]<数字>;
tcp.mss:<>;

示例规则:

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

10.4.6. tcp.wscale

匹配TCP窗口缩放选项值。如果选项不存在则不匹配。

tcp.wscale 使用 无符号8位整数

关键字的格式:

tcp.wscale:<最小>-<最大>;
tcp.wscale:[<|>]<数字>;
tcp.wscale:<>;

示例规则:

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

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

此示例从头部固定部分之后开始查找,即进入可变大小的选项部分。在那里查找MSS选项(类型2,选项长度4),并使用byte_test确定选项值是否小于536。tcp.mss 选项会更高效,因此此关键字用于没有特定关键字可用的情况。

10.5. UDP 关键字

10.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头部的长度字段。长度为8表示没有负载。也可以用 dsize:0; 匹配。

10.6. ICMP 关键字

ICMP(互联网控制报文协议)是IP的一部分。IP本身在传递数据(数据报)时并不可靠。ICMP在出现问题时提供反馈。它不能防止问题发生,但有助于理解问题所在。如果需要可靠性,使用IP的协议必须自行处理可靠性。在不同情况下会发送ICMP消息。例如当目标不可达、没有足够的缓冲区容量转发数据、数据报不应分片但被分片发送等。更多内容