Suricata规则编写——数据包头部关键字

来源:互联网 发布:易观千帆数据哪来的 编辑:程序博客网 时间:2024/06/05 11:00

1.简介

本文介绍suricata支持的IP、TCP、ICMP三种协议的数据包头关键字,http协议由于比较常用,关键字也比较多所以后面单独介绍,而其他应用层协议暂无特定的关键字。

2.IP协议关键字

首先需要对IP协议有一定的了解,网际协议-维基百科,RFC 791,IPv4-维基百科。

IPv4协议的格式如下:

这里写图片描述

<code class="hljs mathematica has-numbering">     <span class="hljs-number">0</span>                   <span class="hljs-number">1</span>                   <span class="hljs-number">2</span>                   <span class="hljs-number">3</span>        <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span>    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |<span class="hljs-keyword">Version</span>|  IHL  |Type of Service|          <span class="hljs-keyword">Total</span> <span class="hljs-keyword">Length</span>         |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |         Identification        |Flags|      Fragment <span class="hljs-keyword">Offset</span>    |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |  Time to Live |    Protocol   |         Header Checksum       |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                       Source Address                          |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                    Destination Address                        |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                    <span class="hljs-keyword">Options</span>                    |    <span class="hljs-keyword">Padding</span>    |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                    Example Internet Datagram Header</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li></ul>

2.1 ttl

ttl关键字用于检测IP数据包头部的TTL(time to live)字段,表示这个数据包能在网络中的最大生存时间,每经过一个路由器便会减1,当这个数值变为0时数据包便会被丢弃,ttl字段是防止数据包在不可达的情况下一直占用网络资源。ttl关键字的格式为:

<code class="hljs css has-numbering"><span class="hljs-tag">ttl</span><span class="hljs-pseudo">:number</span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

2.2 ipopts

ipopts关键字检查的是IP数据包中可选字段中设置的选项,格式如下,每条规则只能使用一次ipopts关键字,但可以使用“|”来分隔多个选项:

<code class="hljs css has-numbering"><span class="hljs-tag">ipopts</span><span class="hljs-pseudo">:opt_name</span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

所有的选项名为:

<code class="hljs sql has-numbering">rr - Record Routeeol - <span class="hljs-operator"><span class="hljs-keyword">End</span> <span class="hljs-keyword">of</span> listnop - <span class="hljs-keyword">No</span> Opts - <span class="hljs-keyword">Time</span> Stampsec - IP Securityesec - IP Extended Securitylsrr - Loose Source Routinglsrre - Loose Source Routing (<span class="hljs-keyword">For</span> MS99-<span class="hljs-number">038</span> <span class="hljs-keyword">and</span> CVE-<span class="hljs-number">1999</span>-<span class="hljs-number">0909</span>)ssrr - Strict Source Routingsatid - Stream identifier<span class="hljs-keyword">any</span> - <span class="hljs-keyword">any</span> IP options <span class="hljs-keyword">are</span> <span class="hljs-keyword">set</span></span></code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li></ul>

2.3 sameip

sameip关键字检查源IP地址与目的IP地址是否相同,仅在相同的情况下才进行匹配,直接在规则中写上sameip;就可以了。正如下面这个例子:

这里写图片描述

2.4 ip_proto

ip_proto关键字用来匹配IP数据包的协议部分,下面列出了部分协议的编号和名字,详细的编号和协议可以参考维基百科的List of IP protocol numbers:

<code class="hljs mathematica has-numbering"> <span class="hljs-number">1</span>     ICMP        Internet <span class="hljs-keyword">Control</span> <span class="hljs-keyword">Message</span>  <span class="hljs-number">6</span>     TCP         Transmission <span class="hljs-keyword">Control</span> Protocol    <span class="hljs-number">17</span>     UDP         User Datagram<span class="hljs-number">47</span>     GRE         <span class="hljs-keyword">General</span> Routing Encapsulation<span class="hljs-number">50</span>     ESP         Encap Security Payload for IPv6   <span class="hljs-number">51</span>     AH          Authentication Header for Ipv6<span class="hljs-number">58</span>     IPv6-ICMP   ICMP for Ipv6</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li></ul>

