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

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

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消息。例如当目标不可达、没有足够的缓冲区容量转发数据、数据报不应分片但被分片发送等。更多内容