Snort规则
⼀、Snort简介
如果病毒⼀样,⼤多数⼊侵⾏为都具有某种特征,Snort的规则就是⽤这些特征的有关信息构建的。⼊侵者会刘勇已知的系统弱点数据库吗,如果⼊侵者试图利⽤这些弱点来实施攻击,也可以作为⼀些特征。这些特征可能出现在包的头部,也可能出现在载荷中。Snort的检测系统是基于规则的,⽽规则是基于特征的。Snort规则可以⽤来检测数据包的不同部分。Snort 1.x可以分析第3等和第4层的信息,但是不能分析应⽤层协议。Snort 2.x增加了对应⽤层头部的⽀持。所有的数据包根据类型的不同按顺序与规则⽐对。
规则可以⽤来产⽣告警信息、记录⽇志,或者使包通过(pass):对Snort来说,也就是悄悄丢弃(drop),通过在这⾥的意义与防⽕墙或路由器上的意义是不同的。在防⽕墙和路由器中,通过和丢弃是两个相反的概念。规则⽂件通常放置在f⽂件中,你可以⽤其他规则⽂件,然后⽤主配置⽂件引⽤它们
(#include 的⽅式,在snort 2.x主要是⽤过主⽂件引⽤)。
⼆、规则⽰例
2.1 第⼀个不可⽤规则
这⾥有⼀个⾮常不好⽤的规则,事实上,也许是最差的规则,但是它可以很好地检测snort是否正常⼯作,并可以产⽣告警:
alert ip any any -> any any (msg: "IP Packet detected";)
这个规则使每当捕获⼀个IP包都产⽣告警信息,下⾯简要解释⼀下该条规则所⽤的语句:
"alert"表⽰如果包与条件匹配,就产⽣⼀个告警信息。条件由下⾯的语句定义
"ip"表⽰规则奖杯⽤在所有的IP包上
第⼀个"any"是对IP包源地址部分的条件定义,表⽰来⾃任何⼀个IP地址的IP包都符合条件,任何IP包都符合本条件
第⼆个"any"⽤来定义源端⼝号,表⽰匹配任何(0 ~ 65535)端⼝号,本条规则匹配IP报⽂,所以端⼝号其实⽆任何意义,因为端⼝号只针对传输层协议(TCP 、UDP)⽣效
第三个"any"是对IP包⽬的地址部分的条件地址,any表⽰这条规则匹配所有的⽬的地址
第四个"any"⽤来定义⽬的端⼝条件,在此条规则中同样不⽣效
最后⼀部分是规则的选项,并包含⼀条将被记录的告警信息
2.2 规则的结构
所有的规则都可以分为两个逻辑组成部分:规则头部和规则选项
规则选项
规则头部
规则头部规则选项
规则的头部包含规则所做的动作的信息,也可以包含于包所对⽐的⼀些条件。选项部分通常包含⼀个告警信息以及包的哪个部分被⽤来产⽣这个信息。⼀条规则可以⽤来探测⼀个或多个类型的⼊侵活动,⼀个好的规则可以⽤来探测多种⼊侵特征。
端⼝⽅向
⽅向地址
地址端⼝
端⼝
地址端⼝
动作
动作协议
协议地址
动作部分表⽰,当规则与包⽐对并不符合条件时,会采取什么类型的动作。通常的动作时产⽣告警或记录⽇志或向其他规则发出请求。
协议部分⽤来在⼀个特定协议的包上应⽤规则。这是规则所涉及的第⼀个条件,⼀些可以⽤到的协议如:IP,ICMP,UDP,TCP等
地址部分定义源或⽬的地址。地址可以是⼀个主机,⼀些主机的地址或者⽹络地址。你也可以⽤这些部分将某些地址从⽹络中排除。注意,在规则中有两个地址段,依赖于⽅向决定地址是源或者是⽬的,例如,⽅向段的值是"->"那么左边的地址就是源地址,右边的地址就是⽬的地址。
如果协议是TCP、UDP,端⼝部分⽤来确定规则所对应的包的源及⽬的端⼝。如果是⽹络层协议,如IP或ICMP,端⼝号就没有意义了。
⽅向部分⽤来确定哪⼀边的地址和端⼝是源,哪⼀边是⽬的在。
⽰例:
alert icmp any any -> any any (msg: "Ping with TTL=100"; ttl:100;)
括号之前的部分叫做规则头部,括号中的部分叫做规则选项。头部⼀次包括下⾯部分:
规则的动作:在这个规则中,动作是alert(告警),就是如果符合下⾯的条件,就会产⽣告警。记住如果产⽣告警,默认的情况下是会记录⽇志的。
协议:在这个规则中,协议时ICMP,也就是说这条规则仅仅对ICMP包有效,如果⼀个包的协议不是ICMP,Snort探测引擎就不会理会这个包已节省CPU事件。协议部分在你对某种协议的包应⽤snort规则的时候是⾮常重要的。
⽅向。这在个⽰例中,⽅向⽤->表⽰从左向右的⽅向,表⽰在这个符号的左⾯部分是源,右⾯是⽬的,也表⽰规则引⽤在从源到⽬的的包上。如果是<-,那么久相反。注意,也可以⽤<>来表⽰规则将应⽤在所有⽅向上。
⽬的地址和端⼝,在这个⽰例中。它们都是"any",表⽰规则并不关⼼它们的⽬的地址。在这个规则中,由于any的作⽤,⽅向段并没有实际的作⽤,因为它将被应⽤在所有⽅向的ICMP包上。
在括号中的选项部分表⽰:如果包符合TTL=100的条件就产⽣⼀条包含⽂字:"Ping with TTL=100"的告警。TTL是IP包头部字段。
三、规则详解
3.1 规则头部
3.1.1 规则动作
动作是snort规则中的第⼀个部分,它表⽰规则的条件符合的时候,将会有什么样的动作产⽣。Snort有5个预定义动作,你也可以定义⾃⼰的动作,需要注意的是,Snort 1.x 和 2.x对规则的应⽤是不同的,在1.x中,只要包符合第⼀个条件,它就会做出动作,然后就不再管它,尽管它可能符合多个条件;在2.x中,只有包和所有的相应规则对⽐后,才根据最严重的情况发出告警。
3.1.1.1 pass
这个动作⾼速Snort不理会这个包,这个动作在你不想检查特定的包的时候可以加快Snort的操作速度。
例如:如果你在⽹络中有⼀台包含⼀些弱点的主机,⽤来检测⽹络安全漏洞,可能希望不理会对这台机器的攻击,pass规则这时就可以⽤到了。
3.1.1.2 log
log动作⽤来记录包,记录包有不同的⽅式,例如:可以记录到⽂件或者数据库。根据命令⾏参数和配置⽂件,包可以被记录为不同的详细程度。你可以⽤"snort -?"命令来查看你所⽤的Snort版本的命令⾏参数。
3.1.1.3 alert
alert动作⽤来在⼀个包符合规则条件时发送告警信息。告警的发送有多种⽅式,例如可以发送到⽂件或者控制台。log动作与alert动作不同在于:alert动作是发送告警然后记录包,log动作仅仅记录包。
3.1.1.4 dynamic
dynamic规则动作由其他activate动作的规则调⽤,在正常情况下,他们不会被⽤来检测包。⼀个动态规则仅能被⼀个"activate"动作激活。
3.1.1.5 ⾃定义动作
除了以上动作外,你也可以定义⾃⼰的动作,以⽤于不同的⽬的,例如:
向syslog发送消息。Syslog是系统⽇志守护进程,它在/var/log中创建⽇志⽂件,这些⽂件的位置可以通过修改/f来改变。你可以在unix系统中⽤命令"man syslog"或者"f"来获取更多的信息。Syslog相当于Windows中的事件查看器。
向如HP OpenView等⽹管系统发送SNMP trap
在⼀个包上引⽤多个动作。如你前⾯所看到的,⼀个规则仅仅规定了⼀个动作,⾃定义动作可以⽤来产⽣多个动作。例如:你可以在发送SNMP trap的同时记录Syslog
将数据记录到XML⽂件中
将信息记录到数据库中,Snort可以将数据记录到MySQL,Postgress SQL,Oracle和Microsoft SQL server中
这些新的动作类型在配置⽂件f中定义。⼀个新动作⽤下⾯的通⽤结构来定义:
ruletyoe action_name
{
action definition
}
关键字ruletype后⾯跟随动作的名称,连个⼤括号中是实际的动作定义,类似于c语⾔中的函数。例如:我们定义⼀个叫做smb_db_alert的动作,⽤来向workstation.list中的主机发送SMB告警,同时在MySQL中的"snort"数据库记录,如下所⽰:
ruletype smb_db_alert
{
type alert
output alert_smb: workstation.list
output database: log,mysql,user=root password=root dbname=snort hsot=localhost
}
3.1.2 协议
协议是Snort规则中的第⼆部分,这⼀部分将显⽰哪种类型的包将与规则⽐对。到⽬前为⽌,Snort可以⽀持以下协议:
IP
ICMP
TCP
UDP
如果协议是IP,Snort检测包中的数据链路层头部来确定包的类型,如果协议类型是其他任何⼀种,Snort检测IP头部来确定协议类型。
3.1.3 协议
在Snort规则中,有两个地址部分,⽤来检测包的来源和⽬的地址。地址可以是⼀个主机地址或者⽹络地址。你可以⽤关键字any来制定所有的地址。地址后⾯⽤斜线来附加⼀个数字,表⽰掩码的位数。⽐如:192.168.2.0/24 代表⼀个C类⽹络192.168.2.0,其⼦⽹掩码是255.255.255.0。
你也可以在Snort规则额胡总制定⼀个地址的列表,⽐如:你在⽹络中包含连个C类地址:192.168.2.0和192.168.8.0,你想对除了这两个⽹络之外的其他地址应⽤规则,你可以⽤下⾯的规则,其中连个地址⽤逗号分隔:
alert icmp ![192.168.2.0/24,192.168.8.0/24] any -> any any (msg: "Ping with TTL=1--"; ttl:100;)
注意:⽅括号与否定器⼀起⽤的,如果没有否定符号,你可以不⽤⽅括号。(2.9版本待确认)
3.1.4 端⼝
端⼝号⽤来在进出特定的某个或⼀些列端⼝的包上运⾏规则,例如,你可以⽤源端⼝23来对来⾃Telnet服务器的包应⽤规则。你可以⽤关键字any来对包应⽤规则,⽽不管它的端⼝号。端⼝号仅仅对TCP、UDP协议有意义,如果你选择的协议是ICMP、IP,端⼝号就不起作⽤。
3.1.
4.1 端⼝范围
你可以在规则中的端⼝段设置⼀些列的端⼝,⽽不是⼀个。⽤冒号分隔起始和结束。例如下⾯的规则将对来⾃1024-2048的所有UDP包告警:
alert udp any 1024:2048 -> any any (msg: "UDP ports";)
3.1.
4.2 上限和下限
你可以仅仅⽤⼀个起始端⼝号或结束端⼝号来表⽰端⼝列表,例如::1024表⽰⽐1024⼩,包含1024的所有端⼝,1000: 表⽰⽐1000⼤,包括1000的所有端⼝3.1.4.3 否定符
与地址段相同,你也可以在Snort规则中的端⼝段中⽤否定符合来排除⼀个或多个端⼝。下⾯的规则将记录除了53端⼝外的其他所有UDP通信。
log udp any !53 -> any any(msg:"Log UDP";)
但是你不能⽤逗号来分隔过个端⼝,如 53,54 这样的表⽰是不允许的,但是你可以⽤ 53:54 来表⽰⼀个端⼝范围。(2.9版本待确认)
3.1.
4.4 共⽤端⼝号
共⽤端⼝号是提供给⼀些公⽤应⽤的。在UNIX平台上,你可以查看/etc/services⽂件,可以看到更多的端⼝的定义。RFC1700中包含详细列表。⽬前ICANN负责管理这些端⼝号,可以在中获取信息。
3.1.4 ⽅向段
在Snort规则中,⽅向段确定源和⽬的,下⾯是⽅向段的相关规定:
"->"表⽰左边的地址和端⼝是源⽽右边是⽬的
"<-"表⽰右边第地址和端⼝是源⽽左边是⽬的在
"<>"表⽰规则奖杯应⽤在两个⽅向上,在你想同时监视服务器和客户端的时候,可以⽤到这个标⽰。
3.2 规则选项
Snort规则选项部分在头部后⾯,在⼀对圆括号⾥⾯,其中可能包含⼀个选项,也可能包含⽤分号分割的过个选项,这些选项的关系是逻辑与的关系,只有当选项中的条件都满⾜的时候,规则动作才会被执⾏。所有snort规则选项之间⽤分号隔开,每个规则选项也被⽤冒号分为选项关键字和选项值。
四类主要的规则选项类:
⼀般提供信息但在检测过程中不产⽣任何影响
有效负载在净荷中查数据,并且能过相互关联(数据包数据部分)
⾮有效负载查⾮净荷中的数据(数据包⾸部)
过后检测选项这些选项时某条规则被处罚后,所设置的执⾏的规则
3.2.1 general rule options
3.2.1.1 msg
msg规则选项向⽇志和警报引擎告知要打印的消息以及数据包转储或警报,他是⼀个简单的⽂本字符串,利⽤\作为转义字符来表⽰离散的字符,否则这些字符可能会使Snort的规则解析器感到困惑(例如分号; 字符)。
msg:"<message text>";
3.2.1.2 reference
提供包含外部的⼀些攻击识别系统的引⽤功能,该插件⽬前⽀持⼏种特定的系统以及唯⼀URL。输出插
件将使⽤此插件来听有关⽣成的警报的其他信息的链接。确保还查看</i/>,以获取基于sid索引警报描述的系统。
格式:
reference:<id system>, <id>; [reference:<id system>, <id>;]
⽰例:
alert tcp any any -> any 21 (msg:"IDS287/ftp-wuftp260-venglin-linux";
flags:AP; content:"|00 00 00 01 02|";
reference:arachnids, IDS287; reference:bugtraq,1387;
reference:cve,CAN-2000-1574;)
3.2.1.3 gid
⽤于标识当规则被触发时,是snort的哪⼀部分⽣成事件,例如gid 1和规则⼦系统有关,⼤于100的gid被实际来表⽰特定的预处理器和解码器。有关正在使⽤的当前⽣成器ID,请参见源代码树中的etc/generat
ors。请注意,gid关键字是可选项,如未指定,默认为1,为避免与snort已定义的gid冲突,建议从1000000开始,⼀般规则编写,不建议使⽤。gid需要和sid配合使⽤。⽂件etc/gen-msg.map包含有关预处理器和解码器gid的更多信息,⽰例:
alert tcp any any -> any 80 (content:"BOB"; gid:1000001; sid:1; rev:1;)
查看/usr/local/share/doc/snort/generators⽂件(此⽂件不是配置⽂件):
rules_subsystem            1 # Snort Rule Engine
rpc_decode                  106 # RPC Preprocessor(预处理器)
stream4                    111 # Stream4 preprocessor(预处理器)
ftp                        125 # FTP decoder(解码器)
3.2.1.3 sid
识别不同的snort规则(snort规则编号),⽤于唯⼀标识⼀条规则,应与rev关键字配合使⽤,⽂件sig-msg.map包含警报消息到Snort规则id的映射。在对警报进⾏处理后以将ID映射到警报消息时,此信息⾮常有⽤。
sid:<snort rule id>;
3.2.1.4 rev
标识snort规则的修订,与sid配合使⽤(说明规则的版本)
alert tcp any any -> any 80 (content:"BOB"; sid:1000003; rev:2;)
3.2.1.5 classtype
snort根据其默认的规则⽂件,将攻击进⾏相应分类,并具有不同的优先级,1-4,1最⾼,规则分类被定义在fig⽂件中。(优先级1(⾼)是最严重的,优先级4(⾮常低)是最不严重的。)
classtype: <class name>;
config classification: name,description,priority
name表⽰类别名称,在snort规则中⽤classtype关键字来指定
description是对类别的简单描述
priority是这个类别的默认优先级,⽤数字表⽰,并可以在snort选项中⽤关键字priority改变。
⽰例:
config classification: DoS,Denial of Service Attack,2
类型描述优先
attempted-admin尝试获取管理员特权⾼
attempted尝试获取⽤户特权⾼
inappropriate-content检测到不适当内容⾼
policy-violation潜在的违反公司隐私的⾏为⾼
shellcode-detect检测到可执⾏代码⾼
successful-admin管理员特权获取成功⾼
successful-user⽤户特权获取成功⾼
trojan-activity检测到⽹络⽊马⾼
unsuccessful-user⽤户权限获取失败⾼
web-application-attack Web应⽤攻击⾼
attemptd-dos试图拒绝服务中
attempted-recon企图泄漏中
bad-unknown潜在的不良流量中
default-login-attempt尝试使⽤默认的⽤户名和密码登录中
denial-of-service尝试拒绝服务攻击中
misc-attack杂项攻击中
non-standard-protocol检测⾮标准协议或事件中
rpc-portmap-decode解码RPC查询中
successful-dos拒绝服务中
successful-recon-largescale⼤规模信息泄漏中
successful-recon-limited信息泄漏中
suspicious-filename-detect检测到可疑⽂件名中
suspicious-login检测到使⽤可疑⽤户名的尝试登录中
system-call-detect检测到系统调⽤中
unusual-client-port-connection客户端正在使⽤异常端⼝中
web-application-activity访问潜在的易受攻击的Web应⽤程序中
icmp-event常规ICMP事件低
misc-activity杂项活动低
network-scan检测⽹络扫描低
not-suspicious不可以流量低
protocol-command-decode通⽤协议命令解码低
string-detect检测到可疑字符串低
unknown未知流量低
tcp-connection检测到TCP连接⾮常低
3.2.1.6 priority
配置规则优先级(可以覆盖规则类型classtype预置的优先级)
priority:<priority interger>;
3.2.1.7 metadata
表明规则的⼀些其他信息,例如是否在规则共享库中共享,及其gid和sid,以及基于什么⽬标的服务标识,采⽤键值对形式,键值之间空格分开,多个键值对,逗号隔开,次关键字只有在Host Attribute Table已经提供才有意义。
metdata:key1 value1;
metdata:key1 value1,key2 value2;
键描述值格式
engine指共享库规则"shared"
sodi共享库规则⽣成器和SID gid/sid
service基于⽬标的服务标识符"http"
alert tcp any any -> any 80 (msg:"Shared Library Rule Example";
metadata:engine shared; metadata:soid 3|12345;)
alert tcp any any -> any 80 (msg:"Shared Library Rule Example";
metadata:engin shared, soid 3|12345;)
alert tcp any any -> any 80 (msg:"Shared Library Rule Example";
metadata:service http;)
3.2.2 payload detection rule options
3.2.2.1 content
查匹配净荷中的内容,并触发响应,选项数据可以包含混合⽂本和⼆进制数据,⼆进制数据放在两个管道符号"||"之间,表⽰为字节码,需要通过⼗六进制的⽅式进⾏表⽰,若果规则前⾯有!,则将在不包含此内容的数据包上触发警报。当编写规则以警告不符合特定模式的数据包时,这很有⽤,格式:
content:[!]"<content string>";
alert tcp any any -> any 139 (content:"|5c 00|p|00|I|00|P|00|E|00 5c|";)
alcet tcp any any -> any 80 (content:!"GET";)
此外,content还有很多修饰符:
Nocase          content字符串⼤⼩写不敏感,即忽略⼤⼩写
rawbytes        直接匹配原始数据包,忽视预处理器解码。如果未设置该关键字,⼤部分预处理器会使⽤
解码规范化数据做content匹配
Depth          匹配的深度
Offset          开始匹配的偏移量
Distance        两次content之间匹配的间距,与offset类似,不过,distance设置的是从上⼀个匹配结束开始的距离,⽽offset是从开始计算
Within          两次content匹配之间⾄多的间距(字节)
http_cookie    匹配cookie
http_raw_cookie 匹配未经normalize的cookie
http_header    匹配header
http_raw_header 匹配未经normalize的header
http_method    匹配method
http_uri        匹配uri
http_raw_url    匹配⽇志未经nomalize的url中
http_stat_code  匹配状态码中匹配
http_stat_msg  匹配状态信息
http_encode    匹配HTTP报⽂中url,⾸部,cookie字段使⽤的特定的编码⽅式,格式(!和or不能结合使⽤)
http_encode格式:
http_encode;[uri|header|cookie], [!][<utf8|double_encode|non_ascii|uencode|bare_byte|ascii|iis_encode>]
http_encode⽰例:
alert tcp any any -> any any (msg:"UTF8/UEncode Encoding present"; http_encode:uri,utf8|uencode;)
alert tcp any any -> any any (msg:"No UTF8"; http_encode:uri,!utf8);
注意:http开头的修饰符需要配合前⾯介绍过的预处理器http_inspect⼀起使⽤
3.2.2.2 protected_content
提供content的⼤部分功能,不同的是输⼊的查询内容形式上不同,上传查询内容的安全哈希摘要进⾏查询,隐藏查询内容更具保护性,如在配置⽂件中未指定默认的哈希算法,则在规则中要指定(md5,sha25,sha512),还需要指定length关键字,标识原始数据长度,格式。
protected_content:[!]"<content hash>", length:orig_len[, hash:md5|sha256|sha512]
⽰例:
alert tcp any any <> any 80 (msg:"MD5 Alert"; protected_content:"293C9EA246FF9985DC6F62A650F78986"; hash:md5; offset:0; length:4;)
- hash 如上例,配合protecte_content,指定使⽤的哈希算法
- length 配合protect_content关键字使⽤,已受保护的形式标识规则摘要的内容的原始数据长度,范围 0 - 65535
3.2.2.4 nocase
使⽤nocase关键字,规则编写者可以指定Snort应该查特定的模式,⽽忽略⼤⼩写。nocase修改规则中的上⼀个content关键字,格式:
nocase;
⽰例:
alert tcp any any -> any 21 (msg:"FTP ROOT"; content:"USER root"; nocase;)
图解:
content:"abc"; cocase;
3.2.2.5 rawbytes
rawbytes关键字允许规则查看原始数据包数据,⽽忽略预处理器进⾏的任何解码。这充当了上⼀个content选项的修饰符。
HTTP Inspect具有⼀组使⽤原始数据的关键字,例如:
http_raw_cookie、http_raw_header、http_raw_uri等,它们与原始HTTP请求和响应的特定部分匹配。
如果未显式指定rawbytes,则默认情况下,⼤多数其他预处理都会使⽤解码/规范化的数据进⾏内容匹配。因此,应中rawbytes以检查数据包中的任意原始数据,格式;
rawbytes;
⽰例:
此⽰例告诉内容模式匹配查看原始流量,⽽不是Telnet解码器提供的解码流量。
alert tcp any any -> any 21 (msg:"Telnet NOP"; content:"|FF F1|"; rawbytes;)
3.2.2.6 depth
depth关键字允许规则编写者指定Snort应该在包中搜索指定模式的距离。depth修改了规则中先前的"content"关键字。
深度为5会使Snort仅在payload的前5个字节内查指定的模式。
由于depth关键字是以前的content关键字的修饰符,因此在指定depth之前,规则中必须由内容。
此关键字允许值⼤于或等于要搜索的模式长度,最⼩允许值为1,此关键字的最⼤允许值为65535。
该值也可以设置为引⽤同⼀规则中由byte_extract关键字提取的变量的字符串值。
格式:
depth:[<number><var_name>];
图解:
content:"abc"; depth:3;
3.2.2.7 offset
offset关键字允许规则编写器指定从何处开始搜索数据包中的模式。offset修改规则中的上⼀个"content"关键字。
偏移量5会告诉Snort咋payload的前5个字节之后开始寻指定的模式。
由于offset关键字是以前的content关键字的修饰符,因此指定offset之前,规则中必须有内容。
辞官集资允许输⼊-65535到65535之间的值。
该值也可以设置为引⽤同⼀规则中由byte_extract关键字提取出来的变量的字符串值。
格式:
offset:[<number>|<var_number>];
图解:
content:"def"; offset:3;
综合⽰例:
alert tcp any any -> any 80 (content:"def"; offset:3; depth:3;)
3.2.2.8 distance
distance关键字使规则编写者可以指定Snort在开始搜索相对于先前模式匹配末尾的指定模式之间应忽略的包数。
可以认为这与offset完全⼀样,只是它与最后⼀个模式匹配的末尾有关,⽽不是与数据包的开头有关。
此关键字允许输⼊-65535到65535之间的值。
该值也可以设置为引⽤同⼀规则中由byte_extract关键字提取的变量的字符串值。
格式:
tcp ip协议有哪几层distance:[<byte_count>|<var_name>];