ip_proto可以使用协议的编号或名称,比如ip_proto:1;ip_proto:ICMP;的作用相同。

2.5 id

在IP数据包中Identification字段是标识一个数据包的特殊值,每发送一个数据包这个字段的值便会加1,有时当上层协议的数据包长度大于一个特定值时IP协议便会将数据分片到多个IP数据包中进行传输,接收端收到后根据ID号相同的数据包进行重新组装,而id关键字正是用来检查这个字段的值。格式为:

<code class="hljs applescript has-numbering"><span class="hljs-property">id</span>:<span class="hljs-type">number</span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

在这里要多说几句,由于IP协议不是可靠的传输协议,只能保证尽可能的将数据包传输到目的地址,所以当IP分片的数据包较多的时候万一其中有一个分片数据包丢失就会导致所有数据包重新传输,这是因为其没有重传机制,不知道是哪个数据包丢失了,这样一来造成大量的资源和时间的浪费,因此在IPv6中取消了IP数据包分片机制,超过了特定长度直接抛弃。

TCP协议是可靠传输协议,并且具有超时重传机制,因此使用了TCP协议会尽量避免使用IP分片,这里用到了TCP报文重组技术。就是在传输层或更上层的协议中的数据超出了单个IP数据包的最大传输长度(MTU,Maximal Transmit Unit),则在TCP协议中对其分段,并且使用窗口管理,使得丢失的数据包可以重传。但是像UDP、ICMP等协议也是不可靠传输,因此有时还是需要使用IP协议的分片机制的。

2.6 fragbits

IP数据包的分片机制中有着重要作用的是Flags和Fragment Offset两个字段。Flags字段占3位,最低位保留,必须为0;第二位为0表示该数据包支持分片,1表示不可分片;第三位为0表示当前数据包时分片的最后一个包,为1表示后面还有分片的包。

fragbits关键字使用R/D/M分别匹配Flags的三位:

<code class="hljs mathematica has-numbering">R 保留位Reserved Bit<span class="hljs-keyword">D</span> 不可分片<span class="hljs-keyword">Do</span> not Fragment M More Fragments</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li></ul>

并且还可以使用量词来进行多种情况的匹配:

<code class="hljs diff has-numbering"><span class="hljs-addition">+ 匹配列出的所有位</span>* 匹配列出的任意一位<span class="hljs-change">! 不匹配列出的所有位</span></code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li></ul>

fragbits关键字的格式为:

<code class="hljs css has-numbering"><span class="hljs-tag">fragbits</span>:<span class="hljs-attr_selector">[*+!]</span><<span class="hljs-attr_selector">[MDR]</span>>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

下面来列举一些例子:

<code class="hljs avrasm has-numbering"><span class="hljs-label">fragbits:</span>+RM<span class="hljs-comment">; 表示匹配Flags标志位为000的数据包</span><span class="hljs-label">fragbits:</span>!M<span class="hljs-comment">; 表示匹配标志位为**0的数据包,此处*表示通配符,即匹配不可分片或可分片的最后一个数据包</span></code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li></ul>

2.7 fragoffset

IP头格式中紧跟着Flags标志的是13位的Fragment Offset字段,这个字段和Flags共同使用,表示当前数据包中的内容在原始数据包中所在的偏移。可以使用<,>和!来作为数字的操作符。fragoffset关键字的格式为:

<code class="hljs xml has-numbering">fragoffset:[!|<span class="hljs-tag"><<span class="hljs-title">|</span>></span>]<span class="hljs-tag"><<span class="hljs-title">number</span>></span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

一般情况下fragoffset和fragbits关键字一起使用,如下例子表示匹配分片会话的第一个数据包:

<code class="hljs css has-numbering"><span class="hljs-tag">fragbits</span><span class="hljs-pseudo">:M</span>;<span class="hljs-tag">fragoffset</span><span class="hljs-pseudo">:0</span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

2.8 Geoip

Geoip技术通过网络流量中的IP地址来判断其所属的国家和城市,suricata使用的是Maxmind提供的GeoIP API。如下例子,其中国家代码可以参考ISO 3166-1:

