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

图例:

也可以在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示例:

不会影响规则中的其他content匹配项。
10.7.3. depth¶
depth是一个绝对content修饰符,位于content之后。必须指定一个数值:
depth:12;
depth后的数字表示从有效载荷起始处检查多少字节。
示例:

10.7.4. startswith¶
startswith``关键词类似于``depth
。不需要参数,必须跟在``content``后。它将``content``修改为必须在缓冲区起始处精确匹配。
示例:
content:"GET|20|"; startswith;
``startswith``是以下写法的简写:
content:"GET|20|"; depth:4; offset:0;
startswith``不能与``depth
、offset
、``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个字节开始检查。

offset和depth可以组合使用,经常一起出现。
示例:
content:"def"; offset:3; depth:3;
如果在规则中使用,会检查有效载荷从第3字节到第6字节。

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




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

10.7.8. within¶
within是相对于前一个匹配的修饰符。必须指定一个数值。使用within确保只有在设定字节数内找到匹配时才触发。within不能为0。
within的绝对值必须小于等于1MB(1048576)。
示例:

within匹配示例:

第二个content必须在前一个content的'3字节内'出现。
如前所述,distance和within可以很好地组合使用。如果要让Suricata检查有效载荷的特定部分,使用within。


10.7.9. rawbytes¶
rawbytes关键词没有实际效果,只是为了兼容使用它的规则(如Snort规则)。
10.7.10. isdataat¶
isdataat关键词用于检查有效载荷的特定位置是否还有数据。以一个数字(位置)开始,可选地跟随'relative'和rawbytes选项。使用'relative'可以相对于前一个匹配的位置检查数据。
可以使用以下两种形式:
isdataat:512;
isdataat:50, relative;
第一个示例检查有效载荷的第512字节。第二个示例检查前一个匹配后的50字节处。
也可以在isdataat前使用否定(!)。

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 <值>];