10.7. 有效载荷关键词

有效载荷关键词用于检查数据包或流内容的有效载荷部分。

10.7.1. content

content关键词在规则中非常重要。在引号之间可以指定需要匹配的内容。最简单的格式如下:

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

一条规则中可以包含多个content匹配项。

content匹配的是字节数据。一个字节有256种可能的值(0-255)。可以匹配所有字符,包括大小写字母a-z以及所有特殊符号。但并非所有字节都是可打印字符,对于不可打印字符需要使用十六进制表示法。许多编程语言使用0x00表示法(0x表示二进制值),而规则语言使用``|00|``表示法。这种表示法也可用于可打印字符。

示例:

|61| 表示 a
|61 61| 表示 aa
|41| 表示 A
|21| 表示 !
|0D| 表示回车符
|0A| 表示换行符

有些字符在规则中有特殊含义,不能直接用于content中,需要使用十六进制表示法:

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

通常十六进制表示法使用大写字母。

例如要在规则中匹配``http://,应写作: ``content: "http|3A|//"; 如果在规则中使用十六进制表示法,必须确保将其放在管道符之间,否则会被视为字面内容。

示例:

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

可以让规则检查整个有效载荷是否匹配content,也可以只检查特定部分。如果不做特殊设置,默认会检查整个有效载荷的所有字节。

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必须精确匹配,否则不会触发。

../_images/content2.png

图例:

../_images/Legenda_rules.png

也可以在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.6.13时会触发告警。

Note

以下字符在content中必须转义: ; \ "

10.7.2. nocase

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

格式:

nocase;

必须放在要修饰的content之后,如:

content: "abc"; nocase;

nocase示例:

../_images/content3.png

不会影响规则中的其他content匹配项。

10.7.3. depth

depth是一个绝对content修饰符,位于content之后。必须指定一个数值:

depth:12;

depth后的数字表示从有效载荷起始处检查多少字节。

示例:

../_images/content4.png

10.7.4. startswith

startswith``关键词类似于``depth。不需要参数,必须跟在``content``后。它将``content``修改为必须在缓冲区起始处精确匹配。

示例:

content:"GET|20|"; startswith;

``startswith``是以下写法的简写:

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

startswith``不能与``depthoffset``within``或``distance``混合用于同一模式。

10.7.5. endswith

endswith``关键词类似于``isdataat:!1,relative;。不需要参数,必须跟在``content``后。它将``content``修改为必须在缓冲区末尾精确匹配。

示例:

content:".php"; endswith;

``endswith``是以下写法的简写:

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

endswith``不能与``offset``within``或``distance``混合用于同一模式。

10.7.6. offset

offset关键词指定从有效载荷的哪个字节开始检查匹配。例如offset:3;表示从第4个字节开始检查。

../_images/content5.png

offset和depth可以组合使用,经常一起出现。

示例:

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

如果在规则中使用,会检查有效载荷从第3字节到第6字节。

../_images/content6.png

10.7.7. distance

distance是一个相对content修饰符,表示当前content与前一个content之间的关系。distance影响前一个匹配之后的位置。必须指定一个数值,该值决定了从前一个匹配结束后的多少字节处开始检查当前匹配。distance只决定Suricata开始查找模式的位置。例如distance:5;表示模式可以出现在前一个匹配结束后的5字节之后的任何位置。要限制查找范围,可以使用'within'。

distance的绝对值必须小于等于1MB(1048576)。

distance示例:

../_images/distance5.png ../_images/distance4.png ../_images/distance.png ../_images/distance1.png

distance也可以是负数,用于检查部分相同内容的匹配(见示例)或完全在前的内容匹配。这种情况不太常用,通常可以用其他关键词实现相同效果。

../_images/distance3.png

10.7.8. within

within是相对于前一个匹配的修饰符。必须指定一个数值。使用within确保只有在设定字节数内找到匹配时才触发。within不能为0。

within的绝对值必须小于等于1MB(1048576)。

示例:

../_images/within2.png

within匹配示例:

../_images/within1.png

第二个content必须在前一个content的'3字节内'出现。

如前所述,distance和within可以很好地组合使用。如果要让Suricata检查有效载荷的特定部分,使用within。

../_images/within_distance.png ../_images/within_distance2.png

10.7.9. rawbytes

rawbytes关键词没有实际效果,只是为了兼容使用它的规则(如Snort规则)。

10.7.10. isdataat

isdataat关键词用于检查有效载荷的特定位置是否还有数据。以一个数字(位置)开始,可选地跟随'relative'和rawbytes选项。使用'relative'可以相对于前一个匹配的位置检查数据。

可以使用以下两种形式:

isdataat:512;

isdataat:50, relative;

第一个示例检查有效载荷的第512字节。第二个示例检查前一个匹配后的50字节处。

也可以在isdataat前使用否定(!)。

../_images/isdataat1.png

10.7.11. absent

``absent``关键词检查粘性缓冲区不存在。可以不带参数使用,仅匹配不存在的缓冲区:

``absent``规则示例:

alert http any any -> any any (msg:"HTTP request without referer"; http.referer; absent; sid:1; rev:1;)

可以带"or_else"参数,匹配不存在的缓冲区或后续的否定内容:

alert http any any -> any any (msg:"HTTP request without referer"; http.referer; absent: or_else; content: !"abc"; sid:1; rev:1;)

对于文件(如``file.data``),absent表示事务中没有文件。

10.7.12. bsize

``bsize``关键词可以匹配缓冲区的长度。这为内容匹配增加了精确度,以前可以使用``isdataat``实现。

bsize使用:ref:64位无符号整数 <rules-integer-keywords>