<code class="hljs http has-numbering"><span class="hljs-attribute">geoip</span>: <span class="hljs-string">src, RU;</span><span class="hljs-attribute">geoip</span>: <span class="hljs-string">both, CN, RU;</span><span class="hljs-attribute">geoip</span>: <span class="hljs-string">dst, CN, RU, IR;</span><span class="hljs-attribute">geoip</span>: <span class="hljs-string">both, US, CA, UK;</span><span class="hljs-attribute">geoip</span>: <span class="hljs-string">any, CN, IR;</span></code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li></ul>

上面用到了src、both、dst和any所表示的意思分别为:

<code class="hljs glsl has-numbering">src 表示源IP地址匹配列出的国家dst 表示目的IP地址匹配列出的国家both 表示无论是源IP还是目的IP地址都匹配列出的国家<span class="hljs-built_in">any</span> 表示源IP或目的IP地址匹配列出的国家</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li></ul>

3.TCP协议关键字

TCP协议的格式和介绍——TCP协议-维基百科,RFC 793。

TCP协议的数据包格式:

这里写图片描述

<code class="hljs mathematica has-numbering">    <span class="hljs-number">0</span>                   <span class="hljs-number">1</span>                   <span class="hljs-number">2</span>                   <span class="hljs-number">3</span>    <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |          Source Port          |       Destination Port        |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                        <span class="hljs-keyword">Sequence</span> <span class="hljs-keyword">Number</span>                        |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                    Acknowledgment <span class="hljs-keyword">Number</span>                      |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |  Data |           |U|A|P|R|S|F|                               |   | <span class="hljs-keyword">Offset</span>| Reserved  |R|<span class="hljs-keyword">C</span>|S|S|Y|<span class="hljs-keyword">I</span>|            Window             |   |       |           |G|<span class="hljs-keyword">K</span>|H|T|<span class="hljs-keyword">N</span>|<span class="hljs-keyword">N</span>|                               |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |           Checksum            |         Urgent Pointer        |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                    <span class="hljs-keyword">Options</span>                    |    <span class="hljs-keyword">Padding</span>    |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   |                             data                              |   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+                            TCP Header <span class="hljs-keyword">Format</span></code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li><li>10</li><li>11</li><li>12</li><li>13</li><li>14</li><li>15</li><li>16</li><li>17</li><li>18</li><li>19</li><li>20</li><li>21</li></ul>

3.1 seq

seq关键字用来检查TCP数据包的序列号(Sequence Number),序列号对于TCP协议的可靠传输、重传机制和确认都有着非常重要的作用,序列号由客户端第一次发起TCP的SYN请求时随机产生,而后的增长都是在这个基础上每发送一个字节加1。seq关键字可以写成如下格式:

<code class="hljs css has-numbering"><span class="hljs-tag">seq</span><span class="hljs-pseudo">:1</span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

来自维基百科的这张图可以很清楚的理解序列号在TCP协议中的作用:

这里写图片描述

3.2 ack

和seq关键字类似,ack关键字是检查确认号(Acknowledgment Number)的,在上一张图中也已经表现的很清楚了。

3.3 window

window关键字用来匹配TCP数据包中的Window字段,格式如下:

<code class="hljs xml has-numbering">window:[!]<span class="hljs-tag"><<span class="hljs-title">number</span>></span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

Window字段由数据包的接收者设置,表明其能接受的最大的字节数,防止一次性接收过多的数据导致缓冲区溢出,其数值取2-65535之间。

4.ICMP关键字

ICMP和IP协议都处于网络层,它用于在网络中发送控制消息,并对产生的问题进行反馈和检查,可以更容易地采取措施来解决问题,ICMP是不可靠的传输协议。参考互联网控制消息协议-维基百科,RFC 792。

由于ICMP可以反馈很多网络中出现的问题,所以其数据包格式也会有一定的不同,Type为3时的格式如下:

