Snort
- Snort简介
- Snort安装与配置
- Snort总体结构分析
- Snort的使用
- Snort的规则
- 使用 Snort构建入侵检测系统实例
Snort简介
Snort是一个基于 Libpcap的轻量级网络入侵检测系统,它运行在一个“传感器(Sensor)”主机上,监听网络数据。
Snort能够把网络数据和规则集进行模式匹配,从而检测可能的入侵企图;或者使用 SPADE(Statistical Packet Anomaly Detection Engine)插件,使用统计学方法对网络数据进行异常检测。
Snort使用一种易于扩展的模块化体系结构,开发人员可以加入自己编写的模块来扩展Snort的功能,如HTTP解码插件、TCP数据流重组插件、端口扫描检测插件、FLEXRESP插件以及各种日志输入插件等。
Snort的特点
-
Snort是一个轻量级的入侵检测系统。Snort虽然功能强大,但是其代码极为简洁、短小,其源代码压缩包只有大约110KB。
-
Snort的跨平台性能极佳,Snort具有跨平台的特点,它支持的操作系统广泛,包括 Linux、OpenBSD、FreeBSD、NetBSD、Solaris、HP-UX、AIX、IRIX、Win32(Windows9xNT2000)等。
-
Snort的功能非常强大:
- Snort具有实时流量分析和日志IP网络数据包的能力。
- Snort能够进行协议分析,内容的搜索/匹配。
- Snort的日志格式既可以是 Tcpdump式的二进制格式,也可以解码成ASCII字符形式。
- Snort可以对TCP包进行重组。
- Snort能够报告非正常的可疑包,从而对端口扫描进行有效的检测。
- Snort还有很强的系统防护能力。
-
扩展性能较好,对于新的攻击威胁反应迅速。作为一个轻量级的网络入侵检测系统,Snort有足够的扩展能力。Snort支持插件,可以使用具有特定功能的报告、检测子系统插件对其功能进行扩展。Snort当前支持的插件包括数据库日志输岀插件、碎数据包检测插件、端口扫描检测插件、HTTP URI normalization插件、XML插件等。
-
遵循公共通用许可证GPL
- Snort遵循GPL,所以任何企业、个人、组织都可以免费使用它作为自己的NIDS。
Snort的组成
Snort由3个重要的子系统构成:数据包解码器、检测引擎、日志与报警系统。
Snort的工作模式
Snort有以下3种工作模式。
- 嗅探器——嗅探器模式仅仅是从网络上:读取数据包并作为连续不断的流显示在终端上。
- 数据包记录器——数据包记录器模式把数据包记录到硬盘上。
- 网络入侵检测系统——网路入侵检测模式是最复杂的而且是可配置的。用户可以让 Snort分析网络数据流以匹配用户定义的一些规则,并根据检测结果采取一定的动作。
Snort安装
略
Snort总体结构分析
插件机制优点
在 Snort中运用了插件机制。对于 Snort来说,插件机制具有以下一些明显的优点。
- 通过增加插件,Snort能够非常容易地増加功能,使程序具有很强的可扩展性。
- 插件机制简化了Snort的编码工作。
- 插件机制使代码功能内聚,模块行强,程序相对易读。
- 插件模块包括预处理插件、处理插件和输出插件3种,它们通常对应规则中的一个或几个关键字,规则匹配中遇到这些关键字时就会激活相应的插件,以完成相应的功能。
预处理插件
它们的源文件名都是以spp_开头的,在规则匹配(误用检测)之前运行,完成的功能主要分为以下几类。
- 模拟 TCP/IP堆栈功能的插件:如I碎片重组、TCP流重组插件。
- 各种解码插件:如HITP解码插件、Unicode解码插件、RPC解码插件、Telnet协商插件等。
- 规则匹配无法进行攻击检测时所用的检测插件:如端口扫描插件、Spade异常入侵检测插件、Bo检测插件、Arp欺骗检测插件等。
处理插件
它们的源文件名都以sp_开头,在规则匹配阶段的ParseRuleOptions中被调用,辅助完成基于规则的匹配检测过程。每个规则处理函数通常对应规则选项中的一个关键字,实现对这个关键字的解释或辅助解释。这些插件的主
要功能如下。
- 协议各字段的检查,如 TCPFlag,IcmpType,IcmpCode,Ttl,IpId,TcpAck,TcpSeg,Dsize,IpOption,Rpc,Icmpld,IcmpSeq,IpTos,Frag Bits,TcpWin,IpProto和 IpSame等。
- 一些辅助功能,如 Respond,Priority,Pattern Match,Session,React,Reference等,这些插件分别完成响应(关闭连接)、严重级别、模式匹配(内容)、会话记录、攻击响应(高级的响应机制)、攻击参考信息等功能。
输出插件
它们的源文件名都以spo_开头,这些插件分为日志和警告两种类型放入两个列表中,在规则匹配过程中和匹配结束之后调用,以便记录日志和警告。以一个HTTP解码预处理器插件为例来解释插件的内部结构:
- 每个插件都有一个安装函数,名称为 SetupXXX(),如Spp_http_decode.c: Setuphttpdecode()
- 在解释规则文件时,如果检测到相应的关键字,系统就会使用规则文件中这些关键字后的字符串作为参数来调用相应的初始化函数。
- 在检测过程中,一旦规则匹配成功,就会触发处理函数的执行,预处理器就会在预处理过程中对数据报调用相应处理函数进行处理。
Snort使用
Libpcap的命令行
Snort和大多数基于 Libpcap的应用程序(如 Tcpdump)一样可以使用标准BPF类型的过滤器。过滤器的正确设置将决定 Snort是否只看到所感兴趣的数据包,如果没有设置过滤器,Snort将看到所有网络中的数据包。
整个过滤器的表达式由一个或多个元语组成,而一个元语则是由一个或多个关键字加上一个相关的值(字符串或数字)所组成。
关键字分为以下几类。
- 属性类关键字:说明后面所跟值的意义,这样的关键字有host、net、port。如果一个元语没有属性关键字,默认为host。
- 方向类关键字:说明报文的流向,这样的关键字有src,dst,src or dst,src and dst。对于空连接层(如:使用slip等的点到点协议),可以使用 inbound和 outbound来说明方向
- 协议类关键字:用来限制协议,这样的关键字有 ether,fddi,ip,arp,rarp,decnet,lat,sca,moprc,mopdl,tcp,udp。如果一个元语没有协议类关键字,那么所有可能的协议都将符合。
过滤器的描述功能非常强大,可以用来描述任何想要得到的报文。例如
net 192.168.1 and not host 192.168.1.1
说明除了主机192.168.1.1外其他所有192.168.1网段的网络数据报文。
tcp[13]&3!=0 and not src and dst net localnet
说明涉及外网的tcp会话中起始和终止报文(SYN和FIN报文)
Snort的命令行
Snort的命令行参数很多,可以使用 Snort-?命令列出这些参数及其简单的解释,详细的解释可以使用 man Snort命令查看帮助页。
-
-A 设置报警模式:fast、full、none(只是使用报警文件)、undock(使用UNIX套接字记入日志,出于测试阶段)。
-
-a 显示ARP(Address resolution protocol,地址解析协议)包。
-
-b 日志文件使用tcpdump格式(更快)
-
-c 使用规则文件 rules
-
-C 只使用字符方式打印负载信息(不使用hex方式)
-
-d 复制应用层。
-
-D 在后台运行 Snort(精灵状态)。
-
-e 显示第二层(数据链路层)包头信息。
-
-F Read BPF filters from file
-
-g 初始化完成后,使 Snort的gid为 gname
-
-h Home网络为hn
-
-i 在接口if监听。
-
-I 把界面名加入到报警输出界面。
-
-I 设置目录ld为日志目录。
-
-M把SMB消息发送到文件 wrkst列出的工作站中(Requires smbclient to be in PATH)
-
-n收到cnt个包后退出。
-
-N关闭日志功能(警报功能仍然有效)。
-
-o把规则测试顺序修改为:Pass|Alert|Log
-
-O打乱被日志的IP地址
-
-p关闭混杂嗅探模式。
-
-P设置复制的包的长度为 snaplen(默认:1514)
-
-q安静模式。不输出 banner和状态报告
-
-r读取并处理 tcpdump文件tf(回放功能)。
-
-s把所有警告信息记入 syslog
-
-S设置规则文件中的n的值等于v的值。
-
-t初始化完成后 Chroot到dir目录。
-
-u初始化完成后,把 Snort的uid设置为 uname。
-
-v设置冗余模式。
-
-V显示版本号。
-
-X从链路层开始复制包的数据。
-
-?显示帮助信息。
如果在一个高数据流量(例如大于100 Mbit/s)的网络环境下运行 Snort,就需要考虑如何配置 Snort才能使它高效率地运行,这就要求使用更快的输出功能,产生更少的警告,可以使用诸如-b,-A fast,-s等选项。例如:
./Snort -b -A fast -c Snort-Iib
使用这种配置选项,日志信息将被以二进制的 tcpdump格式记录到Snort.log文件中。然后,使用下面带有-选项的命令读取这个文件,做进一步的分析:
./Snort -d -c Snort-lib-I ./log-h 192 1681.0/24 -r Snort.log
Snort的规则
Snort规则分为两个部分:规则头和规则选项。规则头包含规则的动作、协议、源地址、目的地址、子网掩码、源和目的端口信息。规则选项包含报警信息以及用于确定是否触发规则响应动作而检查的数据包区域位置信息。
规则头
规则动作
规则的头包含了定义一个包的Who,Where和What信息,以及当满足规则定义的所有属性的包出现时要采取的行动。规则的第一项是“规则动作”(Rule action),“规则动作”告诉Snort在发现匹配规则的包时要干什么。在 Snort中有5种动作:Alert,Log,Pass,Activate和 Dynamic。
协议
规则的下一部分是协议。Snort当前分析可疑包的协议有4种:TCP,UDP,ICMP和IP,将来可能会更多,如ARP,IGRP,GRE,OSPF,RIP,IPX等。
IP地址
规则头的下一个部分处理一个给定规则的P地址和端口号信息。关键字 “any” 可以被用来定义任何地址。
有一个操作符可以应用在IP地址上,它是否定运算符。这个操作符告诉Snort匹配除了列出的IP地址以外的所有IP地址。否定操作符用“!”表示。下面这条规则对任何来自本地网络以外的流都进行报警。
端口号
端口号可以用几种方法表示,包括“any端口、静态端口定义、范围、以及通过否定操作符。“any”端口是一个通配符,表示任何端口。静态端口定义表示一个单个端口号,例如,111表示Portmapper,23表示Telnet,80表示HTTP等。端口范围用范围操作符“:”表示。
方向操作符
方向操作符“->”表示规则所施加的流的方向。方向操作符左边的IP地址和端口号被认为是流来自的源主机,方向操作符右边的I地址和端口信息是目标主机,还有一个双向操作符“<>。它告诉 Snort把地址/端口号对既作为源,又作为目标来考虑。这对于记录/分析双向对话很方便,例如,Telnet或者POP3会话。
Activate和 Dynamic规则
注意:Activate和 Dynamic规则将被 Tagging所代替。在 Snort的将来版本,Activate和 Dynamic规则将完全被功能增强的Tagging所代替。
Activate和 Dynamic规则对给了 Snort更强大的能力。用户现在可以用一条规则来激活另一条规则,当这条规则适用于些数据包时,在一些情况下这是非常有用的,例如用户想设置一条规则:当一条规则结束后来完成记录。Activate规则除了包含一个选择域:Activates外就和一条 Alert规则一样。
规则选项
规则选项组成了 Snort入侵检测引擎的核心,既易用又强大还灵活。所有的 Snort规则选项用分号“;”隔开。规则选项关键字和它们的参数用冒号“:”分开。按照这种写法,Snort中有以下42个规则选项关键字。
- msg——在报警和包日志中打印一个消息
- logto——把包记录到用户指定的文件中而不是记录到标准输出。
- ttl——检查IP头的TTL的值。
- tos——检查IP头中TOS字段的值。
- id——检查IP头的分片ID值。
- ipoption——查看IP选项字段的特定编码
- fragbits——检查IP头的分段位。
- dsize——检查包的净荷尺寸的值。
- flags——检查 TCP Flags的值。
- seq——检查TCP顺序号的值。
- ack——检查TCP应答(Acknowledgement)的值。
- window——测试TCP窗囗域的特殊值。
- itype——检查 ICMP Type的值。
- icode——检查 ICMP Code的值。
- icmp_id——检查 ICMP ECHO ID的值。
- Icmp_seg——检查 ICMP ECHO顺序号的值。
- content——在包的净荷中搜索指定的样式。
- content-list——在数据包载荷中搜索一个模式集合。
- offset——Content选项的修饰符,设定开始搜索的位置。
- depth——Content选项的修饰符,设定搜索的最大深度。
- nocase——指定对 Content:字符串大小写不敏感。
- session——记录指定会话的应用层信息的内容。
- rpc——监视特定应用进程调用的RPC服务。
- resp——主动反应(切断连接等)。
- react——响应动作(阻塞Web站点)。
- reference——外部攻击参考IDS。
- sid——Snort规则ID。
- rev——规则版号
- classtype——规则类别标识。
- priority——规则优先级标识号。
- uricontent——在数据包的URI部分搜索一个内容。
- tag——规则的高级记录行为。
- ip_proto——IP头的协议字段值
- sameip——判定源IP和目的IP是否相等。
- stateless——忽略流状态的有效性。
- regex——通配符模式匹配。
- distance——强迫关系模式匹配所跳过的距离。
- within——强迫关系模式匹配所在的范围。
- byte_test——数字模式匹配。
- byte_jump——数字模式测试和偏移量调整。
规则的语法
规则分类存放在规则文件中。规则文件是普通的文本文件,用户可以使用普通的文本编辑器打开进行编辑。
规则文件可以包含注释行,注释行以“#”字符开头,#号前不能有任何非空字符。
Snort允许定义变量,并在规则中使用这些变量。变量的定义格式如下所示:
var:
在规则中可以直接使用 $,而遇到变量名解释器就会使用< value>替代 $。
预处理程序
预处理程序使得 Snort的功能可以很容易地扩展,用户和程序员能够将模块化的插件方便地融入Snort之中。预处理程序代码在探测引擎被调用之前运行,但在数据包译码之后。通过这个机制,数据包可以通过额外的方法被修改或分析。使用 preprocessor关键字加载和配置预处理程序。
在 Snort规则文件中的 preprocessor指令格式如下:
preprocessor :
例如:
preprocessor minfrag:128
输出插件
输出插件使得Snot在向用户提供格式化输出时更加灵活。输出插件在 Snort的告警和记录子系统被调用时运行,在预处理程序和探测引擎之后。规则文件中指令的格式非常类似于预处理程序。
格式:
output :
例子:
output alert_syslog:LOG_AUTH LOG_ALERT
规则例子
(1)记录所有登录到一个特定主机的数据包:
log tcp any any->192.168.1.1/32 23
(2)在第一条的基础上记录了双向的流量:
log tcp any any<>192.168.1.1/32 23
(3)这一条规则记录了所有到达你的本地主机的icmp数据包:
log icmp any any-> 192.168 1.0/24 any
(4)这条规则允许双向的从你的机子到其他站点的http包:
pass tcp any 80<>192.168 1.0/24 any
(5)这条告警规则显示了本地主机对其他主机的111端口的访问,并在log中显示端口影射调用(‘portmapper call’)信息:
alert tcp 192.168.1.0/24 any-> any 111(msg:“Portmapper call”;)
(6)记录其他任意地址的小于1024端口访问本地小于1024端口的流量:
log tcp any :1024->192.168.1.0/24 :1024
(7)这条规则将会发现 SYN FIN扫描:
alert tcp any any-> 192.168 1.0/24 any(msg:“SYN-FIN scan!”;flags: SF;)
(8)这条规则将会发现空TCP扫描:
alert tcp any any->192.168.1.0/24 any(msg:Null scan!"flags:0;)
(9)这条规则将会发现 Queso fingerprint扫描:
alert tcp any any-> 192.168 1.0/24 any(msg:“Queso fingerprint”;flags: S12;)
(10)这条规则将进行基于内容的查找以发现溢出攻击:
alert tcp any any-192 168 1.0/24 143(msg:“IMAP Buffer overflow!”; content: “|90E8 COFF FFFF|/bin/sh”;)
(11)这条规则将会发现PHF攻击:
alert tcp any any->192.168.1.0/24 80(msg:"PHF attempt "; content: “/cgi-bin/phf”; )
(12)这条规则将会发现 Traceroute包:
alert udp any any-192.168.1.0/24 any(msg:“Traceroute”;ttl:1;)
(13)这条规则将会发现其他主机对本地发出的icmp包:
alert udp any any->192.168 1.0/24 any(msg:“Traceroute”;ttl:1)
(14)这条规则发现nmap的TCP的ping扫描:
alert tcp any any->192.168.1.0/24 any(flags:A;ack:0;msg:NMAP TCP ping!"; )
(15)这条规则将会发现源路由的数据包(源路由攻击):
alert tcp any any-> any any(ipopts:lsrr;msg:“Source Routed packet!”; )