前言
防火墙可以比喻为办公室门口的警卫,用来检查进出者的身份。而入侵检测系统就像是网上的警报器,当发现入侵者时,指出入侵者的来历、他们正在做什么。入侵检测系统被视为防火墙之后的第二道安全闸门。
实验目的
1.掌握snortIDS工作机理
2.应用snort三种方式工作
3.熟练编写snort规则
Snort IDS 概述
Snort IDS(入侵检测系统)是一个强大的网络入侵检测系统。它具有实时数据流量分析和记录IP网络数据包的能力,能够进行协议分析,对网络数据包内容进行搜索/匹配。它能够检测各种不同的攻击方式,对攻击进行实时报警。此外,Snort是开源的入侵检测系统,并具有很好的扩展性和可移植性。
Snort IDS体系结构
Snort体系结构
Snort的结构由4大软件模块组成,它们分别是:
(1)数据包嗅探模块——负责监听网络数据包,对网络进行分析;
(2)预处理模块——该模块用相应的插件来检查原始数据包,从中发现原始数据的“行为”,如端口扫描,IP碎片等,数据包经过预处理后才传到检测引擎;
(3)检测模块——该模块是Snort的核心模块。当数据包从预处理器送过来后,检测引擎依据预先设置的规则检查数据包,一旦发现数据包中的内容和某条规则相匹配,就通知报警模块;
(4)报警/日志模块——经检测引擎检查后的Snort数据需要以某种方式输出。如果检测引擎中的某条规则被匹配,则会触发一条报警,这条报警信息会通过网络、UNIXsocket、WindowsPopup(SMB)、SNMP协议的trap命令传送给日志文件,甚至可以将报警传送给第三方插件(如SnortSam),另外报警信息也可以记入SQL数据库。
Snort三种工作方式
Snort拥有三大基本功能:嗅探器、数据包记录器和入侵检测。嗅探器模式仅从网络上读取数据包并作为连续不断的流显示在终端上,常用命令snort -dev。数据包记录器模式是把数据包记录到硬盘上,常用命令snort -b。网络入侵检测模式是最复杂的,而且是可配置的。我们可以让Snort分析网络数据流以匹配用户定义的一些规则,并根据检测结果采取一定的动作。
Snort规则
snort规则定义
Snort使用一种简单的规则描述语言,这种描述语言易于扩展,功能也比较强大。Snort规则是基于文本的,规则文件按照不同的组进行分类,比如,文件ftp.rules包含了FTP攻击内容。「注」Snort的每条规则必须在一行中,它的规则解释器无法对跨行的规则进行解析。Snort的每条规则都可以分成逻辑上的两个部分:规则头和规则体。
规则头
规则头包括4个部分:规则行为;协议;源信息;目的信息。下图是对于规则头的描述。
Snort规则格式
snort规则头Snort预置的规则动作有5种:
(1)pass—动作选项pass将忽略当前的包,后继捕获的包将被继续分析。
(2)log—动作选项log将按照自己配置的格式记录包。
(3)alert—动作选项alert将按照自己配置的格式记录包,然后进行报警。它的功能强大,但是必须恰当的用,因为如果报警记录过多,从中攫取有效信息的工作量增大,反而会使安全防护工作变得低效。
(4)dynamic—动作选项dynamic是比较独特的一种,它保持在一种潜伏状态,直到activate类型的规则将其触发,之后它将像log动作一样记录数据包。
(5)activate—动作选项activate功能强大,当被规则触发时生成报警,并启动相关的dynamic类型规则。在检测复杂的攻击,或对数据进行归类时,该动作选项相当有用。
除了以上5种预置的规则动作类型,用户还可以定制自己的类型。
规则体
规则体的作用是在规则头信息的基础上进一步分析,有了它才能确认复杂的攻击(Snort的规则定义中可以没有规则体)。规则体由若干个被分别隔开的片断组成,每个片断定义了一个选项和相应的选项值。一部分选项是对各种协议的详细说明,包括IP、ICMP和TCP协议,其余的选项是:规则触发时提供给管理员的参考信息,被搜索的关键字,Snort规则的标识和大小写不敏感选项。
下面是一个规则实例。
alert tcp !192.168.0.1/24 any ->any 21 (content:"USER";msg: "FTP Login";)
- alert表示规则动作为报警。
- tcp表示协议类型为TCP协议。
- !192.168.0.1/24表示源IP地址不是192.168.0.1/24。
- 第一个any表示源端口为任意端口。
- ->表示发送方向操作符。
- 第二个any表示目的IP地址为任意IP地址。
- 21表示目的端口为21。
- content:"USER"表示匹配的字符串为“USER”。
- msg:"FTPLogin"表示报警信息为“FTPLogin”。
上面的规则也可写成:
此外,还有一个双向操作符<>,它使Snort对这条规则中,两个IP地址/端口之间的数据传输进行记录/分析,例如telnet或者POP3对话。下面的规则表示对一个telnet对话的双向数据传输进行记录:
log 192.168.0.1/24 any <> 192.168.0.1/24 23
activate/dynamic规则对扩展了snort功能。使用activate/dynamic规则对,你能够使用一条规则激活另一条规则,当一条特定的规则启动,如果你想要snort接着对符合条件的数据包进行记录时,使用activate/dynamic规则对非常方便。除了一个必需的选项activates外,激活规则非常类似于报警规则(alert)。动态规则(dynamic)和日志规则(log)也很相似,不过它需要一个选项:activated_by。动态规则还需要另一个选项:count。当一个激活规则启动,它就打开由activate/activated_by选项之后的数字指示的动态规则,记录count个数据包。
下面是一条activate/dynamic规则对的规则:
activate tcp any any -> any 23(activates:111;msg:"Telnet Login";) dynamic tcp any any -> any 23 (activated_by:111;count:20;)
当发现Telnet默认使用的23端口有通信,activate规则会被触发并启动dynamic规则,然后dynamic规则将遵循配置,记录后面的20个数据包。在上面的例子里activate规则的“activates”值为111,dynamic规则的“activated_by”值为111,这样就把两个规则关联起来,而不是因为这两个规则有相同的规则头。
预处理
预处理器在调用检测引擎之前,在数据包被解码之后运行。通过这种机制,Snort可以以一种out of band的方式对数据包进行修改或者分析。
预处理器可以使用preprocessor关键词来加载和配置,常用到的预处理器如下:
(1)HTTPdecode预处器HTTP解码预处理模块用来处理HTTPURL字符串,把它们转换为清晰的ASCII字符串。
(2)端口扫描器portscan端口扫描器会把由单个源IP地址发起的端口扫描从开始到结束的全过程记录到标准日志。
(3)stream处理器stream处理器为snort提供了TCP数据包重组的功能。在配置的端口上,stream处理器能够对TCP数据包的细小片段进行重组,使之成为完整的TCP数据包,然后snort可以对其可疑行为进行检查。
(4)frag2处理器frag2预处理器为snort提供了IP分片重组的功能。frag2预处理器能够对分片包进行重组来定位分片攻击,它的工作原理是将所有的分片重组构造成一个包含完整信息的数据包,再将这个包传给检测引擎。
Snort应用
Snort采用命令行方式运行。格式为:snort –[options]<filters>。options为选项参数;filters为过滤器。
Snort主要选项参数:
- -A<alert>设置报警方式为full,fast或者none。在full方式下,snort将传统的报警信息格式写入报警文件,报警内容比较详细。在fast方式下,snort只将报警时间,报警内容,报警IP地址和端口号写入文件。在none方式下,系统将关闭报警功能。
- -a显示ARP包。-b以tcpdump的格式将数据包记入日志。所有的数据包将以二进制格式记录到snort.log文件中。这个选项提高了snort的操作速度,因为直接以二进制存储,省略了转换为文本文件的时间,通过-b选项的设置,snort可以在100Mbps的网络环境中正常工作。
- -c<cf>使用配置文件<cf>。文件内容主要控制系统哪些包需要记入日志,哪些包需要报警,哪些包可以忽略等。
- -C仅抓取包中的ASCII字符。
- -d抓取应用层的数据包。
- -D在守护模式下运行snort。
- -e显示和记录数据链路层信息。
- -F<bpf>从文件<bpf>中读取BPF过滤信息。
- -h<hn>设置<hn>(C类IP地址)为内部网络。当使用这个开关时,所有从外部的流量将会有一个方向箭头指向右边,所有从内部的流量将会有一个左箭头。这个选项没有太大的作用,但是可以使显示的包的信息格式比较容易察看。
- -i<if>使用网络接口文件<if>。
- -l<ld>将包信息记录到目录<ld>下。设置日志记录的分层目录结构,按接收包的IP地址将抓取的包存储在相应的目录下。
- -n<num>处理完<num>包后退出。
- -N关闭日志功能,报警功能仍然工作。
- -p关闭混杂模式的嗅探(sniffing)。这个选项在网络严重拥塞时十分有效。
- -r<tf>读取tcpdump生成的文件<tf>,snort将读取和处理这个文件。
- -s将报警信息记录到系统日志,日志文件可以出现在/var/log/messages目录里。
- -v将包信息显示到终端时,采用详细模式。这种模式存在一个问题:它的显示速度比较慢,如果你是在IDS网络中使用snort,最好不要采用详细模式,否则会丢失部分包信息。
- -V显示版本号,并退出。
Filters过滤器
Snort的<filters>是标准的BPF格式的过滤器。
Snort应用了BPF机制,可以在探测器上书写和执行BPF规则的文件。BPF机制允许用户书写快速的包分析规则,这些规则主要基于源、目的、和其他的头信息。通过嗅探和BPF,我们可以只捕获需要的流量,这样就减轻了需要处理的数据量。
BPF机制很容易理解,可以用于分析TCP、UDP、IP和ICMP协议。规则语法很像自然的口语,使用“and”和“or”作为规则操作符,用“not”作为取反符,此处还可以用括号来告诉引擎将一系列数据作为一个整体来处理。例如:ICMP捕获:icmp。
telnet请求数据包捕获:tcp and dst port 23
。记录所有源自网络192.168.0.0/24,目的是202.98.0.0/24的IP流量:ip and "src net 192.168.0 " and "dst net 202.98.0 "
。
实验步骤
本练习主机A、B为一组,C、D为一组,E、F为一组。首先使用“快照X”恢复Linux系统环境。
一.Snort数据包嗅探
1.启动Snort进入实验平台,单击工具栏“控制台”按钮,进入IDS工作目录,运行Snort对网络接口eth0进行监听,要求如下:
(1)仅捕获同组主机发出的icmp回显请求数据包。
(2)采用详细模式在终端显示数据包链路层、应用层信息。
(3)对捕获信息进行日志记录,日志目录/var/log/snort。
Snort命令:
snort –i eth0 –dev icmp and src 172.16.0.141 –l /var/log/snort
2.查看Snort日志记录。
「说明」默认snort日志记录最后一级目录会以触发数据包的源IP命名。可使用组合键Ctrl+C停止snort运行。
二.Snort数据包记录
(1)对网络接口eth0进行监听,仅捕获同组主机发出的Telnet请求数据包,并将捕获数据包以二进制方式进行存储到日志文件中/var/log/snort/snort.log)。
Snort命令:
snort –i eth0 –b tcp and src 172.16.0.141 and dst port 23
(2)当前主机执行上述命令,同组主机telnet远程登录当前主机。
(3)停止snort捕获(Ctrl+C),读取snort.log文件,查看数据包内容。Snort命令: snort –F /var/log/snort.log
三.简单报警规则
(1)在snort规则集目录ids/rules下新建snort规则集文件new.rules,对来自外部主机的、目标为当前主机80/tcp端口的请求数据包进行报警,报警消息自定义。snort规则:
alert tcp any any -> 172.16.0.142 80 (msg:"Telnet Login")
(2)编辑snort.conf配置文件,使其包含new.rules规则集文件,具体操作如下:使用vim(或vi)编辑器打开snort.conf,切换至编辑模式,在最后添加新行包含规则集文件new.rules。添加包含new.rules规则集文件语句 include &RULE PATH/new.rules
(3)以入侵检测方式启动snort,进行监听。启动snort的命令 snort –c snort.conf
以入侵检测方式启动snort,同组主机访问当前主机Web服务。
转载自:https://www.jianshu.com/p/113345bbf2f7
**********************************************************************************************************************************
Snort规则被分成两个逻辑部分:规则头和规则选项。规则头包含规则的动作,协议,源和目标ip地址与网络掩码,以及源和目标端口信息;规则选项部分包含报警消息内容和要检查的包的具体部分。
1. 规则头:
规则动作:
在snort中有五种动作:alert、log、pass、activate和dynamic.
1、Alert-使用选择的报警方法生成一个警报,然后记录(log)这个包。
2、Log-记录这个包。
3、Pass-丢弃(忽略)这个包。
4、activate-报警并且激活另一条dynamic规则。
5、dynamic-保持空闲直到被一条activate规则激活,被激活后就作为一条log规则执行。
协议类型:
Snort当前分析可疑包的ip协议有四种:tcp 、udp、icmp和ip。将来可能会更多,例如ARP、IGRP、GRE、OSPF、RIP、IPX等。
地址:
关键字"any"可以被用来定义任何地址。地址就是由直接的数字型ip地址和一个cidr块组成的。cidr块指示作用在规则地址和需要检查的进入的任何包的网络掩码。/24表示c类网络, /16表示b类网络,/32表示一个特定的机器的地址。
否定操作符用"!"表示。
你也可以指定ip地址列表,一个ip地址列表由逗号分割的ip地址和CIDR块组成,并且要放在方括号内“[”,“]”。此时,ip列表可以不包含空格在ip地址之间。
例如:
alert tcp ![192.168.1.0/24,10.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";)
变量定义:
var MY_NET 192.168.1.0/24
alert tcp any any -> $MY_NET any (flags: S; msg: "SYN packet";)
注:"$" 操作符之后定义变量;
"?" 和 "-"可用于变量修改操作符;
$var - 定义变量。
$(var) - 用变量"var"的值替换。
$(var:-default) - 用变量"var"的值替换,如果"var"没有定义用"default"替换。
$(var:?message) - 用变量"var"的值替换或打印出错误消息"message"然后退出。
例如:
var MY_NET $(MY_NET:-192.168.1.0/24)
log tcp any any -> $(MY_NET:?MY_NET is undefined!) 23
端口号:
端口号可以用几种方法表示,包括"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 :6000
记录来自任何端口,目标端口小于等于6000的tcp流
log tcp any :1024 -> 192.168.1.0/24 500:
记录来自任何小于等于1024的特权端口,目标端口大于等于500的tcp流
方向操作符:
方向操作符"->"表示规则所施加的流的方向。方向操作符左边的ip地址和端口号被认为是流来自的源主机,方向操作符右边的ip地址和端口信息是目标主机,还有一个双向操作符"<>"。
2. 规则选项:
规则选项组成了snort入侵检测引擎的核心,既易用又强大还灵活。所有的snort规则选项用分号";"隔开。规则选项关键字和它们的参数用冒号":"分开。例如:
- msg - 在报警和包日志中打印一个消息。
- flags -检查tcp flags的值。
- content - 在包的净荷中搜索指定的样式。
Content关键字的选项数据比较复杂;它可以包含混合的文本和二进制数据。二进制数据一般包含在管道符号中("|"),表示为字节码(bytecode)。字节码把二进制数据表示为16进制数字,是描述复杂二进制数据的好方法。例如:content: "|90C8 C0FF FFFF|/bin/sh";
字符: ; \ "
在content选项内容中出现时必须被转义(有两个方法:1.用前导“\”字符 2. 使用字节的二进制表示方式,比如用“|3A|”表示“:”):
内容匹配项的默认是区分大小写的; - offset - content选项的修饰符,设定开始搜索的位置 。
- depth - content选项的修饰符,设定搜索的最大深度。
- nocase - 指定对content字符串大小写不敏感。
- distance - content选项的修饰符,设定模式匹配间的最小间距;
distance关键字是content关键字的一个修饰词,确信在使用content时模式匹配间至少有N个字节存在。它被设计成在规则选项中和其他选项联合使用。
格式:distance: ;
例子:alert tcp any any -> any any (content: "2 Patterns"; content: "ABCDE"; content: "EFGH"; distance: 1;)
- within - content选项的修饰符,设定模式匹配间的最大间距;
within关键字是content关键字的一个修饰词,确保在使用content时模式匹配间至多有N个字节存在。它被设计成在规则选项中和distance选项联合使用。
格式:within: ;
例子:alert tcp any any -> any any (content: "2 Patterns"; content: "ABCDE"; content: "EFGH"; within: 10;)
- byte_test - 数字模式匹配。
把数据包净载中特定位置的字串转换为数值类型与指定的值进行比较。
格式:byte_test: , , , [[relative],[big],[little],[string],[hex],[dec],[oct]] - bytes_to_convert 从数据包取得的字节数。
- operator 对检测执行的操作 (<,>,=,!)。
- value 和转换后的值相测试的值。
- offset 开始处理的字节在负载中的偏移量。
- relative 使用一个相对于上次模式匹配的相对的偏移量。
- big 以网络字节顺序处理数据(缺省)。
- little 以主机字节顺序处理数据。
- string 数据包中的数据以字符串形式存储。
- hex 把字符串数据转换成十六进制数形式。
- dec 把字符串数据转换成十进制数形式。
- oct 把字符串数据转换成八进制数形式。
例子:alert udp $EXTERNAL_NET any -> $HOME_NET any (msg:"AMD procedure 7 plog overflow "; content: "|00 04 93 F3|"; content: "|00 00 00 07|"; distance: 4; within: 4; byte_test: 4,>, 1000, 20, relative;)
- uricontent - 用于匹配正规化处理后URI字段。
这个关键字允许只在一个请求的URI(URL)部分进行搜索匹配。它允许一条规则只搜索请求部分的攻击,这样将避免服务数据流的错误报警。关于这个关键字的参数的描述可以参考content关键字部分。这个选项将和HTTP解析器一起工作。(只能搜索第一个“/”后面的内容)。
例如:uricontent:".emf"; - Flow
这个选项要和TCP流重建联合使用。它允许规则只应用到流量流的某个方向上。这将允许规则只应用到客户端或者服务器端。这将能把内网客户端流览web页面的数据包和内网服务器所发送的数据包区分开来。这个确定的关键字能够代替标志:A+ 这个标志在显示已建立的TCP连接时都将被使用。
选项:
to_client 触发上服务器从A到B的响应。
to_server 触发客户端上从A到B的请求。
from_client 触发客户端上从A到B的请求。
from_server 触发服务器上从A到B的响应。
established 只触发已经建立的TCP连接。
stateless 不管流处理器的状态都触发(这对处理那些能引起机器崩溃的数据包很有用。
no_stream 不在重建的流数据包上触发。
only_stream 只在重建的流数据包上触发。
格式:flow:[to_client|to_server|from_client|from_server|established|stateless|no_stream|only_stream]
reference - 外部攻击参考ids。
这个关键字允许规则包含一个外面的攻击识别系统。这个插件目前支持几种特定的系统,它和支持唯一的URL一样好。这些插件被输出插件用来提供一个关于产生报警的额外信息的连接。 - sid - snort规则id。
这个关键字被用来识别snort规则的唯一性。这个信息允许输出插件很容易的识别规则的ID号。
sid 的范围是如下分配的:
<100 保留做将来使用
100-1000,000 包含在snort发布包中
1000,000 作为本地规则使用
- rev - 规则版本号。
这个关键字是被用来识别规则修改的。修改,随同snort规则ID,允许签名和描述被较新的信息替换。 - classtype - 规则类别标识。
这个关键字把报警分成不同的攻击类。通过使用这个关键字和使用优先级,用户可以指定规则类中每个类型所具有的优先级。 - pcre:
pcre选项允许用户使用与PERL语言相兼容的正则表达式。相关正则表达式的具体细节参看PCRE的Web站点:http://www.pcre.org
pcre:[!]"(/<regex>/|m<delim><regex><delim>)[ismxAEGRUB]";
在表达式后的修饰符设置编译正则表达式的一些标志。
Perl兼容的修饰符:
|i| 对大小不敏感
|s| 在点转义符号中包含换行符, 一般情况下被匹配的缓冲区是作为一个大字符串
|m| 的,和$分别匹配串头和串尾。当设置了m修饰符,和$匹配跟紧跟换行符和紧先导于换行符的情况
|x| 要匹配的模式中的空格符被忽略,除非是被转义过的或在一个字符集中。
PCRE兼容的修饰符:
|A| 模式必须在缓冲区的开头匹配到(同^) 设置指定的$必须匹配到缓冲区末尾。如果不用E |
|E| 修饰符,$则可能只匹配到串尾之前换行符。
|G| 在默认情况下不使用“贪婪”模式,只有在模式后面跟了“?”字符的情况下贪婪。
Snort特定的修饰符:
|R| 此匹配相对于前一个匹配成功串尾开始(类似于distance:0)
|U| 匹配解码后的URI缓冲区(类似于uricontent
|B| 不使用解码后的缓冲区(类似于rawbytes)
修饰符R和B不能同时使用。
例如:alert ip any any -> any any (pcre:"/BLAH/i";)
例子:
alert tcp $EXTERNAL_NET $HTTP_PORTS -> $HOME_NET any (msg:"WEB-CLIENT PNG large colour depth download attempt"; flow:from_server,established; content:"|89|PNG|0D 0A 1A 0A|"; content:"IHDR"; within:8; byte_test:1,>,16,8,relative;classtype:attempted-user; sid:3134; rev:3;reference:url,www.microsoft.com/technet/security/bulletin/MS05-009.mspx; )
alert tcp $EXTERNAL_NET any -> $HOME_NET 139 (msg:"NETBIOS SMB Trans Max Param/Count DOS attempt"; flow:established,to_server; content:"|00|"; depth:1; content:"|FF|SMB%"; within:5; distance:3; byte_test:1,!&,128,6,relative; pcre:"/^.{27}/sR"; content:"|00 00 00 00|"; within:4; distance:5;reference:url,www.corest.com/common/showdoc.php?idx=262;classtype:protocol-command-decode; sid:2101; rev:15;)
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (msg:"SPYWARE-PUT Hijacker shop at home select installation in progress"; flow:to_server,established; uricontent:"GRInstallCL.asp"; nocase; uricontent:"E="; nocase; uricontent:"MID="; nocase; uricontent:"Refer="; nocase; uricontent:"WGR="; nocase; uricontent:"Prev="; nocase; uricontent:"sGUID="; nocase; classtype:misc-activity; sid:5810; rev:1;)
正则表达式元字符的解释:
\: 转移字符,将后一个字符标记为一个特殊字符
^:匹配输入字串的开始位置
$:匹配输入字串的结束位置
*:匹配前面的子表达式0次或多次
+:匹配前面的子表达式1次或多次
?:匹配前面的子表达式0次或1次
{n,m}:匹配至少n次,至多m次
.:匹配到除"\n"之外的所有单个字符
[]:表示一个字符集,可以单个列出,如[amk$];也可以加一个"-"表示一个字符范围,如[a-z];匹配任意一个字符即可;也可以用补集来匹配不在区间范围内的字符。其做法是把""作为类别的首个字符;其它地方的""只会简单匹配 ""字符本身,例如[5] 将匹配除 "5" 之外的任意字符。
例如:
pcre:"/X-Mailer\x3A[\r\n]*mPOP\s+Web-Mail/smi";
pcre:"/Host\x3A[\r\n]*e2give.com/smi";
pcre:"/User-Agent\x3A[\r\n]*NSISDL/smi";
pcre:"/Host\x3A[\r\n]*push\x2Ecom/smi";
...
注:\x 后为十六进制转义值
\r 匹配一个回车符
\n 匹配一个换行符
\s 匹配任何空白字符
\d 匹配任何十进制数;它相当于类 [0-9]。
\D 匹配任何非数字字符;它相当于类 [^0-9]。
\s 匹配任何空白字符;它相当于类 [ \t\n\r\f\v]。
\S 匹配任何非空白字符;它相当于类 [^ \t\n\r\f\v]。
\w 匹配任何字母数字字符;它相当于类 [a-zA-Z0-9_]。
\W 匹配任何非字母数字字符;它相当于类 [^a-zA-Z0-9_]。