基于Snort的***检测系统 3

发布时间:2019-09-03 08:57:58编辑:auto阅读(2252)

    三章使用Snort规则
    如同病毒,大多数***行为都具有某种特征,Snort的规则就是用这些特征的有关信息构建的。在第1章中我们提到,你可以用蜜罐来取得***者所用的工具和技术的信息,以及他们都做了什么。此外,还有***者会利用的已知的系统弱点数据库,如果***者试图利用这些弱点来实施***,也可以作为一些特征。这些特征可能出现在包的头部,也可能在数据载荷中。Snort的检测系统是基于规则的,而规则是基于***特征的。Snort规则可以用来检测数据包的不同部分。Snort 1.x可以分析第3层和第4层的信息,但是不能分析应用层协议。Snort v 2.x增加了对应用层头部分析的支持。所有的数据包根据类型的不同按顺序与规则比对。
    规则可以用来产生告警信息、记录日志,或使包通过(pass):对Snort来说,也就是悄悄丢弃(drop),通过在这里的意义与防火墙或路由器上的意义是不同的,在防火墙和路由其中,通过和丢弃是两个相反的概念。Snort规则用简明易懂的语法书写,大多数规则写在一个单行中。当然你也可以行末用反斜线将一条规则划分为多个行。规则文件通常放在配置文件snort.conf文件中,你也可以用其他规则文件,然后用主配置文件引用它们。
    本章将提供给你不同类型规则的信息以及规则的基本结构。在本章的最后,你可以找到一些用来检测***活动的规则的例子。读完本章以及后面两章后,你所获得的信息就可以使你建立一个基本的Snort***检测系统了。
    3.1 TCP/IP 网络分层
    在你开始书写规则之前,我们先来简要讨论一下TCP/IP的网络层次结构nort规则是常重要的,因为Snort规则依赖于这些层中的协议。
    TCP/IP协议族分为5层,这些层之间相互作用来完成通讯处理工作,它们是:
    1、物理层
    2、数据链路层,某些文章中也把它们叫做网络接口层。物理层和数据链路层由物理介质、网络接口适配器和网络适配器驱动所构成。以太网地址在数据链路层定义。
    3、网络层,也就是IP层。这一层负责点到点的数据通信并提供数据完整性。在这一层,所有的主机以IP地址来区分彼此。除了IP协议之外,这一层的主要协议还有ICMP。关于IP协议的更多信息参见RFC791,关于ICMP协议的更多信息查看RFC792。
    4、传输层,也就是TCP/UDP层。TCP(传输控制协议)用来建立从源到目的的可靠的、面向连接的数据传输。而UDP(用户数据报协议)提供无连接的数据传输,UDP在进行数据传输的时候,并不提供数据送达的保证,常用在可以容忍数据丢失的情况下。参见RFC 768获取UDP的更多信息。参见RFC 793来获得更多的关于TCP的信息。
    5、应用层,包含提供用户与网络接口的应用程序,例如Telnet、Web浏览器、ftp客户端等。这些应用程序常有自己用来进行数据通信的应用层协议。
    Snort规则可以在网络层和传输层进行操作,另外也有一些方法来探测数据链路层和应用层的异常。Snort规则的第二个部分显示了对应的协议,你很快将了解如何书写这些规则。
    3.2 第一个不可用的规则
    这里有个非常不好用的规则,事实上,也许是最差的规则,但是它可以很好的检测Snort是否正常工作,并可以产生告警:
    alert ip any any -> any any (msg: "IP Packet detected";)
    你可以在你第一次安装Snort的时候在snort.conf的末尾加上这条规则,这个规则可以使每当捕获一个IP包都产生告警信息,如果你就这样离开的话,你的硬盘空间很快就会被填满。这个规则之所以不可用,是因为它不信任任何信息。难道你用一个永久规则的目的就是为了检测Snort是否在工作吗?它应该是用来在你安装完Snort后做测试,以确定其工作正常,然后就去掉这条规则。下面的部分你可以了解Snort规则的不同部分,但为完整性起见,下面将简要解释一下刚才的那条规则所用的语句:
    l        “alert”表示如果包与条件匹配,就产生一个告警信息。条件由下面的语句定义。
    l        “ip”表示规则将被用在所有的IP包上。
    l        第一个“any”是对IP包源地址部分的条件定义,表示来自任何一个IP地址的IP包都符合条件,任何IP包都符合本条件。
    l        第二个“any”用来定义端口号,因为端口号与IP层无关,任何IP包都符合条件。
    l        “->”符号表示数据包传送的方向。
    l        第3个“any”用来定义目的地址的条件,any表示这条规则并不关心所有包的目的地址。
    l        第4个“any”用来定义目的端口条件,再说明一次,因为IP层与端口无关。
    l        最后一部分是规则的选项,,并包含一条将被纪录的告警消息。
    下一条规则不想前面那个那么糟糕,它将对所有捕获的ICMP包产生告警。重申一次,这条规则也是来检测Snort是否正常工作的。
    如果你想测试Snort,就发送一个ping(在UNIX机器中,基本上是发送ECHO请求)包。再次重复,它应该是用来在你安装完Snort后做测试,以确定其工作正常,然后就去掉这条规则。以下面的命令为例,你可以向你的网关或其他什么主机发送ICMP包。
    ping 192.168.2.1
    注意,192.168.2.1是与Snort机器在同一网络的网关、路由器或其他机器。你可以在你安装Snort的机器上运行这个命令,这个命令在UNIX和Windows机器上都可以运行。
     
    3.3 CIDR
       RFC 1519定义了无类域间路由或称CIDR。目前有将不同的地址类(比如A和B)做更好的利用的趋势。在CIDR的支持下,你可以用任意长度的掩码,这在基于地址类的网络中是不行的,因为基于类的网络中,掩码的长度是固定的。使用CIDR的时候,网络地址的后面附加上掩码所用的位数,例如192.168.1.0/24表示一个网络的网络地址是192.168.1.0,掩码是24位。24位掩码相当于255.255.255.0。表示一个主机可以用到所有的掩码位,也就是32位。下面的规则表示:只有发送到IP地址为192.168.2.113的主机的ICMP包才会触发告警:
    alert icmp any any -> 192.168.1.113/32 any \
    (msg: "Ping with TTL=100"; ttl:100;)
    3.4 规则的结构
       你已经看到了一些规则,尽管它们不那么好,但在某种意义上还是有用的。现在让我们来看一下Snort规则的结构。所有的Snort规则都可以分为两个逻辑组成部分:规则头部和规则选项。参见图3-1
     
    规则头部 规则选项

    图3-1 Snort 规则的基本结构。
    规则的头部包含规则所做的动作的信息,也包含与包所比对的一些条件。选项部分通常包含一个告警消息以及包的那个部分被用来产生这个消息。一条规则可以用来探测一个或多个类型的***活动,一个好的规则可以来探测多种***特征。
    Snort规则头部的主要结构如图3-2所示:
    动作 协议 地址 端口 方向 地址 端口

    图3-2 Snort规则头部结构
    动作部分表示,当规则与包比对并符合条件是,会采取什么类型的动作。通常的动作时产生告警或记录日志或向其他规则发出请求。你可以来本章的后面了解关于动作的更多信息。
    协议部分用来在一个特定协议的包上应用规则。这是规则所涉及的第一个条件。一些可以用到的协议如:IP,ICMP,UDP等等。
    地址部分定义源或目的地址。地址可以是一个主机,一些主机的地址或者网络地址。你也可以用这些部分将某些地址从网络中排除。后面将详细讨论。注意,在规则中有两个地址段,依赖于方向段决定地址是源或者是目的,例如,方向段的值是“->”那么左边的地址就是源地址,右边的地址是目的地址。
    如果协议是TCP或UDP,端口部分用来确定规则所对应的包的源及目的端口。如果是网络层协议,如IP或ICMP,端口号就没有意义了。
    方向部分用来确定那一边的地址和端口是源,哪一边是目的。
    例如,我们来看一下第2章曾经用到过的这样一个规则,当它探测到TTL为100的ICMP ping包的时候,就会产生告警:
    alert icmp any any -> any any (msg: "Ping with TTL=100"; \
    ttl: 100;)
    括号之前的部分叫做规则头部,括号中的部分叫做规则选项。头部依次包括下面部分:
    l        规则的动作:在这个规则中,动作是alert(告警),就是如果符合下面的条件,就会产生一个告警。记住如果产生告警,默认的情况下是会记录日志的。
    l        协议:在这个规则中,协议是ICMP,也就是说这条规则仅仅对ICMP包有效,如果一个包的协议不是ICMP, Snort探测引擎就不理会这个包以节省CPU时间。协议部分在你对某种协议的包应用Snort规则的时候是非常重要的。
    l        源地址和源端口。在这个例子中,它们都被设置成了any,也就是这条规则将被应用在来自任何地方的ICMP包上,当然,端口号与ICMP是没有什么关系的,仅仅和TCP和UDP有关系。
    l        方向。在这个例子中,方向用->表示从左向右的方向,表示在这个符号的左面部分是源,右面是目的,也表示规则应用在从源到目的的包上。如果是<-,那么就相反。注意,也可以用<>来表示规则将应用在所有方向上。
    l        目的地址和端口。这个例子中,它们也都是“any”,表示规则并不关心它们的目的地址。在这个规则中,由于any的作用,方向段并没有实际的作用,因为它将被应用在所有方向的ICMP包上。
    在括号中的选项部分表示:如果包符合TTL=100的条件就产生一条包含文字:“Ping with TTL=100”的告警。TTL是IP包头部字段。参见RFC 791或者附录C。
    3.5规则头部
       如前面提到的,规则的头部包括括号前面的一些部分,现在让我们从动作开始来详细的看一下规则头部的每个部分。
    3.5.1规则动作
    动作是Snort规则中的第一个部分,它表示规则的条件符合的时候,将会有什么样的动作产生。Snort有5个预定义的动作,你也可以定义自己的动作,需要注意的是,Snort 1.x和2.x对规则的应用是不同的,在1.x中,只要包符合第一个条件,它就会做出动作,然后就不再管它,尽管它可能符合多个条件;在2.x中,只有包和所有相应规则比对后,才根据最严重的情况发出告警。
     
    3.5.1.1 pass
    这个动作告诉Snort不理会这个包,这个动作在你不想检查特定的包的时候可以加快Snort的操作速度。例如,如果你在网络中有一台包含一些弱点的主机,用来检测网络安全漏洞,可能会希望不理会对这台机器的***,pass规则这时就可以用到了。
    3.5.1.2 Log
    Log动作用来记录包,记录包有不同的方式,例如,可以记录到文件或者数据库,这将在以后讨论。根据命令行参数和配置文件,包可以被记录为不同的详细程度。你可以用“snort - ?”命令来查看你所用版本Snort的命令行可用参数。
    3.5.1.3 Alert
    Alert动作用来在一个包符合规则条件时发送告警消息。告警的发送有多种方式,例如可以发送到文件或者控制台。Log动作与Alert动作的不同在于:Alert动作是发送告警然后记录包,Log动作仅仅记录包。
    3.5.1.4 Activate
    Activate动作用来产生告警然后激活其它规则来进行进一步的检验。如下面所说的,动态规则就是用于这个目的。当你需要对捕获的包进行进一步检验的时候,就可以用activate动作。
    3.5.1.5 Dynamic
    Dynamic规则动作由其它用activate动作的规则调用,在正常情况下,他们不会被用来检测包。一个动态规则仅能被一个“activate”动作激活。
    3.5.1.6 自定义动作
    除了以上动作外,你也可以定义自己的动作,以用于不同的目的,例如:
    l        向Syslog发送消息。Syslog是系统日志守护进程,它在/var/log中创建日志文件,这些文件的位置可以通过修改/etc/syslog.conf来改变。你可以在UNIX系统中用命令“man syslog”或者“man syslog.conf”来获得更多信息。Syslog相当于Windows中的事件查看器。
    l        向如HP OpenView或Open NMS(http://www.opennms.org)等网管系统发送SNMP trap。
    l        在一个包上应用多个动作。如你前面所看到的,一个规则仅仅规定了一个动作,自定义动作可以用来产生多个动作。例如,你可以在发送SNMP trap的同时记录Syslog。
    l        将数据记录到XML文件中。
    将信息记录到数据库中,Snort可以将数据记录到MySQL, Postgress SQL, Oracle 和 Microsoft SQL server中。
    这些新的动作类型在配置文件snort.conf中定义。一个新动作用下面的通用结构来定义:
    ruletype action_name
    {
    action definition
    }
        关键字ruletype后面跟随动作的名称,两个大括号中是实际的动作定义,类似于C语言中的函数。例如,我们定义一个叫做smb_db_alert的动作,用来向workstation.list中的主机发送SMB告警,同时在MySQL中的“Snort”数据库记录,如下所示:
    ruletype smb_db_alert
    {
    type alert
    output alert_smb: workstation.list
    output database: log, mysql, user=rr password=rr \
    dbname=snort host=localhost
    }
     
    这些规则的类型我们会在下一章详细讨论,通常它们与配置和输出插件有关。
    3.5.2协议
    协议是Snort规则中的第二部分,这一部分将显示那种类型的包将与该规则比对。到目前为止,Snort可以支持以下协议:
    l        IP
    l        ICMP
    l        TCP
    l        UDP
    如果协议是IP,Snort检测包中的数据链路层头部来确定包的类型,如果协议类型是其他任何一种,Snort检测IP头部来确定协议类型。不同的包头部将在附录C中讨论。
    协议部分仅仅在规则头部的条件中起作用。规则中的选项部分可以附加与协议无关的条件。如下面协议为ICMP的规则:
    alert icmp any any -> any any (msg: "Ping with TTL=100"; \
    ttl: 100;)
    选项部分检测TTL值,它并不是ICMP头部的内容,而是IP头部内容。这就是说选项部分可以检测属于其它协议的一些参数。常用协议的头部和相关分析见附录C。
    3.5.3地址
    在Snort规则中,有两个地址部分,用来检测包的来源和目的地。地址可以是一个主机地址或者网络地址。你可以用关键字any来指定所有的地址。地址后面用斜线来附加一个数字,表示掩码的位数。比如192.168.2.0/24代表一个C类网络192.168.2.0,其子网掩码是255.255.255.0。记住下面的一些子网掩码:
    l        如果子网掩码是24位,它是一个C类网络。
    l        如果子网掩码是16位,它是一个B类网络。
    l        如果子网掩码是24位,它是一个A类网络。
    l        表示一个主机用32位掩码。
    根据CIDR的支持,你可以用任何位数的掩码。参考RFC 791取得关于IP地址和子网掩码的信息。CIDR的更多信息参考RFC 1519。
    前面我们提到,Snort规则中有两个地址段,其中一个是源地址,另外一个是目的地址。方向段指明那个是源地址,哪个是目的地址。参考方向段部分的叙述来了解更多信息。
    下面是一个在Snort规则中地址部分的例子:
    l        192.168.1.3/32定义一个地址为192.168.1.3的主机。
    l        192.168.1.0/24定义从192.168.1.0到192.168.1.255的C类网络地址,子网掩码是24位,相当于255.255.255.0。
    l        152.168.0.0/24定义从152.168.0.0到192.168.255.255的B类网络地址,子网掩码是16位,相当于255.255.0.0。
    l        10.0.0.0/8定义从10.0.0.0到10.255.255.255的A类网络地址,子网掩码是8位,相当于255.0.0.0。
    l        192.168.1.16/28定义从192.168.1.16到192.168.1.31的网络地址,子网掩码是28位,相当于255.255.255.240。在这16个地址中有14个可以用作主机地址,因为还有一个网络地址和一个广播地址,注意,在任何网络中的一个地址总是网络地址,最后一个是广播地址。在这个例子中192.168.1.16是网络地址,192.168.1.31是广播地址。
     
    例,你可以用下面的规则,使到web服务器192.168.1.10/32的80端口的TTL为100的数据包触发告警:
    alert tcp any any -> 192.168.1.10/32 80 (msg: "TTL=100"; \
    ttl: 100;)
    这个规则仅仅用来示例IP地址是如何在Snort规则中应用的。
    3.5.3.1 排除某些地址
    Snort提供一种机制,可以是你用否定符号“!”,也就是感叹号,来排除某些地址,这个符号用来限制Snort 不对某些源或目的地址的包做检测。例如,西面的规则将检测除了来自C类网络192.168.2.0之外所有的包:
    alert icmp ![192.168.2.0/24] any -> any any \
    (msg: "Ping with TTL=100"; ttl: 100;)
    当你想测试不包括你自己的网络的其它的包的时候,这个规则非常有用,这也意味着你信任自己所在网络的所有人!
    3.5.3.2 地址列表
    你也可以在Snort规则中指定一个地址的列表,比如,你的网络中包含两个C类网络:192.168.2.0和192.168.8.0,你想对除了这两个网络之外的其它地址应用规则,你可以用下面的规则,其中两个地址用逗号分隔:
     alert icmp ![192.168.2.0/24,192.168.8.0/24] any -> any \
    any (msg: "Ping with TTL=100"; ttl: 100;)
    注意,方括号是与否定符号以器用的,如果没有否定符号,你可以不用方括号。
    3.5.1端口号
    端口号用来在进出特定的某个或一系列端口的包上运用规则,例如,你可以用源端口23来对来自Telnet服务器的包应用规则。你可以用关键字any来对包应用规则,而不管它的端口号。段口号仅仅对TCP和UDP协议有意义,如果你选择的协议是IP或者ICMP,端口号就不起作用。下面的规则用来检测来自C类网络192.168.2.0/24中的Telnet服务器,并包含“confidential”(机密)的包:
    alert tcp 192.168.2.0/24 23 -> any any \
    (content: "confidential"; msg: "Detected confidential";)
    同类的规则也可以用在这个网络中来自或者去向任何Telnet服务器的包,我们改以下方向段为任何方向,如下所示:
    alert tcp 192.168.2.0/24 23 <> any any \
    (content: "confidential"; msg: "Detected confidential";)
    当你想仅对某种类型的包应用规则的时候,端口号是非常有用的。例如,一种***仅与HTTP web服务器相关,你可以在规则中设置端口号80来检测试图进行这种***的人,这样Snort规则仅仅监视web服务,不对其它的TCP包应用规则。制订良好的规则一定能提高IDS的性能。
    3.5.4.1 端口范围
    你也可以在规则中的端口段设置一系列的端口,而不只是一个。用冒号分隔起始和结束。例如下面的规则将对来自1024-2048的所有UDP包告警:
    alert udp any 1024:2048 -> any any (msg: “UDP ports”;)
    3.5.4.2 上限与下限
    你可以仅用一个起始端口号或结束端口号来表示端口列表,例如:1024表示比1024小,包含1024的所有端口,1000:表示比1000大,包括1000的所有端口。
    3.5.4.3 否定符
    与地址段相同,你也可以在Snort规则中的端口段用否定符号来排除一个或多个端口。下面的规则将记录除了53段口外的其它所有UDP通信。
    log udp any !53 -> any any log udp
    但是你不能用逗号来分隔多个端口,如53,54这样的表示是不允许的,但是你可以用53:54来表示一个端口范围。
    3.5.4.4 共用端口号。
    共用端口号是提供给一些公用应用的,表3-1列举了其中一些及应用。
    端口号 描述
    20 FTP数据
    21 FTP
    22 SSH或安全Shell
    23 Telnet
    25 SMTP或类似于Sendmail的e-mail服务器
    37 NTP(网络时钟协议,用来同步网络主机时间)
    53 DNS 服务器
    67 BootP/DHCP客户端
    68 BootP/DHCP服务器
    69 TFTP
    80 HTTP,web服务器
    110 POP3,供类似于OE的邮件客户端使用
    161 SNMP
    162 SNMP trap
    443 HTTPS或安全HTTP
    514 Syslog

     
    在UNIX平台上,你可以查看/etc/services文件,可以看到更多的端口的定义。RFC 1700中包含详细列表。目前ICANN负责管理这些端口号,你可以在http://www.icann.org获得更多信息。
    3.5.5方向段
    在Snort规则中,方向段确定源和目的。下面是方向段的相关规定:
    ->表示左边的地址和端口是源而右边的是目的。
    <-表示右边的地址和端口是源而左边的是目的。
    <>表示规则将被应用在两个方向上,在你想同时监视服务器和客户端的时候,可以用到这个标示。例如,你可以监视往来POP或者Telnet服务器的数据流。
    3.6 规则选项
       Snort规则的选项在头部的后面,在一对圆括号里面,其中可能包含一个选项,也可能包含用分号分隔的多个选项,这些选项的关系是逻辑与的关系,只有当选项中的条件都满足的时候,规则动作才会被执行。在前面的例子中,你已经来规则中应用了msg和ttl的选项。所有的选项都是由关键字来定义的,一些选项中还会包含变量值。一个选项包含两个主要部分:一个关键字和变量值。关键字和变量值由冒号分隔。如你前面看到的:
    msg: "Detected confidential";
       在这个选项中,关键字是msg,而"Detected confidential"是变量值。
       本部分的后面将叙述在Snort规则的选项部分的各种关键字:
      
       3.6.1关键字ack
       Tcp头部中包含一个32位的Acknowldege Number字段,这个字段表示希望对端发送的下一个Tcp包的序列号。仅当TCP头部的ACK标志位被设为1的时候,这个字段才起作用。关于TCP头部的详细资料,参考附录C或者RFC 793。
       类似于nmap的工具用TCP头部的这个特征来扫描计算机,例如,在这些工具所用的技术中,它们向目标主机发送至80端口,ACK标志为1,序列号为0的TCP包,这样目标主机就不会接受这个包,并发回一个RST标志为1的包,当nmap受到这个包的时候,就知道那台主机是存在的。当目标主机不对ICMP做出回应的时候,这个方法可以起到作用。
       为了探测到这种TCP ping,你可以用类似于下面的规则来产生告警信息:
          alert tcp any any -> 192.168.1.0/24 any (flags: A; \
    ack: 0; msg: "TCP ping detected";)
       这条规则的作用是在当你收到标志位A为1而acknowledgement段的值为0的TCP包的时候,发送一个告警信息。表3-2列举了其他的TCP标志位。在本规则中,定义包的目的是192.168.1.0/24,你可以用其它的值。关键字ack基本上用来探测这种类型的***,一般情况下,如果A位为1,Ack的值是不等于0的。
    3.6.2关键字classtype
    Snort规则可以分配类别和优先级以便区分,为全面了解关键字classtype,首先我们来看被snort.conf用include关键字所引用的classifacation.config文件,该文件的每一行都遵循下面的语法:
    config classification: name,description,priority
    其中name用来表示类别名称,在Snort规则中用classtype关键字来指定,description是对类别的简单描述。Priority是这个类别的默认优先级,用数字表示,并可以在Snort选项中用关键字priority改变。你也可以把这些语句放在snort.conf中。下面是一个例子:
    config classification: DoS,Denial of Service Attack,2
       上面的一行中,定义了一个类别DoS,其优先级为2。在第6章中,你将看到在基于web的Snort分析工具ACID中用到这个类别。现在让我们在规则中应用这个类别,如下例,优先级为默认值:
    alert udp any any -> 192.168.1.0/24 6838 (msg:"DoS"; \
    content: "server"; classtype:DoS;)
    我们改变这个规则,可以覆盖默认优先级:
    alert udp any any -> 192.168.1.0/24 6838 (msg:"DoS"; \
    content: "server"; classtype:DoS; priority:1)
       分类和优先级的意义在于,我们可以了解告警是否紧急,这在我们要对威胁性高的告警提高警惕的时候非常有用。
       如果你看到在第6章中讨论的ACID浏览器窗口,就可以看到图3-3中所示的classifacation栏,在窗口中间的第二列是所捕获数据包的分类。其他的一些分析工具也用关键字classification来区分***行为的类别。典型的classification.conf文件如下所示,这个文件与Snort1.9.0共同发行,你可以在这个文件中增加自己的分类并在自己的规则中应用。
    # $Id: classification.config,v 1.10 2002/08/11 23:37:18 cazz Exp $
    # The following includes information for prioritizing rules
    #
    # Each classification includes a shortname, a description, and a
    default
    # priority for that classification.
    #
    # This allows alerts to be classified and prioritized. You can specify
    # what priority each classification has. Any rule can override the
    default
    # priority for that rule.
    #
    # Here are a few example rules:
    #
    # alert TCP any any -> any 80 (msg: "EXPLOIT ntpdx overflow";
    # dsize: > 128; classtype:attempted-admin; priority:10;
    #
    # alert TCP any any -> any 25 (msg:"SMTP expn root"; flags:A+; \
    # content:"expn root"; nocase; classtype:attempted-recon;)
    #
    # The first rule will set its type to "attempted-admin" and override
    # the default priority for that type to 10.
    #
    # The second rule set its type to "attempted-recon" and set its
    # priority to the default for that type.
    #
    #
    # config classification:shortname,short description,priority
    #
    config classification: not-suspicious,Not Suspicious Traffic,3
    config classification: unknown,Unknown Traffic,3
    config classification: bad-unknown,Potentially Bad Traffic, 2
    config classification: attempted-recon,Attempted Information Leak,2
    config classification: successful-recon-limited,Information Leak,2
    config classification: successful-recon-largescale,Large Scale
    Information Leak,2
    config classification: attempted-dos,Attempted Denial of Service,2
    config classification: successful-dos,Denial of Service,2
    config classification: attempted-user,Attempted User Privilege Gain,1
    config classification: unsuccessful-user,Unsuccessful User Privilege
    Gain,1
    config classification: successful-user,Successful User Privilege Gain,1
    config classification: attempted-admin,Attempted Administrator
    Privilege Gain,1
    config classification: successful-admin,Successful Administrator
    Privilege Gain,1
    # NEW CLASSIFICATIONS
    config classification: rpc-portmap-decode,Decode of an RPC Query,2
    config classification: shellcode-detect,Executable code was detected,1
    config classification: string-detect,A suspicious string was detected,3
    config classification: suspicious-filename-detect,A suspicious filename
    was detected,2
    config classification: suspicious-login,An attempted login using a
    suspicious username was detected,2
    config classification: system-call-detect,A system call was detected,2
    config classification: tcp-connection,A TCP connection was detected,4
    config classification: trojan-activity,A Network Trojan was detected, 1
    config classification: unusual-client-port-connection,A client was
    using an unusual port,2
    config classification: network-scan,Detection of a Network Scan,3
    config classification: denial-of-service,Detection of a Denial of
    Service Attack,2
    config classification: non-standard-protocol,Detection of a nonstandard
    protocol or event,2
    config classification: protocol-command-decode,Generic Protocol Command
    Decode,3
    config classification: web-application-activity,access to a potentially
    vulnerable web application,2
    config classification: web-application-attack,Web Application Attack,1
    config classification: misc-activity,Misc activity,3
    config classification: misc-attack,Misc Attack,2
    config classification: icmp-event,Generic ICMP event,3
    config classification: kickass-porn,SCORE! Get the lotion!,1
    config classification: policy-violation,Potential Corporate Privacy
    Violation,1
    config classification: default-login-attempt,Attempt to login by a
    default username and password,2
    3.6.3关键字content
    Snort的一个重要特征就是它可以在包的里面发现数据特征,这些特征可能以ASCII字符的形式出现,也可能是16进制字符所表示的二进制数据。如同病毒,***者的行为也通常会在数据包中表现某种特征,关键字content就使用来发现这些特征的。Snort1.x版本不支持应用层协议,但是用content与offset关键字联合使用,也可以找到应用层的数据。
    下面的规则可以检测离开网络192.168.1.0并在数据段含有“GET”的TCP包。在HTTP相关的***中,GET是经常被用到的一个关键字。然而,这个规则仅仅能够使你了解如何用关键字content来工作。
    alert tcp 192.168.1.0/24 any -> ![192.168.1.0/24] any \
    (content: "GET"; msg: "GET matched";)
    以下的规则作用与上面一条相同,但是特征以16进制表示。
    alert tcp 192.168.1.0/24 any -> ![192.168.1.0/24] any \
    (content: "|47 45 54|"; msg: "GET matched";)
    16进值的数字47与ASCII字符G的值相等,45与E相等,54与T相等。你可以在同一条规则中同时用ASCII和16进制来进行特征比对。用16进值表示时,应当用双竖线||将字符包括进去。
    在用content关键字的时候,要记住以下的原则:
    内容比对是
     
    3.6.34

    3.7Snort配置文件

    Snort通过配置文件来完成启动配置,例如下面的启动命令:

    /opt/snort/snort -c /opt/snort/snort.conf

    配置文件包括6个基本的部分:

     

    变量定义,变量用于Snort规则和其他的目的,比如规则文件的路径。

    配置参数,指定Snort配置的选项,其中有些参数也可以用在命令行中。

    预处理器配置。用来在探测引擎执行特定的动作前对包进行处理。

    输出模块配置。控制如何记录数据。

    定义新的动作类型。如果预定义的动作类型不能够满足你的要求你可以在配置文件中自定义动作。

    规则配置和引用文件。尽管你可以在snort.conf中定义规则,将规则放在不同的文件中还是更加方便管理。你可以用关键字include来指定你所引用的规则文件。

     

    3.7.1在规则中使用变量

    在配置文件中,你可以使用变量,这样会带来一些方便。例如,你可以在配置文件中定义HOME_NET变量。

    var HOME_NET 192.168.1.0/24

     

    然后你就可以在你的规则中引用这个变量:

    alert ip any any -> $HOME_NET any (ipopts: lsrr; \

    msg: “Loose source routing attempt”; sid: 1000001;)

     

    这样做的好处是可以使配置文件用在不同环境中,你所做的只是改变变量的值,而不需要修改每个规则。

    3.7.11在变量中使用网络列表

    你也可以定义一个包含多个条目的变量,例如一个包含两个网段的网络:

    var HOME_NET [192.168.1.0/24,192.168.10.0/24]

    不同的网络用逗号分隔。

    3.7.1.2 在变量中使用网络接口名称

    在定义变量的时候,你可以用网络接口名称:

    var HOME_NET $eth0_ADDRESS

    var EXTERNAL_NET $eth1_ADDRESS

    3.7.1.3 使用关键字any

    关键字any也可以成为一个变量。它匹配任何值,例如:

    var EXTERNAL_NET any

     

    在系统自带的snort.conf文件中,已经定义了很多变量,你可以根据自己的需要修改。

     

    3.7.2 配置指令

    在snort.conf文件中用配置指令可以让用户配置Snort的全局设定。例如日志文件的路径,规则的应用顺序等等。配置指令的大体格式如下:

    config directive_name[: value]

    表3-6是一个指令列表

    指令
     描述
     
    Order
     改变规则应用的顺序,相当于命令行中的-o选项。
     
    Alertfile
     用来设置告警文件的名称。
     
    Classification
     用来建立规则的分类。
     
    Decode_arp
     打开arp解码,相当于命令行-a选项
     
    Dump_chars_only
     相当于命令行选项 –C
     
    Dump_payload
     相当于命令行选项 –d,用来从包中获得数据载荷的内容
     
    Decode_data_link
     相当于命令行选项 –e,用来数据链路层头部的解码。
     
    Bpf_file
     相当于命令行选项 –F
     
    Set_gid
     相当于命令行选项 –g,用来设定运行Snort的组用户ID
     
    Daemon
     相当于命令行选项 –D,这样用守护进程的模式调用Snort
     
    Reference_net
     相当于命令行选项 –h.用来设置本地网络地址
     
    Interface
     相当于命令行选项 –i.用来设置Snort的网络接口。
     
    Alert_with_interface_name
     相当于命令行选项 –T,用来在告警消息的后面附加接口信息。
     
    Logdir
     相当于命令行选项 –l.
     
    Umask
     相当于命令行选项 –m,用来在运行Snort的时候设置Umask.
     
    Pkt_count
     相当于命令行选项 –n,用来在接受到一定数量的包后退出Snort
     
    Nolog
     相当于命令行选项 –N,用来停止告警以外的日志。
     
    Obfuscate
     相当于命令行选项-O,用来在以伪装的IP来向其他人发送消息,这样可以掩藏自己的IP地址。
     
    No_promisc
     相当于命令行选项 –p,用来关闭混杂模式。
     
    Quite
     相当于命令行选项-q,用来关闭Snort启动时候的欢迎信息和统计信息。
     
    Chroot
     相当于命令行选项-t,用来改变根目录
     
    Checksum_mod
     用来检验特定类型的包的校验值。
     
    Set_uid
     相当于命令行选项-u,用来设置运行Snort的用户ID
     
    Utc
     相当于命令行选项-U,用UTC时间代替本地时间作为日志的时钟。
     
    Verbose
     相当于命令行选项-v,在记录日志的同时,将日志信息输出到标准输出。
     
    Dump_payload_verbose
     相当于命令行选项-X,将原始包信息传送到标准输出
     
    Show_year
     在日志时间戳中加上年份
     
    Stateful
     设置stream4预处理器的声明模式
     

     

    3.7.3预处理器的配置

    预处理器的配置格式如下:

    preprocessor <preprocessor_name>[: <configuration_options>]

    详细内容在第四章解释。

    3.7.4输出模块配置

    输出模块的配置格式如下:

    output <output_module_name>[: <configuration_options>]

    详细内容在第四章解释。

     

    3.7.5定义新的动作类型

    每个Snort规则的第一个部分都是动作。Snort有很多预定义的动作,但是如果这些动作仍然不能满足你的要求,你可以定义自己的动作。

    一个新的动作类型可以包含多个输出模块。例如:

    ruletype dump_database

    {

    type alert

    output database: alert, mysql, user=rr dbname=snort \

    host=localhost

    output log_tcpdump: tcpdump_log_file

    }

    新定义的动作类型同样可以在规则种应用:

    dump_database icmp any any -> 192.168.1.0/24 any \

    (fragbits: D; msg: "Don’t Fragment bit set";)

    如上面的例子,日志将同时被记录到数据库和日志文件。

    3.7.6 规则的配置

    规则的配置往往是配置文件中的最后部分。你可以用include关键字将其他的规则文件引用。

    3.7.8示例

    下面是一个配置文件的示例,如果你修改了配置文件,就需要重新启动Snort使之生效。

    # Variable Definitions

    var HOME_NET 192.168.1.0/24

    var EXTERNAL_NET any

    var HTTP_SERVERS $HOME_NET

    var DNS_SERVERS $HOME_NET

    var RULE_PATH ./

    # preprocessors

    preprocessor frag2

    preprocessor stream4: detect_scans

    preprocessor stream4_reassemble

    preprocessor http_decode: 80 -unicode -cginull

    preprocessor unidecode: 80 -unicode -cginull

    preprocessor bo: -nobrute

    preprocessor telnet_decode

    preprocessor portscan: $HOME_NET 4 3 portscan.log

    preprocessor arpspoof

    # output modules

    output alert_syslog: LOG_AUTH LOG_ALERT

    output log_tcpdump: snort.log

    output database: log, mysql, user=rr password=boota \

    dbname=snort host=localhost

    output xml: log, file=/var/log/snortxml

    # Rules and include files

    include $RULE_PATH/bad-traffic.rules

    include $RULE_PATH/exploit.rules

    include $RULE_PATH/scan.rules

    include $RULE_PATH/finger.rules

    include $RULE_PATH/ftp.rules

    include $RULE_PATH/telnet.rules

    include $RULE_PATH/smtp.rules

    include $RULE_PATH/rpc.rules

    include $RULE_PATH/dos.rules

    include $RULE_PATH/ddos.rules

    include $RULE_PATH/dns.rules

    include $RULE_PATH/tftp.rules

    include $RULE_PATH/web-cgi.rules

    include $RULE_PATH/web-coldfusion.rules

    include $RULE_PATH/web-iis.rules

    include $RULE_PATH/web-frontpage.rules

    include $RULE_PATH/web-misc.rules

    include $RULE_PATH/web-attacks.rules

    include $RULE_PATH/sql.rules

    include $RULE_PATH/x11.rules

    include $RULE_PATH/icmp.rules

    include $RULE_PATH/netbios.rules

    include $RULE_PATH/misc.rules

    include $RULE_PATH/attack-responses.rules

    include $RULE_PATH/myrules.rules

     

    3.8 基于动作的Snort规则包检验顺序

    5种类型的Snort规则可以归为3个大类:

    告警规则

    通过规则

    日志规则

    当Snort收到包的时候,会按照上面三种规则依次检验,这样的设计是安全性非常高的。但是因为大多数包是正常的包,因此这样做也会耗费一些系统资源,Snort提供一种方法改变顺序来提高效率,但是这样做也会使安全性降低。将顺序改变为:

    通过规则

    告警规则

    日志规则

    在改变规则的时候要仔细,因为可能一个比较差的规则就可能让很多恶意的包通过。你可以在配置文件中用config order来实现顺序的改变:

    config order

    如果你定义了自己的规则类型,它们一般会在监测顺序的最后。

     

    3.9自动升级Snort规则

    有许多工具可以用来升级Snort的特征库,下面介绍两个升级Snort规则的方法

    39.1简单的方法

    这个方法包含一个简单的shell脚本,你需要在你的系统中安装wget程序。这个程序用来用HTTP协议来获得文件的信息,与浏览器类似,但是它用命令行来取得文件的信息。

    #!/bin/sh

    # Place of storing your Snort rules. Change these variables

    # according to your installation.

    RULESDIR=/etc/snort

    RULESDIRBAK=/etc/snort/bak

    # Path to wget program. Modify for your system if needed.

    WGETPATH=/usr/bin

    # URI for Snort rules

    RULESURI=http://www.snort.org/downloads/snortrules.tar.gz

    # Get and untar rules.

    cd /tmp

    rm -rf rules

    $WGETPATH/wget $RULESURI

    tar -zxf snortrules.tar.gz

    rm –f snortrules.tar.gz

    # Make a backup copy of existing rules

    mv $RULESDIR/*.rules $RULESDIRBAK

    # Copy new rules to the location

    mv /tmp/rules/*.rules $RULESDIR

    下面让我们来看这个脚本是如何工作的。下面的几行是定义一些变量:

    RULESDIR=/etc/snort

    RULESDIRBAK=/etc/snort/bak

    WGETPATH=/usr/bin

    RULESURI=http://www.snort.org/downloads/snortrules.tar.gz

    下面的3行用来删除/tmp目录下面的/tmp/rules并从$RULESURI变量中指定的URI下载snortrules.tar.gz文件然后用下面的两行命令解压并删除它。

    tar -zxf snortrules.tar.gz

    rm -f snortrules.tar.gz

    下面的一行用来备份现有的规则文件的拷贝,以便你需要使用它们。

    mv $RULESDIR/*.rules $RULESDIRBAK

    脚本中的最后一行将新的规则文件从/tmp/rules目录移动到工作目录./etc/snort这样Snort就可以读取它们了。

    mv /tmp/rules/*.rules $RULESDIR

    运行脚本之后要重新启动Snort。

     

    3.9.2 复杂的方法

    这一部分介绍关于Oinkmaster的信息。你可以在http:// www.algonet.se/~nitzer/oinkmaster/找到关于这个工具的信息。这个工具是用perl写的,所以你必须在运行Snort的机器上安装Perl。

     

     

     

     

    3.10 默认的Snort规则和分类

    随Snort发行版含有很多的规则,它们被存放到不同的文件中,每个文件代表一类规则。例如1.9.0附带的规则文件:

    attack-responses.rules

    backdoor.rules

    bad-traffic.rules

    chat.rules

    ddos.rules

    deleted.rules

    dns.rules

    dos.rules

    experimental.rules

    exploit.rules

    finger.rules

    ftp.rules

    icmp-info.rules

    icmp.rules

    imap.rules

    info.rules

    local.rules

    Makefile

    Makefile.am

    Makefile.in

    misc.rules

    multimedia.rules

    mysql.rules

    netbios.rules

    nntp.rules

    oracle.rules

    other-ids.rules

    p2p.rules

    policy.rules

    pop3.rules

    porn.rules

    rpc.rules

    rservices.rules

    scan.rules

    shellcode.rules

    smtp.rules

    snmp.rules

    sql.rules

    telnet.rules

    tftp.rules

    virus.rules

    web-attacks.rules

    web-cgi.rules

    web-client.rules

    web-coldfusion.rules

    web-frontpage.rules

    web-iis.rules

    web-misc.rules

    web-php.rules

    x11.rules

    例如,所有和X-window***相关的规则都在x11.rules文件中。

    # (C) Copyright 2001,2002, Martin Roesch, Brian Caswell, et al.

    # All rights reserved.

    # $Id: x11.rules,v 1.12 2002/08/18 20:28:43 cazz Exp $

    #----------

    # X11 RULES

    #----------

    alert tcp $EXTERNAL_NET any -> $HOME_NET 6000 (msg:"X11 MIT Magic

    Cookie detected"; flow:established

    ; content: "MIT-MAGIC-COOKIE-1"; reference:arachnids,396;

    classtype:attempted-user; sid:1225; rev:3;

    )

    alert tcp $EXTERNAL_NET any -> $HOME_NET 6000 (msg:"X11 xopen";

    flow:established; content: "|6c00 0b

    00 0000 0000 0000 0000|"; reference:arachnids,395; classtype:unknown;

    sid:1226; rev:2;)

    3.10.1local.rules文件

    local.rules文件中没有规则,它是用来存放管理员自定义的规则的。你也可以用其他文件来存放自定义的规则。

     

     

    3.11一些默认的规则的样板

    这一部分分析一些随Snort发行的预先定义的规则,这里的规则都是来自于telnet.rules文件,现在让我们来分析它们:

    3.11.1监测telnet会话中的su尝试

    下面的规则探测尝试在telnet进程中su超级用户的尝试:

    alert tcp $TELNET_SERVERS 23 -> $EXTERNAL_NET any (msg:"TELNET

    Attempted SU from wrong group"; flow:

    from_server,established; content:"to su root"; nocase;

    classtype:attempted-admin; sid:715; rev:6;)

    在这个规则中,有很多地方需要注意:

     

    变量是$TELNET_SERVERS在snort.conf中定义的Telnet服务器列表。

    规则仅仅监测telnet服务器的回应,而不是请求

    变量$EXTERNAL_NET是在snort.conf中定义的外部网络。规则将监测来自于外部的telnet会话,对于内部网络的telnet会话,就不会做出监测。

    关键字flow用来将规则仅仅应用在已经建立的会话上面。

    关键字content用来监测含有“to su root”的包,如果有,则产生告警。

    关键字nocase使规则忽略包内容的大小写。

    关键字classtype给规则归类

     

    规则的ID是715

    关键字rev显示规则的版本

     

    3.11.2 监测telnet会话中的登录失败

    下面的规则与上个规则类似,它可以监测登录Telnet服务器的失败尝试:

    alert tcp $TELNET_SERVERS 23 -> $EXTERNAL_NET any (msg:"TELNET login

    incorrect"; content:"Login inco

    rrect"; flow:from_server,established; reference:arachnids,127;

    classtype:bad-unknown; sid:718; rev:6;)

    它比上个规则多出了一个指定参考地址的关键字。

     

     

     

    3.12写有质量的规则

    在Snort的发行版中有已经定义好的规则,这些规则对于你编写优质的规则是个不错的参考。尽管不是强制性的,但是你最好在每个规则的选项中用到下面的部分:

    用msg关键字引导的消息

    用classification关键字引导的规则分类

    用sid关键字引导的的数字用来标示规则

    用reference关键字引导的系统弱点参考URL

    用rev来表明不同的规则版本

     

    另外,你应该用不同的方法来***你的网络来测试你的规则,因为恶意用户也会用各种方法来***网络。好的规则应该能够探测到各种***。

     

关键字