摘要
snort是一个强大的轻量级的网络入侵检测系统。它具有实时数据流量分析和日志IP网络数据包的能力,能够进行协议分析,对内容进行搜索/匹配。它能够检测各种不同的攻击方式,对攻击进行实时报警。此外,snort具有很好的扩展性和可移植性。本文将讲述如何开发snort规则。(2002-07-09 13:13:25)
--------------------------------------------------------------------------------
By 书生
前言
snort是一个强大的轻量级的网络入侵检测系统。它具有实时数据流量分析和日志IP网络数据包的能力,能够进行协议分析,对内容进行搜索/匹配。它能够检测各种不同的攻击方式,对攻击进行实时报警。此外,snort具有很好的扩展性和可移植性。本文将讲述如何开发snort规则。
1.基础
snort使用一种简单的规则描述语言,这种描述语言易于扩展,功能也比较强大。下面是一些最基本的东西:
snort的每条规则必须在一行中,它的规则解释器无法对跨行的规则进行解析。注意:由于排版的原因本文的例子有的分为两行。
snort的每条规则都可以分成逻辑上的两个部分:规则头和规则选项。规则头包括:规则行为(rule's action)、协议(protocol)、源/目的IP地址、子网掩码以及源/目的端口。规则选项包含报警信息和异常包的信息(特征码,signature),使用这些特征码来决定是否采取规则规定的行动。
这是一个例子:
alert tcp any any -> 192.168.1.0/24 111(content:"|00 01 86 a5|";msg:"mountd access";)
表1.一条简单的snort规则
从开头到最左边的括号属于规则头部分,括号内的部分属于规则选项。规则选项中冒号前面的词叫做选项关键词(option keywords)。注意对于每条规则来说规则选项不是必需的,它们是为了更加详细地定义应该收集或者报警的数据包。只有匹配所有选项的数据包,snort才会执行其规则行为。如果许多选项组合在一起,它们之间是逻辑与的关系。让我们从规则头开始。 1.1 include
snort使用的规则文件在命令行中指定,include关键词使这个规则文件可以包含其它规则文件中的规则,非常类似与C语言中的#include。snort会从被包含的文件读出其内容,取代include关键词。
格式:
include <文件路径/文件名>
注意:行尾没有分号。
1.2 varriables
在snort规则文件中可以定义变量。
格式:
var
例子:
var MY_NET 192.168.1.0/24,10.1.1.0/24] $MY_NET any (flags:S;msg:'SYNMETA packet";)
表2.变量的定义和使用
规则变量名可以使用多种方式来修改,你可以使用$操作符来定义元变量(meta-variables)。这些修改方式可以结合变量修改操作符:?和-来使用。
$var:定义元变量
$(var):以变量var的内容作为变量名
$(var:-default):以变量var的内容作为变量名,如果var没有定义就使用default作为变量名
$(var:?message):使用变量var的内容作为变量名,如果不成功就打印错误信息message并退出。
例如:
var MY_NET $(MYU_NET:-192.168.1.0/24) tcp any any -> $(MY_NET:?MY_NET is undefined!) 23
表3.高级变量应用
2.规则头(Rule Headers)
2.1 Rule Action
规则头包含一些信息,这些信息包括:哪些数据包、数据包的来源、什么类型的数据包,以及对匹配的数据包如何处理。每条规则的第一项就是规则行为(rule action)。规则行为告诉snort当发现匹配的数据包时,应该如何处理。在snort中,有五种默认的处理方式:alert、log、pass、activate和dynamic。
alert:使用选定的报警方法产生报警信息,并且记录数据包
log:记录数据包
pass:忽略数据包
activate:报警,接着打开其它的dynamic规则
dynamic:保持空闲状态,直到被activete规则激活,作为一条log规则
你也可以定义自己的规则类型,把它们和一个或者几个输出插件联系在一起。然后你就可以在snort规则中使用这些规则类型了。
这个例子将建立一个类型,它将只以tcpdump格式输出日志:
ruletype suspicious
{
type log
output log_tcpdump: suspocious.log
}
下面这个例子将建立一个类型,把日志发送到syslog和MySql数据库:
ruletype redalert
{
type alert
output alert_syslog:LOG_AUTH LOG_ALERT
output database:log,user=snort dbname=snort host=localhost
}
2.2 协议
每条规则的第二项就是协议项。当前,snort能够分析的协议是:TCP、UDP和ICMP。将来,可能提供对ARP、ICRP、GRE、OSPF、RIP、IPX等协议的支持。
2.3 IP地址
规则头下面的部分就是IP地址和端口信息。关键词any可以用来定义任意的IP地址。snort不支持对主机名的解析。所以地址只能使用数字/CIDR的形式。/24表示一个C类网络;/16表示一个B类网络;而/32表示一台特定的主机地址。例如:192.168.1.0/24表示从192.168.1.1到192.168.1.255的地址。
在规则中,可以使用使用否定操作符(negation operator)对IP地址进行操作。它告诉snort除了列出的IP地址外,匹配所有的IP地址。否定操作符使用!表示。例如,使用否定操作符可以很轻松地对表1的规则进行改写,使其对从外部网络向内的数据报警。
alert tcp !192.168.1.0/24 any -> 192.168.1.0/24 111(content:"|00 01 86 a5|";msg:"external mountd access";)
表4.使用IP地址否定操作符的规则
上面这条规则中的IP地址表示:所有IP源地址不是内部网络的地址,而目的地址是内部网络地址。
你也可以定义一个IP地址列表(IP list)。IP地址列表的格式如下:
[IP地址1/CIDR,IP地址/CIDR,....]
注意每个IP地址之间不能有空格。例如:
alert tcp ![192.168.1.0/24,10.1.1.1.0/24] any ->[192.168.1.0/24,10.1.1.0/24] 111 (content:"|00 01 86 a5|";msg:"external mountd access";)
2.4 端口号
在规则中,可以有几种方式来指定端口号,包括:any、静态端口号(static port)定义、端口范围,以及使用非操作定义。any表示任意合法的端口号;静态端口号表示单个的端口号,例如:111(portmapper)、23(telnet)、80(http)等。使用范围操作符:可以指定端口号范围。有几种方式来使用范围操作符:达到不同的目的,例如:
log udp any any -> 192.168.1.0/24 1:1024
记录来自任何端口,其目的端口号在1到1024之间的UDP数据包
log tcp any any -> 192.168.1.0/24 :600
记录来自任何端口,其目的端口号小于或者等于6000的TCP数据包
log tcp any :1024 -> 192.168.1.0/24 500:
记录源端口号小于等于1024,目的端口号大于等于500的TCP数据包
表5.端口范围示例
你还可以使用逻辑非操作符!对端口进行非逻辑操作(port negation)。逻辑非操作符可以用于其它的规则类型(除了any类型,道理很简单)。例如,你如果要日志除了X-window系统端口之外的所有端口,可以使用下面的规则:
log tcp any any -> 192.168.1.0/24 !6000:60 10
表6.对端口进行逻辑非操作
2.5 方向操作符(direction operator)
方向操作符->表示数据包的流向。它左边是数据包的源地址和源端口,右边是目的地址和端口。此外,还有一个双向操作符<>,它使snort对这条规则中,两个IP地址/端口之间双向的数据传输进行记录/分析,例如telnet或者POP3对话。下面的规则表示对一个telnet对话的双向数据传输进行记录:
log !192.168.1.0/24 any <> 192.168.1.0/24 23
表7.使用双向操作符的snort规则
activate/dynamic规则
activate/dynamic规则对扩展了snort功能。使用activate/dynamic规则对,你能够使用一条规则激活另一条规则。当一条特定的规则启动,如果你想要snort接着对符合条件的数据包进行记录时,使用activate/dynamic规则对非常方便。除了一个必需的选项activates外,激活规则(activate rule)非常类似于报警规则(alert rule)。动态规则(dynamic rule)和日志规则(log rule)也很相似,不过它需要一个选项:activated_by。动态规则还需要另一个选项:count。当一个激活规则启动,它就打开由activate/activated_by选项之后的数字指示的动态规则,记录count个数据包。
下面是一条activate/dynamic规则对的规则:
activate tcp !$HOME_NET any -> $HOME_NET 143 (flags:PA;content:"|E8C0FFFFFF|in|;activates:1;
表8.activate/dynamic规则对
这个规则使snort在检测到IMAP缓冲区溢出时发出报警,并且记录后续的50个从$HOME_NET之外,发往$HOME_NET的143号端口的数据包。如果缓冲区溢出成功,那么接下来50个发送到这个网络同一个服务端口(这个例子中是143号端口)的数据包中,会有很重要的数据,这些数据对以后的分析很有用处。 3.规则选项
规则选项构成了snort入侵检测引擎的核心,它们非常容易使用,同时又很强大和容易扩展。在每条snort规则中,选项之间使用分号进行分割。规则选项关键词和其参数之间使用冒号分割。截止到写本文为止(snort 1.7版),snort有23个规则选项关键词:
msg:在报警和日志中打印的消息
logto:把日志记录到一个用户指定的文件,而不是输出到标准的输出文件
ttl:测试IP包头的TTL域的值
tos:测试IP包头的TOS域的值
id:测试IP分组标志符(fragment ID)域是否是一个特定的值
ipoption:查看IP选项(IP option)域
fragbits:测试IP包头的分片位(fragmentation bit)
dsize:测试数据包包数据段的大小
flags:测试TCP标志(flag)是否是某个值
seq:测试TCP包的序列号是否是某个值
ack:测试TCP包的确认(acknowledgement)域是否为某个值
itype:测试ICMP数据包的类型(type)域
icode:测试ICMP数据包的编码(code)域
icmp_id:测试ICMP回送包的标志符(ICMP ECHO ID)是否为某个值
content:在数据包的数据段中搜索模式(pattern)
content-list:在数据包的数据段中搜索模式清单
offset:设置开始搜索的偏移量
depth:设置搜索最大深度
nocase:大小写不敏感匹配内容字符串
session:剥离一个对话的应用层信息
rpc:观察RPC服务对特定应用程序的调用
resp:激活反应措施(断开连接等)
react:激活反应措施(阻塞WEB站点)
3.1 msg
msg规则选项告诉日志引擎在复制包时同时打印的信息,以及让报警引擎输出的警告消息。它只是一个简单的文本字符串,使用作为转义符。
格式:
msg:"";
3.2 logto
logto选项告诉snort把触发某条规则所有的数据包都记录到指定的文件。使用这个选项,对处理来自nmap扫描、HTTP CGI扫描的数据非常方便。注意如果使用二进制日志模式,这个选项会失效。 格式:
logto:"<文件名>";
3.3 ttl
这个选项设置要测试的生命周期(time-to-live)值。只有数据包的TTL和这个选项设置的值精确匹配,测试才会成功。这个选项主要用来检测路由企图。
格式:
ttl:"";
3.4 tos
你可以使用tos关键词检查IP包头的TOS(type of service)域是否是一个特定的值。也是只有在被检测包TOS域的值和给定的值精确匹配时,这个测试才会成功。
格式:
tos:"";
3.5 ID
这个选项关键词用来测试IP分片包头的ID域。一些黑客工具为了不同的目的把这个域设置为特殊的值,例如:31337是在一些黑客中比较流行的值。使用这个选项就可以阻止这种攻击。
格式:
id: "";
3.6 lpoption
如果IP包中有选项域,可以使用这个规则选项搜索IP包头的特定选项,例如源路由。这个规则选项可以使用的参数如下:
rr:路由记录
eof:End of list
nop:无操作
ts:时间戳
sec:IP安全选项
lsrr:宽松源路由(loose source routing)
ssrr:严格源路由(strict source roution)
satid:流标识符
最常被注意的IP选项是loose&strict source routing,不过在Internet上广泛使用的任何应用程序中都没使用这两个选项。每条规则中只能设定一个IP规则。
格式:
ipopts: ;
3.7 fragbits
使用这个规则选项可以观察IP包头的分片位和保留位。它们在IP包头的标识域,共有3位,分别是:保留为(reserved bit,RB)、还有分组片位(more fragments,MF)、不可分片(dont fragment,DF)。这些位可以以各种方式组合检查,使用下面的值指定:
R:保留位
D:DF位
M:MF位
你也可以使用修饰符号对特定的位进行逻辑组合:
+--ALL标志,指定的位加上任何其它的位为真
*--ANY标志,指定的任何位为真
!--NOT标志,指定的位不为真
格式:
fragbits: ;
例子:
alert tcp !$HOME_NET any -> $HOME_NET any (fragbits:R+;msg:"Reserverd IP bit set!";)
表9.fragbits示例
3.8 dsize
这个规则选项用来测试数据包负载的大小。它可以被设置为任意值,还可以使用大于/小于号。例如,如果你知道某个服务有一个特定大小的缓冲区,你就能够设置这个选项来捕获制造缓冲区溢出的企图。它比检查数据包的内容速度快的多。
格式:
dsize: [>|<]
<、>是可选的
3.9 content
关键词content是snort一个非常重要的特征。用户可以在规则中使用这个关键词,snort就会搜索数据包中content指定的内容,并且触发对于这些数据的反应。每当对一个content规则选项进行模式匹配时,snort都会调用Boyer-Moore模式匹配函数,测试数据包的内容。无论在数据包的那个位置发现要搜索的数据,就算测试成功。接下来,snort就会对这条规则中其余的选项进行测试。注意:测试是大小写敏感的。
content选项包含的数据可以混合有文本和二进制数据。二进制数据一般被包在管道符(|)中,由字节码(bytecode)表示。字节码使用16进制数字表示二进制数据。表10是一条混有文本和二进制数据的snort规则。
alert tcp any any -> 192.168.1.0/24 143(content:"|90c8 c0ff ffff|/bin/sh";msg:"IMAP buffer overflow");
表10.content规则选项中混有文本和二进制数据
格式:
content:"";
3.10 offset
在使用content规则选项时,offset规则选项作为其修饰符。这个关键词设置对content的内容进行模式匹配时的起始位置。这个规则选项在某些情况下很有用,例如CGI扫描,要搜索的字符串从来不会在数据包的前4个字节出现。注意:设置偏移值一定要小心,它可能会造成漏检!这个规则选项只能和content规则选项搭配使用。 格式:
offset: ;
3.11 depth
depth是content规则选项的另一个修饰符。它用来设置最大的搜索深度,以减少无谓的搜索,使snort只在特征码可能出现的区域内搜索,例如如果在一个web绑定(web-bound)包中搜索“cgi-bin/phf",你就不必浪费时间在数据包负载数据的前20个字节之外搜索。表11的规则结合了content、offset、depth。
alert tcp any any -> 192.168.1.0/24 80 (content:"cgi-bin/phf";offset:3;depth:22;msg:"CGI-PHF access";)
表11.含有content、offset和depth规则选项的规则
格式:
depth: ;
3.12 nocase
nocase使对content进行模式匹配时大小写不敏感。snort将不再区别每个ASCII字符的大小写。
格式:
nocase;
例如:
alert tcp any any -> 192.168.1.0/24 21 (content:"USER root";nocase;msg:"FTP root login attempt";)
表12.使用nocase修饰符的规则
3.13 flags
这个规则选项用来测试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扫描的检测规则。
alert any any -> 192.168.1.0/24 any (flags:SF;msg:"Possible SYN FIN scan";)
表13.TCP标志
格式:
flags: ;
3.14 seq
这个规则选项涉及TCP包的序列号。实质上,它检测包是否有一个静态的序列号集合,因此这个规则选项非常没有用处。指示出于完整性的考虑才包含了这个选项。 格式:
seq:
3.15 ack
这个规则选项涉及TCP包头的确认域(acknowledge)。迄今为止,它只有一个实际的用途:检测NMAP TCP ping扫描。扫描程序nmap进行TCP ping扫描时,把TCP包头的确认号(4个字节)设置为0,然后向目标主机发出TCP ACK包,确定目标主机是否正在运行。表14是一个检测这种探测的规则:
alert any any -> 192.168.1.0/24 any (flags:A;ack:0;msg:"nmap TCP ping";)
表14.TCP ACK域的使用
格式:
ack:;
3.16 itype
itype规则选项用来测试ICMP包头的类型域,使用数字进行设置。每种ICMP包对应的数值如下:
0:回送应答
3:无法到达目的地
4:抑制包源
5:重定向(改变路径)
8:回送请求
11:IP分组超时
12:IP分组参数有问题
13:时间戳请求
14:时间戳应答
15:信息请求
16:信息应答
17:地址掩码请求
18:地址掩码应答
注意:拒绝服务和淹没攻击的数据包有时使用无效的ICMP类型,可以使用这个规则选项对无效的ICMP类型进行检测,也就是说,这个规则选项中的值可以不是上面所列的数值。
格式:
itype:;
3.17 icode
icode规则选项和itype非常相似,也是使用数字进行设置,具体数值见snort源代码的decode.h文件。同样,也可以使用其它的数值来检测可疑的数据包。
格式:
icode:;
3.18 session
sesion关键词是从snort-1.3.1.1版加入的,用来从TCP会话中剥离用户的数据。如果想观察用户在telnet、rlogin、ftp,甚至WEB会话过程中输入了什么,就可以使用这个规则选项。session规则选项有两个参数关键词:printable、all。使用printable,snort就会只输出可打印数据;使用all,snort就会输出所有的数据,不可打印的数据以16进制表示。不过,这个功能会大大降低snort的速度,所以不太适合大负载的情况,而且最好使用二进制日志文件格式。表15是一条记录telnet会话的规则:
log tcp any any <> 192.168.1.0/24 23 (session: printable;)
表15.记录可打印的telnet会话数据
格式:
session:[printable|all];
3.19 icmp_id
icmp_id规则选项用来检测ICMP回送(echo)数据包的ICMP ID号是否为一个特定的值。之所以会用到这个规则选项,是因为一些隐秘通道(covert channel)程序在通讯时使用静态的ICMP域。为了执行stacheldreht检测规则,开发了这个特别的插件,这些规则是由Max Vision(一位著名的白帽黑客,译者注)编写的。不过,它有助于检测其它一些潜在的攻击。
格式:
icmp_id:;
3.20 icmp_seq
icmp_seq规则选项用来检测一个ICMP回送包的ICMP序列号是否是一个特定的值。之所以会用到这个规则选项,是因为一些隐秘通道(covert channel)程序在通讯时使用静态的ICMP域。为了执行stacheldreht检测规则,开发了这个特别的插件,这些规则是由Max Vision编写的。不过,它有助于检测其它一些潜在的攻击。
格式:
icmp_seq:
3.21 rpc
规则选项rpc可以使snort观察RPC请求,并且自动对应用程序、过程(procedure)和程序版本进行解码。只有这三个变量都匹配时,才算成功。统配符*可以用来代替过程(procedure)和版本号。
格式:
rpc: ;
例子:
alert tcp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3;msg:"RPC getport (TCP)";)
alert udp any any -> 192.168.1.0/24 111 (rpc: 100000,*,3;msg:"RPC getport (UDP)";)
alert udp any any -> 192.168.1.0/24 111 (rpc: 100083,*,*;msg:"RPC ttdb";)
alert udp any any -> 192.168.1.0/24 111 (rpc: 100232,10,*;msg:"RPCsadmin";)
表16.几条RPC报警规则
3.22 resp
对于匹配某个规则的数据包,可以通过resp关键词使snort的灵活反应(flexible reponse,FlexResp)机制生效。使用FlexResp插件,snort能够主动断开恶意连接。下面是这个模块的参数:
rst_snd:向发送方套接字发送TCP-RST数据包
rst_rcv:向接受方套接字发送TCP-RST数据包
rst_all:在两个方向上发送TCP-TST数据包
icmp_net:向发送方发送ICMP_NET_UNREACH数据包
icmp_host:向发送方发送ICMP_HOST_UNREACH数据包
icmp_port:向发送方发送ICMP_PORT_UNREACH数据包
icmp_all:向发送方发送以上各种类型的ICMP数据包
多个参数可以结合使用,各个参数之间使用逗号隔开。
格式:
resp:;
例子:
alert tcp any any -> 192.168.1.0/24 1524 (flags:S;resp:rst_all;msg:"Root shell backdoor attempt";)
alert udp any any -> 192.1.168.1.0/ 31 (resp:icmp_port,icmp_host;msg:"Hacker's Paradise access attempt";)
表17.FlexResp规则
3.23 content-list
使用content-list关键词可以指定更多的正文字符串,突破了content规则选项只能指定单一字符串的限制。表18是一个conternt-list文件。每个要搜索的字符串占一行。这个规则选项是使用react关键词的基础。
#adult sites
porn
adults
hard core
www.pornsite.com
# ...
表18.content-list文件
格式:
content-list:"";
3.24 react
react关键词是基于FlexResp(flexible response)的,它使snort对匹配某个规则的数据包作出反应。基本的反应就是阻塞用户要访问的站点,例如色情站点。snort的FlexResp插件能够主动关闭恶意连接,如果连接使用的是http或者代理服务器端口,FlexResp插件就会向浏览器发出一条HTML/JavaScript警告信息。这个规则选项可以使用下面几个参数:
block:关闭连接并发出注意信息
warn:发出警告信息
这两个参数是基本参数,它们可以和下面的可选参数组合使用:
msg:定义要包含在警告信息中的文本
proxy::使用代理服务器端口发送警告信息
可选参数使用逗号分开,react关键词应该放在选项的最后。例如:
alert tcp any any <> 192.168.1.0/24 80 (content-list:"adults";msg:"Not for children!";react:block,msg;)
alert tcp any any <> 192.168.1.0/24 any (content-list:"adults";msg:"Adults list access attempt";react:block;)
表19.react规则
格式:
react:;
4.预处理器(preprocessors)
4.1 预处理器综述
从snort-1.5开始加入了对预处理器的支持。有了这种支持,用户和程序员能够比较容易地编写模块化的插件,扩展snort的功能。预处理器在调用检测引擎之前,在数据包被解码之后运行。通过这种机制,snort可以以一种out of band的方式对数据包进行修改或者分析。
预处理器可以使用preprocessor关键词来加载和配置,格式如下:
preprocessor :
例如:
preprocessor minfrag: 128
表20.预处理器指令格式
4.2 可用的预处理器模块
4.2.1 minfrag
这个预处理器测试分片包的大小是否为一个特定的值。数据包分片,通常是源/目的地址之间的路由器完成的。一般来说,商业网络设备产生的分片不会小于512个字节,基于这种情况,我们可以对很小的分片进行监视,很小的分片包一般是人为产生的,主要为了使用很小的碎片隐藏数据。
格式:
minfreg:<大小阀值>
4.2.2 HTTP decode预处理插件
HTTP解码预处理模块用来处理HTTP URI字符串,把它们转换为清晰的ASCII字符串。这样就可以对抗evasice web URL扫描程序和能够避开字符串内容分析的恶意攻击者。这个预处理模块使用WEB端口号作为其参数,每个端口号使用空格分开。
格式:
http_decode:<端口号列表>
例如:
preprocessor http_decode: 80 8080
表21.使用HTTP decode预处理模块的规则
4.2.3 端口扫描检测模块
snort端口扫描检测预处理模块是Patrick Mullen开发的,从他的个人主页可以得到更多信息。
snort端口扫描检测预处理模块主要做如下工作:
把由单个源IP地址发起的端口扫描从开始到结束的全过程记录到标准日志设备。
如果指定了一个日志文件,就把被扫描的IP地址和端口号和扫描类型都记录到这个日志文件。
这个模块使用的参数包括:
监视的网络: 以IP地址/子网掩码的格式指定要进行端口扫描监视的网络。
端口数: 在检测周期(detection period)内访问的端口数目。
检测周期(detection period): 达到某个设定的端口访问量需要的时间,以秒计。
日志目录/文件: 保存警告信息的目录/文件。警告信息也可以写到默认警告文件中。
格式:
portscan:<要监视的网络> <端口数> <检测周期> <日志目录/文件>
例子: preprocessor portscan:192.168.1.0/24 5 7 /var/log/portscan.log
表22.端口扫描检测模块的配置
4.2.4 portscan ignorehosts
Patrick Mullen对端口扫描检测系统进行了改进,形成了另一个模块--portscan ignorehosts。有些服务器程序容易和端口扫描检测模块造成冲突,例如NTP、NFS和DNS,如果你运行这些服务器程序,可以告诉端口扫描检测模块忽略对由特定主机发起的TCP SYN和UDP端口扫描的检测。这个模块使用的参数是一个要忽略的IP地址/CIDR的列表。
格式:
portscan-ignorehosts:<主机列表>
例子:
preprocessor portscan-ignorehosts:192.168.1.5/32 192.168.3.0/24
表23.portscan ignorehosts模块的配置
4.2.5 defrag模块
defrag插件是由Dragos Rulu开发的,它使snort能够消除IP碎片包,给黑客使用IP碎片包绕过系统的检测增加了难度。这个模块非常容易配置,不需要参数,直接放在preprocessor关键词之后即可。它的功能超过了migfrag模块的功能,所以你如果使用defrag,就不用在用minfrag模块了。
格式:
defrag
例子:
preprocessor defrag
defrag模块的配置
4.2.6 stream模块
stream插件为snort提供了TCP数据包重组的功能。在配置的端口上,stream插件能够对TCP数据包的细小片段进行重组成为完整的TCP数据包,然后snort可以对其可疑行为进行检查。这个插件有好多参数:
超时(timeout): 在一个TCP数据包送达之前,保存一个
TCP数据流缓冲的最长时间。
端口(port): 要监视的服务器端口。我们不想监视所有的
TCP端口,这也不太现实。
最大字节数(maxbytes): 重组包的最大长度。
格式:
stream:timeout ,ports ,maxbytes
例如:
preprocessor stream:timeout 5,ports 21 23 80 8080,maxbytes 16384
TCP数据包重组插件配置
4.2.7 spade:the Statisical Packet Anomaly Dection Engine
如果需要了解更多关于spade的信息,请参考snort源代码中的README.Spake文件,或者http://www.silicondefense.com/spice/。
使用这个模块使snort能够在你的网络上进行统计异常检测(statistical anomaly dection),这是一个全新的检测引擎。如果你对此感兴趣,请参考源代码中的有关文档和SiliconDefense站点的有关文档。
5.输出模块
5.1 输出模块综述
snort输出模块是从1.6版加入的新特征,使snort的输出更为灵活。snort调用其报警或者日志子系统时,就会调用指定的输出模块。设置输出模块的规则和设置预处理模块的非常相似。
在snort配置文件中可以指定多个输出插件。如果对同一种类型(报警、日志)指定了几个输出插件,那么当事件发生时,snort就会顺序调用这些插件。使用标准日志和报警系统,默认情况下,输出模块就会将数据发送到/var/log/snor目录,或者用户使用-l命令行开关指定的目录。
在规则文件中,输出模块使用output关键词指定:
格式:
output name:<选项>
例子:
output alert_syslog: LOG_AUTH LOG_ALERT
表26.输出模块的配置
5.2 可用的输出模块
5.2.1 alert_syslog
使用这个输出模块,snort把报警信息发送到syslog,与-s命令行开关非常类似。这个输出模块允许用户在规则文件中指定logging facility和优先级,给用户以更大的灵活性。
有效的关键词:
选项:
LOG_CONS
LOG_NDELAY
LOG_PERROR
LOG_PID
facility
LOG_AUTH
LOG_AUTHPRIV
LOG_DAEMON
LOG_LOCAL0
LOG_LOCAL1
LOG_LOCAL3
LOG_LOCAL4
LOG_LOCAL5
LOG_LOCAL6
LOG_LOCAL7
优先级
LOG_EMERG
LOG_ALERT
LOG_ERR
LOG_WARNING
LOG_NOTICE
LOG_INFO
LOG_DEBUG
格式:
alert_syslog: <优先级> <选项>
5.2.2 alert_fast
使用快速单行格式(quick on line format)把snort报警信息输出到指定的输出文件。这种报警方式比完全(full)报警模式速度快,因为使用这种报警模式不需要把全部的数据包头都输出到指定的文件。
格式:
alert_fast: <输出文件>
例子:
output alert_fast: alert.fast
表27.快速报警配置
5.2.3 alert_full
把全部的数据包头都输出到snort报警信息。这种报警机制一般较满,因为程序需要对整个数据包进行分析。报警信息可以输出到默认的日志目录/var/log/snort,也可以使用命令行指定日志目录。
格式:
alert_full:<输出文件>
例子:
output alert_full:alert_full
表28.full报警配置
5.2.4 alert_smb
snort使用这个插件把WinPopup报警信息输出到由NETBIOS命名的主机,主机名由参数指定的文件给出。注意我们不鼓励使用这种报警方式,因为samba客户程序smbclient以root权限运行。接收报警信息工作站的名字列表由保存在一个文件中,每行是一台主机的NETBIOS名字。
格式:
alert_smb:<文件>
例子:
output alert_smb:workstation.list
表29.SMB报警配置
5.2.5 alert_unixsock
设置一个UNIX域套接字(UNIX domain socket),把报警信息发送到这个套接字。外部程序/进程可以在这个套接字上监听,实时接收snort报警信息和数据包数据。这个接口目前尚处于实验状态。
格式:
alert_unixsock
示例:
output alert_unixsock
表30.UnixSock报警配置
5.2.6 log_tcpdump
log_tcpdump输出模块使用tcpdump格式的文件记录数据包日志。这种日志文件格式便于使用很多外部的工具对数据进行分析,只要这些工具软件支持tcpdump格式的文件。这个模块只有一个参数,就是输出文件的名字。
格式:
log_tcpdump:<输出文件名>
示例:
output log_tcpdump:snort.log
表31.tcpdump输出模块的配置
5.2.7 数据库输出模块
snort的数据库输出模块是JedPickel开发的,用来将snort产生的数据送到各种SQL数据库系统。如果要获得安装和配置这个模块更为详尽的信息,可以参考ncident.org web page。这个插件使用的参数是记录snort日志的数据库名和参数表。参数表使用这种格式:parameter=argument。有如下参数可以使用:
host: 数据库所在的主机。如果指定了一个非零字符串,snort就使用TCP/IP协议连接以此命名的主机。如果没有主机名,snort就使用一个本地UNIX-domain套接字连接本地主机。
port: 数据库所在服务器的端口号,或者一个UNIX-domain套接字文件。
dbname: 数据库名字。
user: 数据库用户名。
passwd: 密码。
sensor_name: 指定这个snort触发器的名字,如果没有指定就自动产生。
encoding: 因为数据包的负载和选项都是二进制数据,所以没有一种简单和可移植的方式将snort的数据保存在数据库。所以在snort数据库输出插件中提供了一些选项,让你自己决定使用那种编码。下面是这几种编码的优点和缺点:
hex: 默认编码选项,使用16进制字符串代表二进制数据。
存储空间: 两倍于二进制数据
搜索性: 极好
可读性: 极差
base64: 使用base64字符串代表二进制数据。
存储空间: 大约是直接存储二进制数据的1.3倍
搜索性: 可能无须后续处理。
可读性: 不可读需要后续处理。
ascii:: 使用ASCII字符串代替二进制数据。非ASCII字符使用.代替。如果你选择这个选项,那么IP和TCP包头的选项会仍然使用hex表示。
存储空间: 比直接存储二进制数据稍大。
搜索性: 非常便于二进制数据中搜索文本字符串。
可读性: 很好。
detail: 设置你要保存多少细节数据,有如下选项:
full: 保存引起报警的数据包的所有细节,包括IP/TCP包头和负载数据。
fast: 只记录少量的数据。如果选择这种记录方式,不利于以后对数据的分析,但在某些情况下还有其用处。使用这种方式,将记录数据包的以下域:时间戳(timestamp)、签名(signature)、源地址、目的地址、源端口、目的端口、TCP标志和协议。
还需要定义日志方法和数据库类型。有两种日志方法:log和alert。如果使用log,snort就会调用log输出,将日志数据记录到数据库;如果设置为alert,snort就会调用alert输出,在数据库中记录报警信息。
当前版本中,snort可以使用四种数据库:MySQL、PostgreSQL、Oracle以及和unixODBC兼容的数据库。可以使用你喜欢的数据库。
格式:
database:,<数据库类型>,<参数表>
例子:
output database:log,mysql,dbname=snort user=snort host=localhost password=xyz
表33.数据库输出插件配置
6.如何建立好的snort规则
在开发高效、高速的snort规则时,有几个概念要铭记于心。
3. 关键词content指定的内容是大小写敏感的,除非你使用nocase选项
不要忘记content规则选项指定的内容是大小写敏感的,许多程序一般使用大写表示命令。FTP就是一个很好的例子。请比较下面两条规则:
alert tcp any any -> 192.168.1.0/24 21 (content:"user root";msg:"FTP root login";)
alert tcp any any -> 192.168.1.0/24 21 (content:"USER root";msg:"FTP root login";)
第二条规则可以使snort捕获大多数使用root用户名的自动登录企图,而在数据包中从来就没有小写的user。
4. 提高snort对含有content规则选项的规则的检测速度
snort检测引擎对各个规则选项的测试顺序与其在各条规则中所处的位置无关。在各个规则选项中,检测引擎最后测试的总是content规则选项。因此,在开发规则时,要尽量使用快速的选项筛选掉根本不必对其内容进行检查的包。例如,如果实现了一个TCP会话过程,那么在会话过程的大部分时间内,双方传输的数据包的TCP标志ACK、PSH都被置位。而测试包头的TCP标志比对数据包的内容进行模式匹配需要的计算量要小的多。所以,在开发相关的检测规则时,需要设置flags规则选项对PSH和ACK没有置位的数据包进行过滤。而这样做,增加的额外计算量微乎其微。例如:
alert tcp any any -> 192.168.1.0/24 80(content:"cgi-bin/phf";flags:PA;msg:"CGI-PHF probe";)