有效载荷关键词 ================ .. role:: example-rule-emphasis 有效载荷关键词用于检查数据包或流内容的有效载荷部分。 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,也可以只检查特定部分。如果不做特殊设置,默认会检查整个有效载荷的所有字节。 .. container:: example-rule 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; :example-rule-emphasis:`content:"NICK ";` pcre:"/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;) 默认情况下模式匹配是区分大小写的。content必须精确匹配,否则不会触发。 .. image:: payload-keywords/content2.png 图例: .. image:: payload-keywords/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中必须转义: ``;`` ``\`` ``"`` nocase ------ 如果不区分大小写,可以使用nocase。nocase是一个content修饰符。 格式:: nocase; 必须放在要修饰的content之后,如:: content: "abc"; nocase; nocase示例: .. image:: payload-keywords/content3.png 不会影响规则中的其他content匹配项。 depth ----- depth是一个绝对content修饰符,位于content之后。必须指定一个数值:: depth:12; depth后的数字表示从有效载荷起始处检查多少字节。 示例: .. image:: payload-keywords/content4.png startswith ---------- ``startswith``关键词类似于``depth``。不需要参数,必须跟在``content``后。它将``content``修改为必须在缓冲区起始处精确匹配。 示例:: content:"GET|20|"; startswith; ``startswith``是以下写法的简写:: content:"GET|20|"; depth:4; offset:0; ``startswith``不能与``depth``、``offset``、``within``或``distance``混合用于同一模式。 endswith -------- ``endswith``关键词类似于``isdataat:!1,relative;``。不需要参数,必须跟在``content``后。它将``content``修改为必须在缓冲区末尾精确匹配。 示例:: content:".php"; endswith; ``endswith``是以下写法的简写:: content:".php"; isdataat:!1,relative; ``endswith``不能与``offset``、``within``或``distance``混合用于同一模式。 offset ------ offset关键词指定从有效载荷的哪个字节开始检查匹配。例如offset:3;表示从第4个字节开始检查。 .. image:: payload-keywords/content5.png offset和depth可以组合使用,经常一起出现。 示例:: content:"def"; offset:3; depth:3; 如果在规则中使用,会检查有效载荷从第3字节到第6字节。 .. image:: payload-keywords/content6.png distance -------- distance是一个相对content修饰符,表示当前content与前一个content之间的关系。distance影响前一个匹配之后的位置。必须指定一个数值,该值决定了从前一个匹配结束后的多少字节处开始检查当前匹配。distance只决定Suricata开始查找模式的位置。例如distance:5;表示模式可以出现在前一个匹配结束后的5字节之后的任何位置。要限制查找范围,可以使用'within'。 distance的绝对值必须小于等于1MB(1048576)。 distance示例: .. image:: payload-keywords/distance5.png .. image:: payload-keywords/distance4.png .. image:: payload-keywords/distance.png .. image:: payload-keywords/distance1.png distance也可以是负数,用于检查部分相同内容的匹配(见示例)或完全在前的内容匹配。这种情况不太常用,通常可以用其他关键词实现相同效果。 .. image:: payload-keywords/distance3.png within ------ within是相对于前一个匹配的修饰符。必须指定一个数值。使用within确保只有在设定字节数内找到匹配时才触发。within不能为0。 within的绝对值必须小于等于1MB(1048576)。 示例: .. image:: payload-keywords/within2.png within匹配示例: .. image:: payload-keywords/within1.png 第二个content必须在前一个content的'3字节内'出现。 如前所述,distance和within可以很好地组合使用。如果要让Suricata检查有效载荷的特定部分,使用within。 .. image:: payload-keywords/within_distance.png .. image:: payload-keywords/within_distance2.png rawbytes -------- rawbytes关键词没有实际效果,只是为了兼容使用它的规则(如Snort规则)。 isdataat -------- isdataat关键词用于检查有效载荷的特定位置是否还有数据。以一个数字(位置)开始,可选地跟随'relative'和rawbytes选项。使用'relative'可以相对于前一个匹配的位置检查数据。 可以使用以下两种形式:: isdataat:512; isdataat:50, relative; 第一个示例检查有效载荷的第512字节。第二个示例检查前一个匹配后的50字节处。 也可以在isdataat前使用否定(!)。 .. image:: payload-keywords/isdataat1.png absent ------ ``absent``关键词检查粘性缓冲区不存在。可以不带参数使用,仅匹配不存在的缓冲区: ``absent``规则示例: .. container:: example-rule alert http any any -> any any (msg:"HTTP request without referer"; :example-rule-emphasis:`http.referer; absent;` sid:1; rev:1;) 可以带"or_else"参数,匹配不存在的缓冲区或后续的否定内容: .. container:: example-rule alert http any any -> any any (msg:"HTTP request without referer"; :example-rule-emphasis:`http.referer; absent: or_else;` content: !"abc"; sid:1; rev:1;) 对于文件(如``file.data``),absent表示事务中没有文件。 bsize ----- ``bsize``关键词可以匹配缓冲区的长度。这为内容匹配增加了精确度,以前可以使用``isdataat``实现。 bsize使用:ref:`64位无符号整数 `。 可以指定可选运算符;如果未指定,默认为'='。使用关系运算符(如'<'、'>'或'<>'(范围))时,bsize值将使用关系运算符进行比较。范围是排他的。 如果一个或多个``content``关键词位于``bsize``之前,将检查每个content的出现,如果内容长度和bsize值不匹配,将引发错误。 格式:: bsize:; bsize:=; bsize:<; bsize:>; bsize:<>; ``bsize``规则示例: .. container:: example-rule 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;) .. container:: example-rule alert dns any any -> any any (msg:"test bsize rule"; dns.query; content:"short"; bsize:<10; sid:124; rev:1;) .. container:: example-rule alert dns any any -> any any (msg:"test bsize rule"; dns.query; content:"longer string"; bsize:>10; sid:125; rev:1;) .. container:: example-rule alert dns any any -> any any (msg:"test bsize rule"; dns.query; content:"middle"; bsize:6<>15; sid:126; rev:1;) 强调范围如何工作:在上面的示例中,如果``bsize``大于6且小于15,将发生匹配。 dsize ----- 使用dsize关键词可以匹配数据包有效载荷/数据的大小。例如,可以查找等于某个n('dsize:n')、不等于('dsize:!n')、小于('dsize:n')的异常有效载荷大小。这在检测缓冲区溢出时可能很方便。 使用应用/流层协议关键词(如http.uri)时不能使用dsize。 dsize使用:ref:`16位无符号整数 `。 格式:: dsize:[<>!]number; || dsize:min<>max; dsize值示例: .. container:: example-rule 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;) .. _byte_test: byte_test --------- ``byte_test``关键词提取``<字节数>``并在特定``<偏移量>``处对``<测试值>``执行由``<运算符>``选择的操作。``<位掩码值>``应用于提取的字节(在应用运算符之前),最终结果将根据``<位掩码值>``中尾随``0``的数量右移一位。 格式:: byte_test:<字节数> | <变量名>, [!]<运算符>, <测试值>, <偏移量> [,relative] \ [,<字节序>][, string, <数字类型>][, dce][, bitmask <位掩码值>]; +----------------+------------------------------------------------------------------------------+ | <字节数> | 从数据包中选择的要转换的字节数 | | | 或byte_extract/byte_math变量的名称。 | +----------------+------------------------------------------------------------------------------+ | <运算符> | | | | - [!] 否定可以前缀其他运算符 | | | - < 小于 | | | - > 大于 | | | - = 等于 | | | - <= 小于或等于 | | | - >= 大于或等于 | | | - & 位与 | | | - ^ 位或 | +----------------+------------------------------------------------------------------------------+ | <值> | 测试转换值的目标值[接受十六进制或十进制] | +----------------+------------------------------------------------------------------------------+ | <偏移量> | 有效载荷中的字节数 | +----------------+------------------------------------------------------------------------------+ | [relative] | 相对于最后一个内容匹配的偏移量 | +----------------+------------------------------------------------------------------------------+ | [字节序] | 读取的数字类型: | | | - big (最高有效字节在最低地址) | | | - little (最高有效字节在最高地址) | +----------------+------------------------------------------------------------------------------+ | [string] <数字>| | | | - hex - 转换后的字符串以十六进制表示 | | | - dec - 转换后的字符串以十进制表示 | | | - oct - 转换后的字符串以八进制表示 | +----------------+------------------------------------------------------------------------------+ | [dce] | 允许DCE模块确定字节顺序 | +----------------+------------------------------------------------------------------------------+ | [bitmask] | 对转换后的字节应用AND运算符 | +----------------+------------------------------------------------------------------------------+ 示例:: 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;) 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 <值>]; +-----------------------+-----------------------------------------------------------------------+ | <字节数> | 从数据包中选择的字节数 | | | 或byte_extract变量的名称。 | +-----------------------+-----------------------------------------------------------------------+ | <偏移量> | 有效载荷中的字节数 | +-----------------------+-----------------------------------------------------------------------+ | oper <运算符> | 要执行的数学运算: +, -, \*, /, <<, >> | +-----------------------+-----------------------------------------------------------------------+ | rvalue <右值> | 执行数学运算的值 | +-----------------------+-----------------------------------------------------------------------+ | result <结果变量> | 存储计算值的位置 | +-----------------------+-----------------------------------------------------------------------+ | [relative] | 相对于最后一个内容匹配的偏移量 | +-----------------------+-----------------------------------------------------------------------+ | [endian <类型>] | - big (最高有效字节在最低地址) | | | - little (最高有效字节在最高地址) | | | - dce (允许DCE模块确定字节顺序) | +-----------------------+-----------------------------------------------------------------------+ | [string <数字类型>] | | | | - hex 转换后的数据以十六进制表示