如何编写snort的检测规则.docx
《如何编写snort的检测规则.docx》由会员分享,可在线阅读,更多相关《如何编写snort的检测规则.docx(22页珍藏版)》请在冰豆网上搜索。
如何编写snort的检测规则
摘要
snort是一个强大的轻量级的网络入侵检测系统。
它具有实时数据流量分析和日志IP网络数据包的能力,能够进行协议分析,对内容进行搜索/匹配。
它能够检测各种不同的攻击方式,对攻击进行实时报警。
此外,snort具有很好的扩展性和可移植性。
本文将讲述如何开发snort规则。
(2002-07-0913:
13:
25)
--------------------------------------------------------------------------------
By书生
前言
snort是一个强大的轻量级的网络入侵检测系统。
它具有实时数据流量分析和日志IP网络数据包的能力,能够进行协议分析,对内容进行搜索/匹配。
它能够检测各种不同的攻击方式,对攻击进行实时报警。
此外,snort具有很好的扩展性和可移植性。
本文将讲述如何开发snort规则。
1.基础
snort使用一种简单的规则描述语言,这种描述语言易于扩展,功能也比较强大。
下面是一些最基本的东西:
snort的每条规则必须在一行中,它的规则解释器无法对跨行的规则进行解析。
注意:
由于排版的原因本文的例子有的分为两行。
snort的每条规则都可以分成逻辑上的两个部分:
规则头和规则选项。
规则头包括:
规则行为(rule'saction)、协议(protocol)、源/目的IP地址、子网掩码以及源/目的端口。
规则选项包含报警信息和异常包的信息(特征码,signature),使用这些特征码来决定是否采取规则规定的行动。
这是一个例子:
alerttcpanyany->192.168.1.0/24111(content:
"|000186a5|";msg:
"mountdaccess";)
表1.一条简单的snort规则
从开头到最左边的括号属于规则头部分,括号内的部分属于规则选项。
规则选项中冒号前面的词叫做选项关键词(optionkeywords)。
注意对于每条规则来说规则选项不是必需的,它们是为了更加详细地定义应该收集或者报警的数据包。
只有匹配所有选项的数据包,snort才会执行其规则行为。
如果许多选项组合在一起,它们之间是逻辑与的关系。
让我们从规则头开始。
1.1include
snort使用的规则文件在命令行中指定,include关键词使这个规则文件可以包含其它规则文件中的规则,非常类似与C语言中的#include。
snort会从被包含的文件读出其内容,取代include关键词。
格式:
include<文件路径/文件名>
注意:
行尾没有分号。
1.2varriables
在snort规则文件中可以定义变量。
格式:
var
例子:
varMY_NET192.168.1.0/24,10.1.1.0/24]$MY_NETany(flags:
S;msg:
'SYNMETApacket";)
表2.变量的定义和使用
规则变量名可以使用多种方式来修改,你可以使用$操作符来定义元变量(meta-variables)。
这些修改方式可以结合变量修改操作符:
?
和-来使用。
$var:
定义元变量
$(var):
以变量var的内容作为变量名
$(var:
-default):
以变量var的内容作为变量名,如果var没有定义就使用default作为变量名
$(var:
?
message):
使用变量var的内容作为变量名,如果不成功就打印错误信息message并退出。
例如:
varMY_NET$(MYU_NET:
-192.168.1.0/24)tcpanyany->$(MY_NET:
?
MY_NETisundefined!
)23
表3.高级变量应用
2.规则头(RuleHeaders)
2.1RuleAction
规则头包含一些信息,这些信息包括:
哪些数据包、数据包的来源、什么类型的数据包,以及对匹配的数据包如何处理。
每条规则的第一项就是规则行为(ruleaction)。
规则行为告诉snort当发现匹配的数据包时,应该如何处理。
在snort中,有五种默认的处理方式:
alert、log、pass、activate和dynamic。
alert:
使用选定的报警方法产生报警信息,并且记录数据包
log:
记录数据包
pass:
忽略数据包
activate:
报警,接着打开其它的dynamic规则
dynamic:
保持空闲状态,直到被activete规则激活,作为一条log规则
你也可以定义自己的规则类型,把它们和一个或者几个输出插件联系在一起。
然后你就可以在snort规则中使用这些规则类型了。
这个例子将建立一个类型,它将只以tcpdump格式输出日志:
ruletypesuspicious
{
typelog
outputlog_tcpdump:
suspocious.log
}
下面这个例子将建立一个类型,把日志发送到syslog和MySql数据库:
ruletyperedalert
{
typealert
outputalert_syslog:
LOG_AUTHLOG_ALERT
outputdatabase:
log,user=snortdbname=snorthost=localhost
}
2.2协议
每条规则的第二项就是协议项。
当前,snort能够分析的协议是:
TCP、UDP和ICMP。
将来,可能提供对ARP、ICRP、GRE、OSPF、RIP、IPX等协议的支持。
2.3IP地址
规则头下面的部分就是IP地址和端口信息。
关键词any可以用来定义任意的IP地址。
snort不支持对主机名的解析。
所以地址只能使用数字/CIDR的形式。
/24表示一个C类网络;/16表示一个B类网络;而/32表示一台特定的主机地址。
例如:
192.168.1.0/24表示从192.168.1.1到192.168.1.255的地址。
在规则中,可以使用使用否定操作符(negationoperator)对IP地址进行操作。
它告诉snort除了列出的IP地址外,匹配所有的IP地址。
否定操作符使用!
表示。
例如,使用否定操作符可以很轻松地对表1的规则进行改写,使其对从外部网络向内的数据报警。
alerttcp!
192.168.1.0/24any->192.168.1.0/24111(content:
"|000186a5|";msg:
"externalmountdaccess";)
表4.使用IP地址否定操作符的规则
上面这条规则中的IP地址表示:
所有IP源地址不是内部网络的地址,而目的地址是内部网络地址。
你也可以定义一个IP地址列表(IPlist)。
IP地址列表的格式如下:
[IP地址1/CIDR,IP地址/CIDR,....]
注意每个IP地址之间不能有空格。
例如:
alerttcp!
[192.168.1.0/24,10.1.1.1.0/24]any->[192.168.1.0/24,10.1.1.0/24]111(content:
"|000186a5|";msg:
"externalmountdaccess";)
2.4端口号
在规则中,可以有几种方式来指定端口号,包括:
any、静态端口号(staticport)定义、端口范围,以及使用非操作定义。
any表示任意合法的端口号;静态端口号表示单个的端口号,例如:
111(portmapper)、23(telnet)、80(http)等。
使用范围操作符:
可以指定端口号范围。
有几种方式来使用范围操作符:
达到不同的目的,例如:
logudpanyany->192.168.1.0/241:
1024
记录来自任何端口,其目的端口号在1到1024之间的UDP数据包
logtcpanyany->192.168.1.0/24:
600
记录来自任何端口,其目的端口号小于或者等于6000的TCP数据包
logtcpany:
1024->192.168.1.0/24500:
记录源端口号小于等于1024,目的端口号大于等于500的TCP数据包
表5.端口范围示例
你还可以使用逻辑非操作符!
对端口进行非逻辑操作(portnegation)。
逻辑非操作符可以用于其它的规则类型(除了any类型,道理很简单)。
例如,你如果要日志除了X-window系统端口之外的所有端口,可以使用下面的规则:
logtcpanyany->192.168.1.0/24!
6000:
6010
表6.对端口进行逻辑非操作
2.5方向操作符(directionoperator)
方向操作符->表示数据包的流向。
它左边是数据包的源地址和源端口,右边是目的地址和端口。
此外,还有一个双向操作符<>,它使snort对这条规则中,两个IP地址/端口之间双向的数据传输进行记录/分析,例如telnet或者POP3对话。
下面的规则表示对一个telnet对话的双向数据传输进行记录:
log!
192.168.1.0/24any<>192.168.1.0/2423
表7.使用双向操作符的snort规则
activate/dynamic规则
activate/dynamic规则对扩展了snort功能。
使用activate/dynamic规则对,你能够使用一条规则激活另一条规则。
当一条特定的规则启动,如果你想要snort接着对符合条件的数据包进行记录时,使用activate/dynamic规则对非常方便。
除了一个必需的选项activates外,激活规则(activaterule)非常类似于报警规则(alertrule)。
动态规则(dynamicrule)和日志规则(logrule)也很相似,不过它需要一个选项:
activated_by。
动态规则还需要另一个选项:
count。
当一个激活规则启动,它就打开由activate/activated_by选项之后的数字指示的动态规则,记录count个数据包。
下面是一条activate/dynamic规则对的规则:
activatetcp!
$HOME_NETany->$HOME_NET143(flags:
PA;content:
"|E8C0FFFFFF|in|;activates:
1;
表8.activate/dynamic规则对
这个规则使snort在检测到IMAP缓冲区溢出时发出报警,并且记录后续的50个从$HOME_NET之外,发往$HOME_NET的143号端口的数据包。
如果缓冲区溢出成功,那么接下来50个发送到这个网络同一个服务端口(这个例子中是143号端口)的数据包中,会有很重要的数据,这些数据对以后的分析很有用处。
3.规则选项
规则选项构成了snort入侵检测引擎的核心,它们非常容易使用,同时又很强大和容易扩展。
在每条snort规则中,选项之间使用分号进行分割。
规则选项关键词和其参数之间使用冒号分割。
截止到写本文为止(snort1.7版),snort有23个规则选项关键词:
msg:
在报警和日志中打印的消息
logto:
把日志记录到一个用户指定的文件,而不是输出到标准的输出文件
ttl:
测试IP包头的TTL域的值
tos:
测试IP包头的TOS域的值
id:
测试IP分组标志符(fragmentID)域是否是一个特定的值
ipoption:
查看IP选项(IPoption)域
fragbits:
测试IP包头的分片位(fragmentationbit)
dsize:
测试数据包包数据段的大小
flags:
测试TCP标志(flag)是否是某个值
seq:
测试TCP包的序列号是否是某个值
ack:
测试TCP包的确认(acknowledgement)域是否为某个值
itype:
测试ICMP数据包的类型(type)域
icode:
测试ICMP数据包的编码(code)域
icmp_id:
测试ICMP回送包的标志符(ICMPECHOID)是否为某个值
content:
在数据包的数据段中搜索模式(pattern)
content-list:
在数据包的数据段中搜索模式清单
offset:
设置开始搜索的偏移量
depth:
设置搜索最大深度
nocase:
大小写不敏感匹配内容字符串
session:
剥离一个对话的应用层信息
rpc:
观察RPC服务对特定应用程序的调用
resp:
激活反应措施(断开连接等)
react:
激活反应措施(阻塞WEB站点)
3.1msg
msg规则选项告诉日志引擎在复制包时同时打印的信息,以及让报警引擎输出的警告消息。
它只是一个简单的文本字符串,使用作为转义符。
格式:
msg:
"";
3.2logto
logto选项告诉snort把触发某条规则所有的数据包都记录到指定的文件。
使用这个选项,对处理来自nmap扫描、HTTPCGI扫描的数据非常方便。
注意如果使用二进制日志模式,这个选项会失效。
格式:
logto:
"<文件名>";
3.3ttl
这个选项设置要测试的生命周期(time-to-live)值。
只有数据包的TTL和这个选项设置的值精确匹配,测试才会成功。
这个选项主要用来检测路由企图。
格式:
ttl:
"";
3.4tos
你可以使用tos关键词检查IP包头的TOS(typeofservice)域是否是一个特定的值。
也是只有在被检测包TOS域的值和给定的值精确匹配时,这个测试才会成功。
格式:
tos:
"";
3.5ID
这个选项关键词用来测试IP分片包头的ID域。
一些黑客工具为了不同的目的把这个域设置为特殊的值,例如:
31337是在一些黑客中比较流行的值。
使用这个选项就可以阻止这种攻击。
格式:
id:
"";
3.6lpoption
如果IP包中有选项域,可以使用这个规则选项搜索IP包头的特定选项,例如源路由。
这个规则选项可以使用的参数如下:
rr:
路由记录
eof:
Endoflist
nop:
无操作
ts:
时间戳
sec:
IP安全选项
lsrr:
宽松源路由(loosesourcerouting)
ssrr:
严格源路由(strictsourceroution)
satid:
流标识符
最常被注意的IP选项是loose&strictsourcerouting,不过在Internet上广泛使用的任何应用程序中都没使用这两个选项。
每条规则中只能设定一个IP规则。
格式:
ipopts:
;
3.7fragbits
使用这个规则选项可以观察IP包头的分片位和保留位。
它们在IP包头的标识域,共有3位,分别是:
保留为(reservedbit,RB)、还有分组片位(morefragments,MF)、不可分片(dontfragment,DF)。
这些位可以以各种方式组合检查,使用下面的值指定:
R:
保留位
D:
DF位
M:
MF位
你也可以使用修饰符号对特定的位进行逻辑组合:
+--ALL标志,指定的位加上任何其它的位为真
*--ANY标志,指定的任何位为真
!
--NOT标志,指定的位不为真
格式:
fragbits:
;
例子:
alerttcp!
$HOME_NETany->$HOME_NETany(fragbits:
R+;msg:
"ReserverdIPbitset!
";)
表9.fragbits示例
3.8dsize
这个规则选项用来测试数据包负载的大小。
它可以被设置为任意值,还可以使用大于/小于号。
例如,如果你知道某个服务有一个特定大小的缓冲区,你就能够设置这个选项来捕获制造缓冲区溢出的企图。
它比检查数据包的内容速度快的多。
格式:
dsize:
[>|<]
<、>是可选的
3.9content
关键词content是snort一个非常重要的特征。
用户可以在规则中使用这个关键词,snort就会搜索数据包中content指定的内容,并且触发对于这些数据的反应。
每当对一个content规则选项进行模式匹配时,snort都会调用Boyer-Moore模式匹配函数,测试数据包的内容。
无论在数据包的那个位置发现要搜索的数据,就算测试成功。
接下来,snort就会对这条规则中其余的选项进行测试。
注意:
测试是大小写敏感的。
content选项包含的数据可以混合有文本和二进制数据。
二进制数据一般被包在管道符(|)中,由字节码(bytecode)表示。
字节码使用16进制数字表示二进制数据。
表10是一条混有文本和二进制数据的snort规则。
alerttcpanyany->192.168.1.0/24143(content:
"|90c8c0ffffff|/bin/sh";msg:
"IMAPbufferoverflow");
表10.content规则选项中混有文本和二进制数据
格式:
content:
"";
3.10offset
在使用content规则选项时,offset规则选项作为其修饰符。
这个关键词设置对content的内容进行模式匹配时的起始位置。
这个规则选项在某些情况下很有用,例如CGI扫描,要搜索的字符串从来不会在数据包的前4个字节出现。
注意:
设置偏移值一定要小心,它可能会造成漏检!
这个规则选项只能和content规则选项搭配使用。
格式:
offset:
;
3.11depth
depth是content规则选项的另一个修饰符。
它用来设置最大的搜索深度,以减少无谓的搜索,使snort只在特征码可能出现的区域内搜索,例如如果在一个web绑定(web-bound)包中搜索“cgi-bin/phf",你就不必浪费时间在数据包负载数据的前20个字节之外搜索。
表11的规则结合了content、offset、depth。
alerttcpanyany->192.168.1.0/2480(content:
"cgi-bin/phf";offset:
3;depth:
22;msg:
"CGI-PHFaccess";)
表11.含有content、offset和depth规则选项的规则
格式:
depth:
;
3.12nocase
nocase使对content进行模式匹配时大小写不敏感。
snort将不再区别每个ASCII字符的大小写。
格式:
nocase;
例如:
alerttcpanyany->192.168.1.0/2421(content:
"USERroot";nocase;msg:
"FTProotloginattempt";)
表12.使用nocase修饰符的规则
3.13flags
这个规则选项用来测试TCP包头的标志。
实际上,在snort中有8个有效的标志:
F:
FIN(TCP标志字节最左边一位)
S:
SYN
R:
RST
P:
PSH
A:
ACK
S:
ACK
U:
URG
2:
保留位2
1:
保留位1(标志字节最右边一位)
还可以使用逻辑操作符对指定的标志位进行操作:
+:
ALL,指定的标志位和其它任意的标志位为真
*:
ANY,指定的标志位中任意的标志位为真
!
:
NOT,除了指定标志位外,任意的标志位为真
保留位能够用来检测非正常的行为,例如对IP协议栈指纹特征的探测企图或者其它可疑行为。
表13是一条针对SYN-FIN扫描的检测规则。
alertanyany->192.168.1.0/24any(flags:
SF;msg:
"PossibleSYNFINscan";)
表13.TCP标志
格式:
flags:
;
3.14seq
这个规则选项涉及TCP包的序列号。
实质上,它检测包是否有一个静态的序列号集合,因此这个规则选项非常没有用处。
指示出于完整性的考虑才包含了这个选项。
格式:
seq:
3.15ack
这个规则选项涉及TCP包头的确认域(acknowledge)。
迄今为止,它只有一个实际的用途:
检测NMAPTCPping扫描。
扫描程序nmap进行TCPping扫描时,把TCP包头的确认号(4个字节)设置为0,然后向目标主机发出TCPACK包,确定目标主机是否正在运行。
表14是一个检测这种探测的规则:
alertanyany->192.168.1.0/24any(flags:
A;ack:
0;msg:
"nmapTCPping";)
表14.TCPACK域的使用
格式:
ack:
;
3.16itype
itype规则选项用来测试ICMP包头的类型域,使用数字进行设置。
每种ICMP包对应的数值如下:
0:
回送应答
3:
无法到达目的地
4:
抑制包源
5:
重定向(改变路径)
8:
回送请求
11:
IP分组超时
12:
IP分组参数有问题
13:
时间戳请求
14:
时间戳应答
15:
信息请求
16:
信息应答
17:
地址掩码请求
18:
地址掩码应答
注意:
拒绝服务和淹没攻击的数据包有时使用无效的ICMP类型,可以使用这个规则选项对无效的ICMP类型进行检测,也就是说,这个规则选项中的值可以不是上面所列的数值。
格式:
itype:
;
3.17icode
icode规则选项和itype非常相似,也是使用数字进行设置,具体数值见snort源代码的decode.h文件。
同样,也可以使用其它的数值来检测可疑的数据包。
格式:
icode:
;
3.18session
sesion关键词是从snort-1.3.1.1版加入的,用来从TCP会话中剥离用户的数据。
如果想观察用户在telnet、rlogin、ftp,甚至WEB会话过程中输入了什么,就可以使用这个规则选项。
session规则选项有两个参数关键词:
printable、all。
使用printable,snort就会只输出可打印数据;使用all,snort就会输出所有的数据,不可打印的数据以16进制表示。
不过,这个功能会大大降低snort的速度,所以不太适合大负载的情况,而且最好使用二进制日志文件格式。
表15是一条记录telnet会话的规则:
logtcpanyany<>192.168.1.0/2423(session:
printable;)
表15.记录可打印的telnet会话数据
格式:
session:
[printable|all];
3.19icmp_id
icmp_id规则选项用来检测ICMP回送(echo)数据包的ICMPID号是否为一个特定的值。
之所以会用到这个规则选项,是因为一些隐秘通道(covertchannel)程序在通讯时使用静态的ICMP域。
为了执行stacheldreht检测规则,开发了这个特别的插件,这些规则是由M