<code class="hljs 1c has-numbering">    <span class="hljs-number">0</span>                   <span class="hljs-number">1</span>                   <span class="hljs-number">2</span>                   <span class="hljs-number">3</span>    <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span> <span class="hljs-number">2</span> <span class="hljs-number">3</span> <span class="hljs-number">4</span> <span class="hljs-number">5</span> <span class="hljs-number">6</span> <span class="hljs-number">7</span> <span class="hljs-number">8</span> <span class="hljs-number">9</span> <span class="hljs-number">0</span> <span class="hljs-number">1</span>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   <span class="hljs-string">|     Type      |     Code      |          Checksum             |</span>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   <span class="hljs-string">|                             unused                            |</span>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+   <span class="hljs-string">|      Internet Header + 64 bits of Original Data Datagram      |</span>   +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>

4.1 itype

itype关键字用于检测ICMP报文的Type类型,ICMP协议有多种类型以反馈不同的问题,下面列出几个典型的类型,更多类型请参考上面的维基百科和RFC文档:

<code class="hljs dos has-numbering"><span class="hljs-number">0</span>   <span class="hljs-keyword">echo</span>响应(<span class="hljs-winutils">ping</span>使用到)<span class="hljs-number">3</span>   目标不可达<span class="hljs-number">4</span>   ICMP拥塞控制<span class="hljs-number">5</span>   路径控制<span class="hljs-number">8</span>   <span class="hljs-keyword">echo</span>请求<span class="hljs-number">11</span>  ICMP超时</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li></ul>

itype关键字有两种格式:

<code class="hljs xml has-numbering">itype:min<span class="hljs-tag"><></span>max; itype:[<span class="hljs-tag"><<span class="hljs-title">|</span>></span>]<span class="hljs-tag"><<span class="hljs-title">number</span>></span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li></ul>

比如itype:>10;表示匹配ICMP类型大于10的报文。

4.2 icode

ICMP在每个Type下还用code对各个问题进行更加精确的划分。比如Type为3下还分了很多种原因导致的目的地不可达:

这里写图片描述

icode的关键字的用法和itype类似:

<code class="hljs xml has-numbering">icode:min<span class="hljs-tag"><></span>max; icode:[<span class="hljs-tag"><<span class="hljs-title">|</span>></span>]<span class="hljs-tag"><<span class="hljs-title">number</span>></span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li><li>2</li></ul>

4.3 icmp_id

当ICMP报文的Type值为0或8时有一个ID,当报文的接收者收到一个ICMP报文时他会使用相同的ID给发送者返回相关的反馈信息。格式为:

<code class="hljs css has-numbering"><span class="hljs-tag">icmp_id</span><span class="hljs-pseudo">:number</span>;</code><ul class="pre-numbering" style="display: block;"><li>1</li></ul>

4.4 icmp_seq

icmp_seq通常和icmp_id一起使用,格式也和icmp_id相同,也是为了确认ICMP反馈的数据包对应的request数据包信息。

5.小结

本文简单了解了IP/TCP/ICMP三种协议,在此基础上学习了suricata针对这三种协议头的部分字段的检测。有时这些字段的检测并不能确定一次攻击,但是在很多恶意攻击的前面阶段可以使用这些字段写的规则来完成一些状态的设置,方便后续更精确的对恶意攻击进行检测,同时还能还原整个攻击过程,提高整体的检测效果。

参考链接

https://redmine.openinfosecfoundation.org/projects/suricata/wiki/Header_keywords
http://zh.wikipedia.org/wiki/%E7%BD%91%E9%99%85%E5%8D%8F%E8%AE%AE
http://www.rfcsearch.org/rfcview/RFC/791.html#3.1
http://zh.wikipedia.org/wiki/IPv4#.E9.A6.96.E9.83.A8
http://en.wikipedia.org/wiki/List_of_IP_protocol_numbers
http://zh.wikipedia.org/wiki/%E4%BC%A0%E8%BE%93%E6%8E%A7%E5%88%B6%E5%8D%8F%E8%AE%AE
http://tools.ietf.org/html/rfc793
http://zh.wikipedia.org/wiki/%E4%BA%92%E8%81%94%E7%BD%91%E6%8E%A7%E5%88%B6%E6%B6%88%E6%81%AF%E5%8D%8F%E8%AE%AE
http://tools.ietf.org/html/rfc792

0 0
原创粉丝点击