可以指定可选运算符;如果未指定,默认为'='。使用关系运算符(如'<'、'>'或'<>'(范围))时,bsize值将使用关系运算符进行比较。范围是排他的。

如果一个或多个``content``关键词位于``bsize``之前,将检查每个content的出现,如果内容长度和bsize值不匹配,将引发错误。

格式:

bsize:<number>;
bsize:=<number>;
bsize:<<number>;
bsize:><number>;
bsize:<lo-number><><hi-number>;

``bsize``规则示例:

alert dns any any -> any any (msg:"bsize exact buffer size"; dns.query; content:"google.com"; bsize:10; sid:1; rev:1;)

alert dns any any -> any any (msg:"bsize less than value"; dns.query; content:"google.com"; bsize:<25; sid:2; rev:1;)

alert dns any any -> any any (msg:"bsize buffer less than or equal value"; dns.query; content:"google.com"; bsize:<=20; sid:3; rev:1;)

alert dns any any -> any any (msg:"bsize buffer greater than value"; dns.query; content:"google.com"; bsize:>8; sid:4; rev:1;)

alert dns any any -> any any (msg:"bsize buffer greater than or equal value"; dns.query; content:"google.com"; bsize:>=8; sid:5; rev:1;)

alert dns any any -> any any (msg:"bsize buffer range value"; dns.query; content:"google.com"; bsize:8<>20; sid:6; rev:1;)

alert dns any any -> any any (msg:"test bsize rule"; dns.query; content:"short"; bsize:<10; sid:124; rev:1;)

alert dns any any -> any any (msg:"test bsize rule"; dns.query; content:"longer string"; bsize:>10; sid:125; rev:1;)

alert dns any any -> any any (msg:"test bsize rule"; dns.query; content:"middle"; bsize:6<>15; sid:126; rev:1;)

强调范围如何工作:在上面的示例中,如果``bsize``大于6且小于15,将发生匹配。

10.7.13. dsize

使用dsize关键词可以匹配数据包有效载荷/数据的大小。例如,可以查找等于某个n('dsize:n')、不等于('dsize:!n')、小于('dsize:<n')或大于('dsize:>n')的异常有效载荷大小。这在检测缓冲区溢出时可能很方便。

使用应用/流层协议关键词(如http.uri)时不能使用dsize。

dsize使用:ref:16位无符号整数 <rules-integer-keywords>

格式:

dsize:[<>!]number; || dsize:min<>max;

dsize值示例:

alert tcp any any -> any any (msg:"dsize exact size"; dsize:10; sid:1; rev:1;)

alert tcp any any -> any any (msg:"dsize less than value"; dsize:<10; sid:2; rev:1;)

alert tcp any any -> any any (msg:"dsize less than or equal value"; dsize:<=10; sid:3; rev:1;)

alert tcp any any -> any any (msg:"dsize greater than value"; dsize:>8; sid:4; rev:1;)

alert tcp any any -> any any (msg:"dsize greater than or equal value"; dsize:>=10; sid:5; rev:1;)

alert tcp any any -> any any (msg:"dsize range value"; dsize:8<>20; sid:6; rev:1;)

alert tcp any any -> any any (msg:"dsize not equal value"; dsize:!9; sid:7; rev:1;)

10.7.14. byte_test

``byte_test``关键词提取``<字节数>``并在特定``<偏移量>``处对``<测试值>``执行由``<运算符>``选择的操作。``<位掩码值>``应用于提取的字节(在应用运算符之前),最终结果将根据``<位掩码值>``中尾随``0``的数量右移一位。

格式:

byte_test:<字节数> | <变量名>, [!]<运算符>, <测试值>, <偏移量> [,relative] \
[,<字节序>][, string, <数字类型>][, dce][, bitmask <位掩码值>];

示例:

alert tcp any any -> any any \
       (msg:"Byte_Test Example - Num = Value"; \
       content:"|00 01 00 02|"; byte_test:2,=,0x01,0;)

alert tcp any any -> any any \
       (msg:"Byte_Test Example - Num = Value relative to content"; \
       content:"|00 01 00 02|"; byte_test:2,=,0x03,2,relative;)

alert tcp any any -> any any \
       (msg:"Byte_Test Example - Num != Value"; content:"|00 01 00 02|"; \
       byte_test:2,!=,0x06,0;)

alert tcp any any -> any any \
       (msg:"Byte_Test Example - Detect Large Values"; content:"|00 01 00 02|"; \
       byte_test:2,>,1000,1,relative;)

alert tcp any any -> any any \
       (msg:"Byte_Test Example - Lowest bit is set"; \
       content:"|00 01 00 02|"; byte_test:2,&,0x01,12,relative;)

alert tcp any any -> any any (msg:"Byte_Test Example - Compare to String"; \
       content:"foobar"; byte_test:4,=,1337,1,relative,string,dec;)

10.7.15. byte_math

``byte_math``关键词提供了对提取值执行数学运算的能力,可以使用现有变量或指定值。

当包含``relative``时,必须有先前的``content``或``pcre``匹配。

注意:如果``oper``是``/``且除数为0,则``byte_math``关键词永远不会匹配。

结果可以存储在结果变量中,并在规则后面的其他选项中被引用。

关键词

修饰符

content

offset,depth,distance,within

byte_test

offset,value

byte_jump

offset

isdataat

offset

格式:

byte_math:bytes <字节数> | <变量名> , offset <偏移量>, oper <运算符>, rvalue <右值>, \
      result <结果变量> [, relative] [, endian <字节序>] [, string <数字类型>] \
      [, dce] [, bitmask <>];
| - dce (允许DCE模块确定字节顺序) |