SNORT 入侵检测系统
原名称 | SNORT 入侵检测系统 |
作者 | YxWa |
原平台 | 乌云 |
原文链接 | http://drops.wooyun.org/运维安全/9232 |
转载声明 | 由于乌云已无法访问,无法联系原作者,文章内容来自于乌云镜像站 |
0x00 一条简单的规则
alert tcp 202.110.8.1 any -> 122.111.90.8 80 (msg:”Web Access”; sid:1)
- alert:表示如果此条规则被触发则告警
- tcp:协议类型
- ip地址:源/目的IP地址
- any/80:端口号
- ->:方向操作符,还有
<>
双向。 - msg:在告警和包日志中打印消息
- sid:Snort 规则 id
这条规则看字面意思就很容易理解。Snort 就是利用规则来匹配数据包进行实时流量分析,网络数据包记录的网络入侵检测/防御系统(Network Intrusion Detection/Prevention System),也就是 NIDS/NIPS。
0x01 SNORT目录结构
建议将 Snort 的目录结构配置成如下:
/etc/snort ├── barnyard2.conf barnyard2日志分析工具配置文件 ├── snort.conf snort配置文件(关键) ├── threshold.conf 事件过滤配置文件 ├── classification.config 规则分类配置文件(classtype) ├── reference.config 外部参考配置文件(reference) ├── gen-msg.map generate id 和 msg 对应关系map ├── sid-msg.map snort id 和 msg对应关系map ├── unicode.map 预处理器http_inspect编码翻译文件 ├── preproc_rules 预处理器及解码器规则集 │ ├── decoder.rules │ ├── preprocessor.rules │ └── sensitive-data.rules ├── rules Snort规则集(关键) │ ├── web-iis.rules │ ├── web-php.rules More… ├── so_rules Share Object规则集 │ ├── browser-ie.rules │ ├── browser-other.rules More…
0x02 snort.conf配置文件
此文件是配置snort的核心文件,包括以下几部分:
- Set the network variables: 设置各类网络地址,规则中易于使用
- Configure the decoder: 设置解码器
- Configure the base detection engine: 设置基础检测引擎
- Configure dynamic loaded libraries: 设置动态链接库
- Configure preprocessors: 设置预处理器
- Configure output plugins: 设置输出插件
- Customize your rule set: 设置自定义规则
- Customize preprocessor and decoder rule set: 设置预处理、解码器规则
- Customize shared object rule set: 设置共享对象规则集
0x03 SNORT体系结构
- 数据包嗅探模块,主要负责监听网络数据包,并根据 TCP/IP 协议解析数据包。
- 预处理模块
- 包重组预处理器,它的作用是为了防止攻击信息被拆分到多个包中而 逃避了 Snort 的检测;
- 协议编码预处理器,它的功能是把数据包协议解码成一个统一的格式,再传送给检测模块;
- 协议异常检测预处器。
- 检测引擎模块,当预处理器把数据包送过来后,检测引擎将这些数据包与三维链表形式的检测规则进行匹配,一旦发现数据包中的内容和某条规则相匹配,就通知报警模块。
- 报警/日志模块,检测引擎将数据包传送给报警模块后,报警模块会根据规则定义(alert,log..)对其进行不同的处理(数据库,日志)。
下面分别详细介绍这四大模块。
0x04 解码模块与预处理模块
4.1 模块介绍
由于解码模块和预处理模块功能类似,都是在规则检测引擎之前对数据包的处理,所以两个模块一并介绍。 解码模块主要是将从监控网络当中抓取的原始网络数据包,按照各个网络协议栈从下至上进行解码,并将解码数据保存到各个对应的数据结构当中,最后交由预处理模块进行处理。
解码后的数据包经过预处理之后才能被主探测引擎进行规则匹配。预处理器的主要用来应对一些 IDS 攻击手段。其作用包括:
- 针对可疑行为检查包或修改包,以便探测引擎能对其正确解释
- 负责对流量标准化,以便探测引擎能精确匹配特征
目前已知的 IDS 逃避技术主要有:
- 多态 URL 编码
- 多态 shellcode
- 会话分割
- IP 碎片
Snort 主要包含以下三类预处理器(举例说明):
- 包重组预处理器:
- frag3:IP 分片重组和攻击监测
- stream:维持 TCP 流状态,进行会话重组
- 协议规范化预处理器:
- http_inspect:规范 HTTP 流
- rpcDecode:规范 RPC 调用
- 异常检测预处理器:
- ARP spoof:检测 ARP 欺骗
- sfPortscan:检测端口扫描
4.2 模块配置
配置分两个步骤,都是在snort.conf
中配置。
snort.conf
的 2 和 5 中配置解码器或者预处理参数。snort.conf
的 8 中启用检测规则。
4.2.1 解码器配置举例
- 配置解码器
config disable_decode_alerts 关闭decode告警。 config enable_decode_oversized_alerts 如果一个包(IP,UDP,TCP)长度长于 length 字段,则告警。 # Stop generic decode events
格式为
config docoder [option]
,使用#
作为注释 - 启用解码器检测规则
include $PREPROC_RULE_PATH/decoder.rules
snort.conf
文件中使用include
关键词包含配置文件和规则文件。 - 在
decoder.rules
中我们找到了检测IP长度异常的规则
alert ( msg:"DECODE_IPV4_DGRAM_GT_IPHDR"; sid:6; gid:116; rev:1; metadata:rule-type decode;classtype:protocol-command-decode; )
4.2.2 预处理器http_insepect配置举例
- 下面是 http_inspect 默认的配置
preprocessor http_inspect: global iis_unicode_map unicode.map 1252 compress_depth 65535 decompress_depth 65535 #unicode.map是http_inspect解码unicode时的解码文件。 preprocessor http_inspect_server: server default \ http_methods { GET POST PUT SEARCH MKCOL ...} \ ... enable_cookie #将http请求或响应中的cookie提取到缓存,用于后面规则匹配。 normalize javascript #对标签中的js脚本解码。 ...
- 启用预处理器规则
#include $PREPROC_RULE_PATH/preprocessor.rules
下面是一条解码器规则:
alert ( msg:"DECODE_TCP_INVALID_OFFSET"; sid:46; gid:116; rev:1; metadata:rule-type decode; reference:cve,2004-0816; classtype:bad-unknown; )
发现这条规则和之前看到的不一样,它没有源/目的IP,端口等信息,说明这条规则是由解码器自动触发的,用户不需要干预。 一般我们也不需要去修改解码器或者预处理器的规则,只需要去snort.conf
中添加、配置或者删除插件即可
0x05检测引擎模块
规则结构 alert tcp 202.110.8.1 any -> 122.111.90.8 80 (msg:”Web Access”; sid:1) |---||---||---||---||---||---||---||---||---||--规则头---||---||---||---||---||---||---||---||--||---||---||---||-规则选项---||---||---||---||-|
5.1 规则头
动作
在 snort 中有五种动作:alert、log、pass、activate和dynamic.
- Alert: 生成一个告警,然后记录(log)这个包。
- Log: 记录这个包。
- Pass: 丢弃这个包。
- Activate: alert并且激活另一条dynamic规则。
- Dynamic:保持空闲直到被一条activate规则激活,被激活后就作为一条log规则执行。
协议
Snort 当前可分析的协议有四种:TCP,UDP,ICMP 和 IP。将来可能会更多,例如:ARP、IGRP、GRE、OSPF、RIP、IPX 等。
IP地址
- 地址就是由直接的 ip 地址或一个 CIDR 块组成的。也可以指定 ip 地址列表,一个 ip 地址列表由逗号分割的 ip 地址和 CIDR 块组成,并且要放在方括号内
[,]
- 否定操作符用
!
表示 - 关键字
any
可以被用来定义任何地址
例如:alert tcp ![192.168.1.0/24,10.1.1.0/16] any -> 192.168.2.1 80(msg:”notice!”;content|xxxx|;)
方向操作符
方向操作符->
表示规则所施加的流的方向。方向操作符左边的 ip 地址和端口号被认为是流来自的源主机,方向操作符右边的 ip 地址和端口信息是目标主机,还有一个双向操作符<>
。
端口号
- 端口号可以用几种方法表示,包括 any 端口、静态端口定义、范围、以及通过否定操作符。
- 静态端口定义表示一个单个端口号,例如 111 表示portmapper,23 表示 telnet,80 表示 http 等等
- 端口范围用范围操作符
:
表示。比如:80:
,:1024
,80:1024
5.2 规则选项
规则选项分为四大类:
- General rule option 通用规则选项
- Payload detection rule option 负载检测规则选项
- Non-Payload detection rule option 非负载检测规则选项
- Post detection rule option 后检测规则选项
5.2.1 General rule option通用规则选项
sid
snort id,这个关键字被用来识别 Snort 规则的唯一性(说的其实严禁,后面会有补充)。sid
的范围是如下分配的:
<100
保留做将来使用100-1000000
包含在snort发布包中>1000000
作为本地规则使用
msg
标示一个消息,但是规则中的msg
不起作用,sid
和msg
的对应关系查阅sid-msg.map
。
sid-msg.map
格式:sid || msg
例子:384 || PROTOCOL-ICMP PING
在/etc/snort/rules/protocol-icmp.ruls
中我们找到了这条规则:alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"PROTOCOL-ICMP PING"; icode:0; itype:8; metadata:ruleset community; classtype:misc-activity; sid:384; rev:8;)
此文件作用是将sid
与msg
的一一对应,否则,在告警中会出现下图中第一条的现象。
此文件用于自定义规则中sid
与msg
的对应和在 Snort 自有规则中自定义告警信息。 上图中Snort Alert[1:1000015:0]
其中内容对应为Snort alert[gid:sid:rev]
。这说明一个规则需要这三个因素才能确定,之前说只有sid
唯一标示一条规则是不严谨的。
gid
generate id,作用是为了说明这条规则是 Snort 的哪部分触发的。比如是由解码器、预处理器还是 Snort 自有规则等。
查看/usr/local/share/doc/snort/generators
文件(此文件不是配置文件):
rules_subsystem 1 # Snort Rules Engine rpc_decode 106 # RPC Preprocessor(预处理器) stream4 111 # Stream4 preprocessor(预处理器) ftp 125 # FTP decoder(解码器) ... ...
decoder 和 preprocessor 的gid
就不一一列举,可以看到 Snort Rule Engine 的gid
为 1,自定义规则和 Snort 自有规则(也就是/etc/snort/rules
目录下的规则)gid
默认是 1。但是这里我们获知 decoder 和 preprocessor 也是有sid
的。
举例说明:
/etc/snort/rules/protocol-icmp.rules
中的一条规则:alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:“PROTOCOL-ICMP Traceroute”; icode:0; itype:30; metadata:ruleset community; classtype:misc-activity; sid:456; rev:8;)
gid
默认为 1
/etc/snort/preproc_rules/decoder.rules
中的一条规则:alert ( msg:"DECODE_IP6_EXCESS_EXT_HDR"; sid:456; gid:116; rev:1; metadata:rule-type decode; classtype:misc-activity; )
可以看到两条规则的sid
是相同的,所以还需要gid
来区分。
gen-msg.map
这个文件和sid-msg.map
作用类似,在逻辑上应该是包含了sid-msg.map
(sid-msg.map
相当于默认gid
为 1)
格式:generatorid || alertid(sid) || MSG
例子:
1 || 1 || snort general alert 129 || 2 || stream5: Data on SYN packet 116 || 271 || snort_decoder: WARNING: IPv6 header claims to not be IPv6 116 || 456 || snort_decoder: WARNING: too many IPV6 extension headers #例子 ...
拿gid
中第二条规则举例,如果此条规则被触发,则会报snort_decoder: WARNING: too many IPV6 extension headers
告警,而不是DECODE_IP6_EXCESS_EXT_HDR
。所以规则中的 msg 仅仅起到标示作用,告警 msg 需要在sid-msg.map
和gen-msg.map
这两个文件中对应查找
rev
这个关键字是被用来识别规则修改的版本,需要和sid
,gid
配合使用。 这样就介绍完了gid
,sid
,rev
三个确定规则唯一的元素。
reference
外部攻击参考,这个关键字允许规则包含一个外面的攻击识别系统。这个插件目前支持几种特定的系统,这些插件被输出插件用来提供一个关于产生报警的额外信息的连接。
reference.config
格式:config reference: system URL
例子:config reference: cve http://cve.mitre.org/cgi-bin/cvename.cgi?name=
定义了一些外部安全网站的网址。比如规则中定义reference: cve,1001
,那么就像在上面的网址后面添加了 1001,http://cve.mitre.org/cgi-bin/cvename.cgi?name=1001
,最后点击告警中的[cve]
,就会跳转到相应的网址。注:reference
也需要在sid-msg.map
中与sid
对应,否则不起作用,类比msg
。
classtype
规则类别标识。这个关键字把报警分成不同的攻击类。通过使用这个关键字和使用优先级,用户可以指定规则类中每个类型所具有的优先级。
priority
设置classtype
的优先级。classtype
和priority
是配合使用的,classification.config
文件将其联系起来。
classification.config
格式:config classification:shortname,short description,priority
例子:config classification: attempted-admin,Attempted Administrator Privilege Gain,1
写在此文件中的都是默认值,
priority
关键词可以在规则中重写优先级。
例子:alert tcp any any -> any 80 (msg:"EXPLOIT ntpdx overflow"; dsize:>128; classtype:attempted-admin; priority:10 );
metadata
可以在规则中添加自定义的信息,一般以键值对的形式出现。
通用规则选项只是对一条规则进行标示,分类等操作,并没有进行实际的过滤检测。
5.2.2 Payload Detection Rule Options 负载检测规则选项
content
content
是 Snort 重要的关键词之一。它规定在数据包的负载中搜索指定的样式。它的选项数据可以包含混合的文本和二进制数据。二进制数据一般包含在管道符号中|
,表示为字节码(bytecode),也就是将二进制数据的十六进制形式。
alert tcp any any -> any 139 (content:"|5c 00|P|00|I|00|P|00|E|00 5c|";)
alert tcp any any -> any 80 (content:!“GET”;)
content
还有很多修饰符:
修饰符 | 解释 |
---|---|
Nocase | content字符串大小写不敏感 |
rawbytes | 直接匹配原始数据包 |
Depth | 匹配的深度 |
Offset | 开始匹配的偏移量 |
Distance | 两次content匹配的间距 |
Within | 两次content匹配之间至多的间距 |
http_cookie | 匹配cookie |
http_raw_cookie | 匹配未经normalize的cookie |
http_header | 匹配header |
http_raw_header | 匹配未经normalize的header |
http_method | 匹配method |
http_url | 匹配url |
http_raw_url | 匹配日在未经normalize的url中 |
http_stat_code | 匹配状态码中匹配 |
http_stat_msg | 匹配状态信息 |
http_encode | 匹配编码格式 |
http 开头的修饰符需要配合前面介绍过的预处理器 http_inspect 一起使用。
pcre
允许用户使用与PERL语言相兼容的正则表达式。
格式 pcre:[!]"(/<regex>/|m<delim><regex><delim>)[ismxAEGRUBPHMCOIDKY]
例子:alert tcp any any -> any 80 (content:“/foo.php?id="; pcre:"/\/foo.php?id=[0-9]{1,10}/iU";)
正则的细节查阅 snort_manual。
protected_content
将content
中的查询内容使用 hash 算法加密,保护规则的私密性。protected_content:[!]"<content hash>", length:orig_len[, hash:md5|sha256|sha512];
rawbytes
忽略解码器及预处理器的操作,直接匹配原始网络包。
上面只列举出了一些常用的 payload detection rule option,更多的关键词查阅 snort_manual。
5.2.3 Non-Payload Detection Rule Option非负载检测规则选项
此类规则选项都是对数据包帧结构中特殊字段的匹配。
选项 | 解释 |
---|---|
Fragoffset | IP 偏移量 |
Ttl | IP 生存时间 |
Tos | IP 服务类型 |
Id | IP 标识 |
Ipopts | IP 可选项 |
Fragbits | IP 标志 |
Dsize | 数据包负载量 |
Flags | TCP flags |
Seq | TCP seq |
Ack | TCP ack |
Window | TCP window |
Icmp_id | ICMP ID |
5.2.4 Post-Detection Rule Option后检测规则选项
选项 | 解释 |
---|---|
Logto | 输出日志路径 |
Session | 从TCP会话中获取用户数据 |
Resp | 通过发送响应结束恶意的请求 |
React | 不仅仅记录触发规则的特定数据包 |
Tag | 不仅仅记录触发规则的特定数据包 |
Activates | activate动作 |
Activates_by | dynamic动作 |
Count | dynamic规则被触发后可以匹配的包的数目 |
Replace | 替换content内容 |
Detection-filter | 检测过滤 |
5.3 检测引擎模块配置
- 在
/etc/rules
目录下的*.rules
文件中写规则 snort.conf
7 中include
对应规则。
include $RULE_PATH/local.rules #include $RULE_PATH/app-detect.rules #include $RULE_PATH/attack-responses.rules #include $RULE_PATH/backdoor.rules #include $RULE_PATH/bad-traffic.rules #include $RULE_PATH/blacklist.rules
0x06 Snort告警/日志模块
6.1 输出模块配置
snort.conf
设置日志路径:config logdir:/var/log/snort
设置输出格式为unified2:output unified2: filename snort.log, limit 128
barnyard2.conf
barnyard2 的作用是将 unified2 格式的数据存入数据库
设置与 Snort 日志关联config waldo_file:/var/log/snort/barnyard.waldo
设置数据库output database: log, mysql, user=snort password=123456 dbname=snort host=localhost
6.2 数据库
scheme
信息表,和其他数据库内容上没有联系
字段名 | 解释 |
---|---|
vseq |
数据库模式ID |
ctime |
数据库创建时间 |
sensor
字段名 | 解释 |
---|---|
sid |
传感器代号 |
hostname |
传感器所属的用户名称 |
Interface |
传感器对应的网络接口 |
filter |
对应传感器的过滤原则 |
detail |
表示传感器监测模式,记录模式详细程度的级别 |
encoding |
包含数据存在形式 |
last_cid |
对应每个 sid 即传感器捕获告警的最后一个值 |
detail
传感器sensor的检测级别
- 0: fast快速检测
- 1: full全面检测
encoding
数据包中数据的存在形式
- 0: Hex
- 1: base64
- 2: ascii
event
最核心的一张表,告警的每一条数据都会存储在 event 表中,一条 event 数据就代表一个包
字段名 | 解释 |
---|---|
sid |
sensor id,传感器id |
cid |
event id,事件 id。sid 和 cid 共同作为主码,其中 cid 是在 sid 的基础上进行排序的。每个 sid 对应自己的 cid 排序 |
signature |
对应 signature 表格中的 sig_id 选项,表明这条告警事件所属的规则形式的告警对应哪一类 rules |
timestamp |
对应告警事件发生的系统时间 |
signature
存储 Snort 规则的一张表,可以看到sig_sid
,sig_gid
,sig_rev
分别对应规则中的sid
,gid
,rev
。注意规则中的snort id
和数据库中的sensor id
注意区分。
字段名 | 解释 |
---|---|
sig_id |
总数代表发生告警种类的总数。是告警种类的主码。唯一标识一条规则 |
sig_name |
告警名称。对应每条 alert 语句的 Msg |
sig_class_id |
对应 sig_class 表格中的 sig_class_id。代表告警种类的大类信息 |
sig_priority |
告警的优先级 |
sig_rev |
版本号 |
sig_sid |
snort id |
sig_gid |
generate id |
sig_reference
提供报警种类信息signature
的参考信息。将signature
与reference
联系起来的表格。
字段名 | 解释 |
---|---|
sig_id |
对应的告警种类 |
ref_id |
对应 reference 表格中的主码 |
ref_seq |
参考序列号 |
reference
字段名 | 解释 |
---|---|
Ref_id |
主码 |
Ref_system_id |
对应 reference_system 表格 |
Ref_tag |
规则中 cve,bugtraq 后面的参数 |
reference_system
字段名 | 解释 |
---|---|
ref_system_id |
主码 |
ref_system_name |
reference system 的名字,如 cve,url 等 |
sig_class
signature告警种类的分类信息。
字段名 | 解释 |
---|---|
sig_class_id |
分类编号 |
sig_class_name |
分类名称 |
iphdr
tcphdr
udphdr
data
data_payload
是数据包有效载荷
- 规则中协议为 tcp 时,data_payload 中是 tcp 后面的内容
- 规则中协议为 icmp 时,data_payload 中是 icmp 协议中的 data 字段值
opt
IP 和 OPT 的 option。
参考文献
- CentOS6.6下基于snort+barnyard2+base的入侵检测系统的搭建
- 基于Snort的C_S模式的IDS的设计与应用_王会霞.caj
- Snort 笔记1 - 3种模式简介
- Snort.conf 分析
- Snort 入侵检测系统简介
- Snort部署及端口扫描检测试验总结
- Barnyard create_mysql
- Snort mysql概述
- Snort响应模块总结-实时监听-数据库分析
- Snort数据表项含义及ER图
- 上文的中文翻译
- Snort rules概述
- Snort安装配置与NIDS规则编写
- Snort 笔记2 - 规则编写
- 撰写一组SNORT规则防御SQL注入
- Snort规则中的逻辑关系
- Snort_manual.pdf 官方文档中文翻译
- Snort sid-msg.map文件概述
- Snort classification.config文件概述
- Snort reference.config文件概述