转载自 《snort 笔记2 ----- 规则编写》
为了看懂rules,可以看下文,想要写好,就没那么简单了。^-^。
**************************************************************************************************************************
I 总体结构分析:
alert tcp any any -> 192.168.1.0/24 111 (content:"|00 01 86 a5|"; msg: "mountd access";)
分析:
- 多行之间用 / 分开
- 规则包括:规则头rule header: alert tcp any any -> 192.168.1.0/24 111 和规则选项 rule options:(content:"|00 01 86 a5|"; msg: "mountd access";)
II 规则头:3个要素: who , where, what,how(行动)
- 2.1 规则动作 rule action。告诉snort一旦匹配干什么事,原来的snort共5种:alert, log,pass,activate,dynamic
(alert:警报并且记录; log:记录; pass::丢弃(忽略); activate:报警并且激活另外一条dynamic规则;dynamic:被激活后log,也可自己自定义,参考manual)
******************************************
以下是2.9版本的mannal中新添加的action:
1. alert - generate an alert using the selected alert method, and then log the packet
2. log - log the packet
3. pass - ignore the packet
4. activate - alert and then turn on another dynamic rule
5. dynamic - remain idle until activated by an activate rule , then act as a log rule
6. drop - block and log the packet
7. reject - block the packet, log it, and then send a TCP reset if the protocol is TCP or an ICMP port unreachable
message if the protocol is UDP.
8. sdrop - block the packet but do not log it.
******************************************
- 2.2 协议。snort当前可分析的协议包有:tcp,udp,ip,icmp。
- 2.3 ip地址。ip地址可以用any定义任何地址,并且需要添加掩码(16-B类,24-C类,32-特定的机器),并且可以使用!操作符。如果ip地址是个列表,需要[192.168.1.0/24,10.1.1.0/24]类似,使用[],中间用逗号隔开,如果要加!,要加到[]外部。
- 2.4 端口号。any表示全部,如果表示范围,eg:1:1024,中间用冒号隔开。但是:200也可,表示小于等于200的,反之:1024:表示大于等于1024的。当然也可以类似ip地址使用!否定操作符。
- 2.5 方向操作符。规则所施加的流的方向. 单向,从源到目的 ->; 双向,既是源又是目标<>.
III 规则选项:nids的核心,所有选项用“;”隔开,规则选项关键字和他们的参数用“:”分开,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_seq - 检查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 - 数字模式测试和偏移量调整
*****************************************
在2.9的mannal中把它们分为了4类:
*******************************************
general :These options provide information about the rule but do not have any affect during detection
对检测无影响
payload :These options all look for data inside the packet payload and can be inter-related
需要深入到包中的数据。
non-payload: These options look for non-payload data
不需要包数据。
post-detection :These options are rule specific triggers that happen after a rule has “fired.”
触发器,只有当一个规则触发后才发生。
*******************************************
在对各种分类介绍之前,我观察了rules下面的系统原有的rules,发现在规则选项中如下几项用的十分多:(尤其是前8项)
1 msg:
2 content
3 nocase
4 flow
5 reference
6 classtype
7 sid
8 rev
9 icmp_id
10 icmp_seq
11 itype
12 offset
13 depth
给出几个常见的eg:(从snort发布的rule中摘录)
***********************************
1 alert icmp $EXTERNAL_NET any -> $HOME_NET any (msg:"ICMP PING NMAP"; dsize:0; itype:8; reference:arachnids,162; classtype:attempted-recon; sid:469; rev:3;
2 # These rules look for specific Agobot/PhatBot commands on an IRC session
alert tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"COMMUNITY BOT Agobot/PhatBot bot.about command"; flow: established; flowbits:isset,community_is_proto_irc; content:"bot.about"; classtype: trojan-activity; sid:100000242; rev:2;
***********************************
下面把以上常用的进行分类着重介绍(这个分类是2.9版manual中分类,这样能更清晰地给出规则选型的使用环境)
A : general有那些:
1 msg: alert和log的同时,同时print的东西
2 reference: 允许规则包含外面的攻击系统: arachnids(一个攻击特征数据库),cve(这个不用说了吧),bugtraq(一个完整的对计算机安全漏洞(它们是什么,如何利用它们,以及如何修补它们)的公告及详细论述进行适度披露的邮件列表)等.
3 sid:规则的唯一序列 (<100保留,100~999999为snrot发布用,>=1000,000本地用),允许输出插件容易识别规则的ID好,常和rev一起使用。rev:用来标记规则修改,按照我的理解,就是当前规则改了一次,rev就记录这个次数。
4 classtype:这个选项把alert分为不同的攻击类。通过使用这个关键字和优先级,用户可以指定每个类型需要的优先级。比如上文的classtype为trojan-activity就属于high类别。
总体描述:
**********************************
msg
The msg keyword tells the logging and alerting engine the message to print with
the packet dump or alert.
reference
The reference keyword allows rules to include references to external attack identification
systems.
gid
The gid keyword (generator id) is used to identify what part of Snort generates the
event when a particular rule fires.
sid
The sid keyword is used to uniquely identify Snort rules.
rev
The rev keyword is used to uniquely identify revisions of Snort rules.
classtype
The classtype keyword is used to categorize a rule as detecting an attack that is
part of a more general type of attack class.
priority
The priority keyword assigns a severity level to rules.
metadata
The metadata keyword allows a rule writer to embed additional information about
the rule, typically in a key-value format.
**********************************
B:payload类型
1 content:最重要的rule option之一。它允许用户设置规则在包的净荷中搜索指定的内容并根据内容触发响应。当进行content选项模式匹配时, Boyer-Moore模式匹配函数被调用,并且对包的内容进行检查(很花费计算能力)。如果包的净荷中包含的数据确切地匹配了参数的内容,这个检查成功并且该规则选项的其他部分被执行。注意这个检查是大小写敏感的。
Content关键字的选项数据比较复杂;它可以包含混合的文本和二进制数据。二进制数据一般包含在管道符号中("|"),表示为字节码 (bytecode)。字节码把二进制数据表示为16进制数字,是描述复杂二进制数据的好方法。下面是包含了一个混合数据的snort规则范例
eg: 1) content:"/bin/sh";
2)content:"|90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90|";
3) content:"name=|22 CC CC CC CC CC|"; 来自web-php.rules.
2 nocase: 用于取消content中的大小写敏感
3 depth:depth也是一个content规则选项修饰符。它设置了内容模式匹配函数从他搜索的区域的起始位置搜索的最大深度。它对于限制模式匹配函数超出 搜索区域指定范围而造成无效搜索很有用。(也就是说,如果你在一个web包中搜索"cgi-bin/phf",你可能不需要浪费时间搜索超过净荷的头20 个字节)。eg: content:"NICK "; nocase; offset: 0; depth: 5; (来自community-bot.rules)
4 offset: offset规则选项被用作使用content规则选项关键字的规则的修饰符。这个关键字修饰符指定模式匹配函数从包净荷开始处开始搜索的偏移量。 它对于cgi扫描检测规则很有用,cgi扫描的内容搜索字符串不会在净荷的前4个字节中出现。小心不要把这个偏移量设置的太严格了,会有可能漏掉攻击!这 个规则选项关键字必须和content规则选项一起使用。
其它的payload类型的规则选项:
**********************************
part1: content及其修饰符
Modifier Section
nocase 3.5.2
rawbytes 3.5.3
depth 3.5.4
offset 3.5.5
http_client_body 3.5.8
http_cookie 3.5.9
http_raw cookie 3.5.10
http_header 3.5.11
http_raw_header 3.5.12
http_method 3.5.13
http_uri 3.5.14
http_raw uri 3.5.15
http_stat code 3.5.16
http_stat msg 3.5.17
fast_pattern 3.5.19
distance
The distance keyword allows the rule writer to specify how far into a packet Snort should ignore before
starting to search for the specified pattern relative to the end of the previous pattern match.
within
The within keyword is a content modifier that makes sure that at most N bytes are between pattern
matches using the content keyword.
part2: 其它的:
uricontent
The uricontent keyword in the Snort rule language searches the normalized request URI field.
isdataat
The isdataat keyword verifies that the payload has data at a specified location.
pcre
The pcre keyword allows rules to be written using perl compatible regular expressions.
byte_test
The byte test keyword tests a byte field against a specific value (with operator).
byte_jump
The byte jump keyword allows rules to read the length of a portion of data, then skip that far forward
in the packet.
ftpbounce
The ftpbounce keyword detects FTP bounce attacks.
asn1
The asn1 detection plugin decodes a packet or a portion of a packet, and looks for various malicious
encodings.
cvs
The cvs keyword detects invalid entry strings.
dce_iface
See the DCE/RPC 2 Preprocessor section 2.2.13.
dce_opnum
See the DCE/RPC 2 Preprocessor section 2.2.13.
dce_stub_data
See the DCE/RPC 2 Preprocessor section 2.2.13.
**********************************
C: non-payload类型:
1 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 不在重建的流数据包上触发(对dsize 和 stream4 有用。
only_stream 只在重建的流数据包上触发。
格式:
flow:[to_client|to_server|from_client|from_server|established|stateless|no_stream|only_stream]}
例子:
alert tcp !$HOME_NET any -> $HOME_NET 21 (flow: from_client; content: "CWD incoming"; nocase; msg: "cd incoming detected"; )
alert tcp !$HOME_NET 0 -> $HOME_NET 0 (msg: "Port 0 TCP traffic"; flow: stateless;)
2 Icmp_id
Icmp_id选项检查ICMP ECHO数据包中ICMP ID数值是否是指定值。许多秘密通道(covert channel)程序使用静态ICMP字段通讯,所以该选项在检查这种流量时非常有用。这个特别的插件用于增强由Max Vision编写的stacheldraht探测规则,但是在探测一些潜在攻击时确实有效。
3 Icmp_seq
Icmp_seq选项检查ICMP ECHO数据包中ICMP sequence字段数值是否是指定值。许多秘密通道(covert channel)程序使用静态ICMP字段通讯,所以该选项在检查这种流量时非常有用。这个特别的插件用于增强由Max Vision编写的stacheldraht探测规则,但是在探测一些潜在攻击时确实有效。(我知道该字段的信息和icmp_id的描述几乎完全相同,实际上它们就是同样的东西!)
其它:
*************************************
fragoffset
The fragoffset keyword allows one to compare the IP fragment offset field against a decimal value.
ttl
The ttl keyword is used to check the IP time-to-live value.
tos
The tos keyword is used to check the IP TOS field for a specific value.
id
The id keyword is used to check the IP ID field for a specific value.
ipopts
The ipopts keyword is used to check if a specific IP option is present.
fragbits
The fragbits keyword is used to check if fragmentation and reserved bits are set in the IP header.
dsize The dsize keyword is used to test the packet payload size.
flags
The flags keyword is used to check if specific TCP flag bits are present.
flow
The flow keyword allows rules to only apply to certain directions of the traffic flow.
flowbits
The flowbits keyword allows rules to track states during a transport protocol session.
seq
The seq keyword is used to check for a specific TCP sequence number.
ack
The ack keyword is used to check for a specific TCP acknowledge number.
window
The window keyword is used to check for a specific TCP window size.
itype
The itype keyword is used to check for a specific ICMP type value.
icode
The icode keyword is used to check for a specific ICMP code value.
icmp_id
The icmp id keyword is used to check for a specific ICMP ID value.
icmp_seq
The icmp seq keyword is used to check for a specific ICMP sequence value.
rpc
The rpc keyword is used to check for a RPC application, version, and procedure numbers in SUNRPC
CALL requests.
ip_proto
The ip_proto keyword allows checks against the IP protocol header.
sameip
The sameip keyword allows rules to check if the source ip is the same as the destination IP.
*****************************************
D: post-Detection 规则选项:
logto
The logto keyword tells Snort to log all packets that trigger this rule to a special output log file.
session
The session keyword is built to extract user data from TCP Sessions.
resp
The resp keyword is used attempt to close sessions when an alert is triggered.
react
This keyword implements an ability for users to react to traffic that matches a Snort rule by closing
connection and sending a notice.
tag
The tag keyword allow rules to log more than just the single packet that triggered the rule.
activates
This keyword allows the rule writer to specify a rule to add when a specific network event occurs.
activated_by
This keyword allows the rule writer to dynamically enable a rule when a specific activate rule is
triggered.
count
This keyword must be used in combination with the activated by keyword. It allows the rule writer
to specify how many packets to leave the rule enabled for after it is activated.
replace Replace the prior matching content with the given string of the same length. Available in inline mode
only.
detection filter Track by source or destination IP address and if the rule otherwise matches more than the configured rete it will fire.
IV 规则临界值:不被推荐,在以后的版本中被替代。
Rule thresholds are deprecated and will not be supported in a future release. Use detection filters (3.7.10) within rules, or
event filters (2.4.2) as standalone configurations instead.
eg:
alert tcp $external_net any -> $http_servers $http_ports /
(msg:"web-misc robots.txt access"; flow:to_server, established; /
uricontent:"/robots.txt"; nocase; reference:nessus,10302; /
classtype:web-application-activity; threshold:type limit, track /
by_src, count 1 , seconds 60; sid:1000852; rev:1;)
******************
type limit|threshold|both
type limit alerts on the 1st m events during the time interval, then ignores events
for the rest of the time interval. Type threshold alerts every m times we see
this event during the time interval. Type both alerts once per time interval after
seeing m occurrences of the event, then ignores any additional events during the
time interval.
track by src|by dst
rate is tracked either by source IP address, or destination IP address. This means
count is maintained for each unique source IP addresses, or for each unique destination
IP addresses. Ports or anything else are not tracked.
count c
number of rule matching in s seconds that will cause event filter limit to be
exceeded. c must be nonzero value.
seconds s
time period over which count is accrued. s must be nonzero value.
************************
V: 如何写出好的规则(来自manual2.9)
1 Content_matching :
如果可能,至少在你的规则中包含一次Content
If at all possible, try and have at least one content (or uricontent)
rule option in your rule.
2 Catch the Vulnerability, Not the Exploit
针对漏洞本身写rule,而不是利用代码
Try to write rules that target the vulnerability, instead of a specific exploit.
For example, look for a the vulnerable command with an argument that is too large, instead of shellcode that binds a shell.
By writing rules for the vulnerability, the rule is less vulnerable to evasion when an attacker changes the exploit slightly.
3 Catch the Oddities of the Protocol in the Rule
抓住协议中奇特的部分
以FTP协议为例:
Many services typically send the commands in upper case letters. FTP is a good example. In FTP, to send the username, the client sends:
user username_here
A simple rule to look for FTP root login attempts could be:
alert tcp any any -> any any 21 (content:"user root";)
4 Optimizing Rules 优化规则(摘自2.9 manual)
The content matching portion of the detection engine has recursion to handle a few evasion cases. Rules that are not properly written can cause Snort to waste time duplicating checks.
The way the recursion works now is if a pattern matches, and if any of the detection options after that pattern fail, then look for the pattern again after where it was found the previous time. Repeat until the pattern is not found again or the opt functions all succeed.
On first read, that may not sound like a smart idea, but it is needed. For example, take the following rule:
alert ip any any -> any any (content:"a"; content:"b"; within:1;) (逻辑关系不对,影响判断)
This rule would look for “a”, immediately followed by “b”. Without recursion, the payload “aab” would fail, even though it is obvious that the
payload “aab” has “a” immediately followed by “b”, because the first ”a” is not immediately followed by “b”.
While recursion is important for detection, the recursion implementation is not very smart.
For example, the following rule options are not optimized:
content:"|13|"; dsize:1; (位置先后很重要)
By looking at this rule snippit, it is obvious the rule looks for a packet with a single byte of 0x13. However, because of recursion, a packet with
1024 bytes of 0x13 could cause 1023 too many pattern match attempts and 1023 too many dsize checks. Why? The content 0x13 would be found
in the first byte, then the dsize option would fail, and because of recursion, the content 0x13 would be found again starting after where the previous
0x13 was found, once it is found, then check the dsize again, repeating until 0x13 is not found in the payload again.
Reordering the rule options so that discrete checks (such as dsize) are moved to the beginning of the rule speed up Snort.
The optimized rule snipping would be:
dsize:1; content:"|13|";
A packet of 1024 bytes of 0x13 would fail immediately, as the dsize check is the first option checked and dsize is a discrete check without recursion.
The following rule options are discrete and should generally be placed at the beginning of any rule:(下列rule option是离散的,应该放在任何rule的前面)
• dsize
• flags
• flow
• fragbits
• icmp id
• icmp seq
• icode
• id
• ipopts
• ip proto
• itype
• seq
• session
• tos
• ttl
• ack
• window
• resp
• sameip
5 Testing Numerical Values
snort manual 2.9 180-182页,很好的一个解决方案。