.. role:: example-rule-emphasis IP 关键字 ----------- ttl ^^^ ttl 关键字用于检查数据包头部中的特定 IP 生存时间值。格式如下:: ttl:<数字>; 例如:: ttl:10; ttl 使用 :ref:`无符号8位整数 `。 在 ttl 关键字末尾可以输入要匹配的值。生存时间值决定了数据包在互联网系统中存在的最大时间。如果该字段设为0,则数据包必须被销毁。生存时间基于跳数计算。数据包每经过一个跳点/路由器,其 TTL 计数器就会减1。该机制的目的是限制数据包的存在时间,防止数据包陷入无限路由循环。 规则中使用 ttl 关键字的示例: .. container:: example-rule alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"TTL为0的IP数据包"; :example-rule-emphasis:`ttl:0;` classtype:misc-activity; sid:1; rev:1;) ipopts ^^^^^^ ipopts 关键字用于检查是否设置了特定的 IP 选项。ipopts 必须用在规则开头。每条规则只能匹配一个选项。可匹配的选项包括: ========= ============================= IP 选项 描述 ========= ============================= rr 记录路由 eol 列表结束 nop 无操作 ts 时间戳 sec IP安全 esec IP扩展安全 lsrr 松散源路由 ssrr 严格源路由 satid 流标识符 any 任意IP选项被设置 ========= ============================= ipopts 关键字的格式:: ipopts: <名称>; 例如:: ipopts: ts; 规则中使用 ipopts 的示例: .. container:: example-rule alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"带时间戳选项的IP数据包"; :example-rule-emphasis:`ipopts:ts;` classtype:misc-activity; sid:2; rev:1;) sameip ^^^^^^ 每个数据包都有源IP地址和目标IP地址。有时源IP可能与目标IP相同。sameip 关键字可以检查源IP地址是否与目标IP地址相同。sameip 关键字的格式是:: sameip; 规则中使用 sameip 的示例: .. container:: example-rule alert ip any any -> any any (msg:"源和目标IP相同的IP数据包"; :example-rule-emphasis:`sameip;` classtype:bad-unknown; sid:3; rev:1;) 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 的示例: .. container:: example-rule alert ip any any -> any any (msg:"协议为1的IP数据包"; :example-rule-emphasis:`ip_proto:1;` classtype:bad-unknown; sid:5; rev:1;) 命名形式的示例:: ip_proto:ICMP; ipv4.hdr ^^^^^^^^ 粘性缓冲区,用于匹配IPv4头部中包含的内容。 示例规则: .. container:: example-rule alert ip any any -> any any (msg:"IPv4头部关键字示例"; :example-rule-emphasis:`ipv4.hdr; content:"|06|"; offset:9; depth:1;` sid:1; rev:1;) 此示例检查IPv4头部第10字节是否为06值,表示IPv4协议是TCP。 ipv6.hdr ^^^^^^^^ 粘性缓冲区,用于匹配IPv6头部中包含的内容。 示例规则: .. container:: example-rule alert ip any any -> any any (msg:"IPv6头部关键字示例"; :example-rule-emphasis:`ipv6.hdr; content:"|06|"; offset:6; depth:1;` sid:1; rev:1;) 此示例检查IP64头部第7字节是否为06值,表示IPv6协议是TCP。 id ^^ id 关键字可以匹配特定的IP ID值。ID用于标识主机发送的每个数据包,通常每发送一个数据包就递增1。IP ID用作分片标识号。每个数据包都有一个IP ID,当数据包被分片时,该数据包的所有分片都具有相同的ID。这样,数据包的接收方就知道哪些分片属于同一个数据包。(IP ID不负责顺序,这时会使用偏移量来明确分片的顺序。) id 的格式:: id:<数字>; 规则中使用 id 的示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"id关键字示例"; :example-rule-emphasis:`id:1;` content:"content|3a 20|"; fast_pattern; classtype:misc-activity; sid:12; rev:1;) 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 fragbits (IP分片) ^^^^^^^^^^^^^^^^^^^ fragbits 关键字可以检查IP头部中的分片和保留位是否设置。fragbits 关键字应放在规则开头。fragbits 用于修改分片机制。在从一个互联网模块路由消息到另一个模块时,可能会遇到数据包大于网络能处理的最大数据包大小的情况。这时,数据包可以分片发送。这个最大数据包大小称为最大传输单元(MTU)。 可以匹配以下位:: M - 更多分片 D - 不分片 R - 保留位 可以使用以下修饰符更精确地匹配这些位:: + 匹配指定的位及其他位 * 匹配任何指定的位 ! 匹配未设置指定的位 格式:: fragbits:[*+!]<[MDR]>; 规则中使用 fragbits 的示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"fragbits关键字示例 分片偏移>0的非分片数据包"; :example-rule-emphasis:`fragbits:M;` fragoffset:>0; classtype:bad-unknown; sid:123; rev:1;) fragoffset ^^^^^^^^^^ fragoffset 关键字可以匹配IP分片偏移字段的特定十进制值。如果要检查会话的第一个分片,需要将fragoffset 0与More Fragment选项结合使用。分片偏移字段便于重组。id用于确定哪些分片属于哪个数据包,分片偏移字段则明确分片的顺序。 可以使用以下修饰符:: < 如果值小于指定值则匹配 > 如果值大于指定值则匹配 ! 如果不存在指定值则匹配 fragoffset 的格式:: fragoffset:[!|<|>]<数字>; 规则中使用 fragoffset 的示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"fragoffset关键字示例 分片偏移>0的无效非分片数据包"; fragbits:M; :example-rule-emphasis:`fragoffset:>0;` classtype:bad-unknown; sid:13; rev:1;) tos ^^^ tos 关键字可以匹配IP头部TOS字段的特定十进制值。tos 关键字的值为0-255。IP头部的这个字段已被 `rfc2474 `_ 更新,以支持 `差分服务 `_ 功能。注意该字段的值定义时最右2位为0。指定tos值时,请确保值符合这一点。 例如,不要指定十进制值34(十六进制22),而是右移两位并使用十进制136(十六进制88)。 可以用前导`x`指定十六进制值,如`x88`。 tos 的格式:: tos:[!]<数字>; 规则中使用 tos 的示例: .. container:: example-rule alert ip any any -> any any (msg:"tos关键字示例 tos值8"; flow:established; :example-rule-emphasis:`tos:8;` classtype:not-suspicious; sid:123; rev:1;) 使用否定值的 tos 示例: .. container:: example-rule alert ip any any -> any any (msg:"带否定内容的tos关键字示例"; flow:established,to_server; :example-rule-emphasis:`tos:!8;` classtype:bad-unknown; sid:14; rev:1;) TCP 关键字 ------------ 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:[!|*|+][,]; 示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"tcp.flags签名示例"; :example-rule-emphasis:`tcp.flags:FPU,CE;` classtype:misc-activity; sid:1; rev:1;) 也可以通过使用 `prefilter` 关键字将 `tcp.flags` 内容用作 fast_pattern。有关 `prefilter` 使用的更多信息,请参阅 :doc:`prefilter-keywords`。 示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"tcp.flags签名示例"; :example-rule-emphasis:`tcp.flags:FPU,CE; prefilter;` classtype:misc-activity; sid:1; rev:1;) seq ^^^ ``seq`` 关键字可用于签名中检查特定的TCP序列号。序列号是TCP连接两端几乎随机生成的数字。客户端和服务器都创建一个序列号,每发送一个字节就增加1。因此双方的序列号是不同的。这个序列号必须被连接双方确认。 通过序列号,TCP处理确认、顺序和重传。其数值随发送方发送的每个数据字节而增加。seq有助于跟踪数据流中字节的位置。如果SYN标志设为1,则第一个数据字节的序列号是这个数字加1(即2)。 示例:: seq:0; 签名中使用 seq 的示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL SCAN NULL"; flow:stateless; ack:0; flags:0; :example-rule-emphasis:`seq:0;` reference:arachnids,4; classtype:attempted-recon; sid:2100623; rev:7;) 数据包中使用 seq 的示例(Wireshark): .. image:: header-keywords/Wireshark_seq.png ack ^^^ ``ack`` 关键字可用于签名中检查特定的TCP确认号。 ``ack`` 是对TCP连接另一方发送的所有先前(数据)字节接收的确认。在大多数情况下,TCP连接的每个数据包在第一个SYN之后都有一个ACK标志和一个ack-number,随着每个新数据字节的接收而增加。 ``ack`` 的格式:: ack:1; 签名中使用 ``ack`` 的示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL SCAN NULL"; flow:stateless; :example-rule-emphasis:`ack:0;` flags:0; seq:0; reference:arachnids,4; classtype:attempted-recon; sid:2100623; rev:7;) 数据包中使用 ``ack`` 的示例(Wireshark): .. image:: header-keywords/Wireshark_ack.png window ^^^^^^ ``window`` 关键字用于检查特定的TCP窗口大小。 TCP窗口大小是控制数据流的机制。窗口由接收方设置(接收方通告窗口大小),表示可以接收的字节数。这些数据必须先被接收方确认,发送方才能发送相同数量的新数据。 该机制用于防止接收方被数据淹没。窗口大小的值有限,可以是2到65,535字节。要更好地利用带宽,可以使用更大的TCP窗口。 window 关键字的格式:: window:[!]<数字>; 规则中使用 window 的示例: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (msg:"GPL DELETED typot特洛伊木马流量"; flow:stateless; flags:S,12; :example-rule-emphasis:`window:55808;` reference:mcafee,100406; classtype:trojan-activity; sid:2182; rev:8;) tcp.mss ^^^^^^^ 匹配TCP MSS选项值。如果选项不存在则不匹配。 ``tcp.mss`` 使用 :ref:`无符号16位整数 `。 关键字的格式:: tcp.mss:<最小>-<最大>; tcp.mss:[<|>]<数字>; tcp.mss:<值>; 示例规则: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (flow:stateless; flags:S,12; :example-rule-emphasis:`tcp.mss:<536;` sid:1234; rev:5;) tcp.wscale ^^^^^^^^^^ 匹配TCP窗口缩放选项值。如果选项不存在则不匹配。 ``tcp.wscale`` 使用 :ref:`无符号8位整数 `。 关键字的格式:: tcp.wscale:<最小>-<最大>; tcp.wscale:[<|>]<数字>; tcp.wscale:<值>; 示例规则: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (flow:stateless; flags:S,12; :example-rule-emphasis:`tcp.wscale:>10;` sid:1234; rev:5;) tcp.hdr ^^^^^^^ 粘性缓冲区,用于匹配整个TCP头部。 示例规则: .. container:: example-rule alert tcp $EXTERNAL_NET any -> $HOME_NET any (flags:S,12; :example-rule-emphasis:`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` 选项会更高效,因此此关键字用于没有特定关键字可用的情况。 UDP 关键字 ------------ udp.hdr ^^^^^^^ 粘性缓冲区,用于匹配整个UDP头部。 示例规则: .. container:: example-rule alert udp any any -> any any (:example-rule-emphasis:`udp.hdr; content:"|00 08|"; offset:4; depth:2;` sid:1234; rev:5;) 此示例匹配UDP头部的长度字段。长度为8表示没有负载。也可以用 `dsize:0;` 匹配。 ICMP 关键字 ------------- ICMP(互联网控制报文协议)是IP的一部分。IP本身在传递数据(数据报)时并不可靠。ICMP在出现问题时提供反馈。它不能防止问题发生,但有助于理解问题所在。如果需要可靠性,使用IP的协议必须自行处理可靠性。在不同情况下会发送ICMP消息。例如当目标不可达、没有足够的缓冲区容量转发数据、数据报不应分片但被分片发送等。更多内容