网络入侵检测系统(NIDS)是网络安全管理常用的安全设备之一。各大安全厂商都有自己的IDS(入侵检测系统)产品,如雇明星辰的天阒.绿盟的冰之眼,天融信的TOPSENTRY等。被评为2006年百大安全工具第三名的SNORT也是一个开源的NIDSo除开源的SNORT外,各大商用的网络入侵检测系统一般都非常昂贵,而且部署也比较麻烦,一般适合用于较为庞大的网络环境,如IDC和大型的企业应用网络等。在安全管理过程中,我们发现一些网络环境也有使用入侵检测系统的需求,比如一个大型网络环境中的子网络部分。因为大型网络入侵检测系统比较昂贵,部署也比较麻烦,因此我们只能在骨干网络上应用.在核心网络上检测安全事件。由于各子网络在地址分配上一般都使用NAT。
这样我们在核心的入侵检测系统上检测到一些安全事件.如病毒木马等的时候,只能定位到某个子网络,而不能精确地定位到子网络上哪台机器出了问题。一般在这种情况下.我们不可能把入侵检测系统再放到子网络中去,只能到出问题的子网络上使用一些抓包工具.如Sniffer、WireSHare等来抓包分析,以期找到问题出处。这些抓包工具般都用来进行协议分析,而不是专门的安全事件分析工具.并不能很好地识别安全事件,只能靠工程师自身的知识来对网络中的数据包进行分析,以定位事件来源。如果安全事件比较多,安全工程师的工作负担会很大。网络IDS的主要原理就是对网络传输的数据包进行内容和行为检查,那我们能不能用简单的方法实现一个轻量级的网络IDS以填补安全管理中的空白呢?为了解决这个问题,我们先要明确这个轻量级iDS的设计目标,然后我们并根据这些目标来寻找实现的方法。我们的IDS要实现的目标有
1、基于Windows平台,部署和使用方便,不用安装额外的插件,能即拷即用,方便放到笔记本电脑上携带至工作地点:
2、适用于办公网络,网络环境不太复杂,检测的安全事件主要为病毒和木马
3、基于对安全事件的模式匹配来检测安全事件,即像杀毒软件一样,有安全事件的规则库,可自定义检测规则,能对检测规则进行方便的修改和升级。如果一个数据包内容和检测规则定义的内容匹配,则把这个数据包定义为攻击数据包
4、检测广度为单TCP和UDP数据包,只做到单包检测:
5、检测深度为TCP和UDP的payload部分,即数据包的数据段:
6、实时检测,适用于网络流量为10MBPS的小型网络或者单机
7、有简单的日志记录功能,能记录并保存检测到的安全事件。
如果我们的IDS达到了上面这些设计目标,那么我们在日常安全管理过程中碰到的问题就可以得到有效的解决。
开发环境
在Windows环境下进行开发,首选的集成开发环境是vc++。我们使用6.0版本来开发iDS.它有强大的开发库,为开发底层的Windows程序提供了便捷的方法。IDS一个主要的功能就是进行网络数据包的捕获。在Windows平台下实现网络数据包的捕获有两种方法,一种是WinPcap开发包,一种就是使用WinSocket建立原始套接字。WinPcap提供了功能强大的网络数据包捕获接口,但是用它开发应用程序后,必须在程序运行的系统上安装WinPcap工具包.才能使程序正常工作.这和我们的设计目标不符而用Socket编写的程序能在普遍的环境中直接使用,不需要做任何额外的工作。因此,我们选用原始套接字来实现数据包捕获过程。
原理和流程
Common Intrusion Detection Framework (CIDF)是现阶段iDS设计的标准模型,几乎所有的IDS产品都是按照这个模型进行设计和开发的。它以模块设计的方法将一个入侵检测系统分为以下组件事件产生器(Event generators)、事件分析器(Eventanalyzers)、响应单元(Response units)和事件数据库{Event dalabases)。
事件产生器是产生入侵检测系统初始分析数据的模块,在我们设计的IDS中,它表现为对网络数据包的捕获,也就是建立一个原始套接字对经过网卡的所有IP数据包进行抓取,送到下一步的程序中进行分析,它对入侵检测系统的数据输入端。事件分析器是对上一步抓取的数据包进行模式匹配分析的模块。它对数据包和载人系统中的规则进行匹配分析,如果匹配成功,则把该数据包视为一个攻击数据包,产生一次攻击事件。响应单元是在事件分析模块检测到安全事件时,做出相应的响应动作的模块。其响应动作有发出警报、发送邮件、记录安全事件等,用于通知用户有安全事件发生。事件数据库是保存安全事件记录的模块,也就是一个安全事件曰志,以便日后对安全事件记录进行查询和处理,它是入侵检测系统的输出端。
我们根据CIDF设计模型对我们的IDS进行模块化设计,并把它的工作流程化,做出其工作流程图,如图1所示。
数据包捕获的实现
网卡的工作模式有两种.一种是普通模式,它只能接收发往网卡本地址和广播地址的数据包。另外一种是混杂模式,在这种模式下,它将接收所有到达的数据包。因此,作为网络入侵检测系统.它应把接收数据包的网卡设为混杂状态。然后把主网络设备上的数据包流量镜像到该网卡上,使入侵检测系统能捕获和分析网络传输的所有数据包。在indows下,我们用原始套接字来实现入侵检测系统的这个功能。要使用原始套接字,我们要在程序中加入WinSocket头文件”#incIUde <winsock2h>“。和平常的Sockei编程差不多.我们建立一个原始套接字的过程如下。
1、初始化一个原始套接字。
和建立一般的Socket不同的是,WSASocket函数的第二个参数是SOCK_RAW.表明建立的套接字是原始套接字。
2、获得本机网卡的IP地址.并绑定到原始套接字上。
3、用WSAIoctl函数把该网卡设为混杂模式,即SIO_RCVALL。
这样,我们就建立了一个原始套接字,并把它绑定到了网卡上。我们用这个原始套接字可以捕获到经过网卡的所有数据包。原始套接宇本身带有数据缓冲功能,只须在程序中建立一个单数据包长度的临时缓冲空间,使用recv函数在原始套接字的缓冲区取一个数据包,放到程序的临时缓冲区内.把它交给我们的事件分析模块对它进行分析。由于网络数据包最大长度为65536字节,而使用ecv函数每次接收一个数据包,那么接收数据包的缓冲区也设置为65536字节"cHar pBuffer=(char*)malloc(MAX_PACKET_S【ZE):"。接收到数据包后,我们把它送到协议分析和事件分析的流程中。模式匹配人侵检测方法的实质是在数据包字节串上寻找匹配攻击特征的关键字节串.其主要过程如下。
协议分析的实现
1、分析网络上的每一个数据包是否具有某种攻击特征。
2、从网络数据包的包头开始和攻击特征比较。
3、如果比较结果相同,则检测到一个可能的攻击。
4、如果比较结果不同,则从网络数据包中下一个字节位置重新开始比较。
5、直到检测到攻击或网络数据包中的所有字节匹配完毕.一个攻击特征匹配结束。
6、对于每一个攻击特征。重复2开始的比较。直到每一个攻击特征匹配完毕,对数据包的匹配完毕。用原始套接宇捕获的数据包在形式上只是一段无序的字节流,因此用传统的模式匹配来对数据包字节流进行分析有很大的弊端。这种分析方法计算量是很大的,它每秒要求的比较量为:特征数据攻击特征字节数×网络数据包字节数×每秒数据包数量×攻击特征数量如果所有攻击特征长度为20字节,网络数据包平均长度为30字节,每秒30000数据包.供给特征库中有4000条特征,那么每秒比较次数为20 × 300 × 30000×4000=7200DOOOOOOO这个计算量是CPU很难承受的。
解决这个问题的方法有两个,一是对无序的数据包字节流进行协议分析二是优化检测特征,定义高效的数据包检测规则。
我们知道,数据包字节流虽然在形式上是无序的,但它是具有一定的逻辑结构的,它的每个数据位都有特定意义,所以我们可以按照其逻辑结构对数据包进行分类处理,也就是个协议分析的过程。
原始套接字接收的数据包是一个iP数据包iP数据包由IP报头和iP数据段组成。以下是一个用C语言表示的iP报头的逻辑组成结构。
缓冲区接到一个数据包的字节流后,我们先把它复制到一个临时空间temp里,然后把它转换为一个iP报头结构,在程序中表示为:"IPHeader *pipheader=( IPHeader#)temp”。对temp作一个C语言中的强制类型转换,这样我们就可以像操作一个结构一样对数据包进行操作了,比如要取得该数捉包的源地址可以通过这样的方式"ternp->sourcelp:"。lP报头的proto位表明了此ip包的下一层协议.那么可以通过该位对数据包进行进一步的分析。我们只关心两种协议UDP和TCP.当proto=IPPROTO_TCP时,表明该数据包为TCP数据包当proto-lPPROTO_UDP时,则表明该数据包为UDP数据包。jP数据包的数据段部分根据proto的值不同有不同的内容,如果proto指定这个包为TCP数据包,在数据段的开头包含一个TCP报头如果proto指定这个包为UDP数据包,则在数据段的开头包含一个UDP报头。TCP和UDP的报头结构可以用C语言描述如下。
由于在lP数据包结构中.TCP和UDP报头的位置跟在iP报头后。所以我们要对iP包字节流进行偏移运算后才能对TCP和uDP报头进行操作,偏移位是lP报头的长度。我们把iP包字节流分别进行偏移运算后转换为各自结构对于TCP是"TCPHeader*ptcpheader= TCPHeader*)(temp+sizeof( IPHeader))”,而对于UDP则是”UDPHeader{pudpHeader -(UDPHeader*)( temp+sizeof( iPHeader))”。把iP数据包按条件分别转换为TCP和UDP格式后,就可以分别对它们的各个数据位和它们承载的数据信息进行操作了,这样就达到了简单的协议分析的目的。TCP和UDP报头后是TCP和UDP的数据段。用于承载TCP和UDP数据.这些数据段也包含了下层协议的内容,如HTTP、FTP等。由于我们对IDS只做简单的实现,所以不再做深入的分析。这种结构化的分析方法比按顺序逐位分析数据包明了了很多,它能对数据包进行一个初始的识别和分层处理,使程序能够根据不同的条件进行下一步工作,从而提高了程序的工作效率并降低了CPU的工作量。
检测规则定义的实现
检测规则用于定义攻击数据包的特征.IDS程序读入规则后。对抓取的数据包和检测规则定义的攻击特征进行匹配,以达到检测攻击行为的目的。XML是用来定义程序数据特征的有力手段。因此我们的程序用XML来定义规则。以下是一条定义检测灰鸽子2006的完整规则体。
检测规则放入程序目录下的一个rule.xml文件中.以下是规则体各XML元素的意义。rule指定一条规则,是规则的父元素,规则的内容放入该元素中srcip指定要检测的源地址,它可以是特定的lP.比如要检测源lP为1 92 1 68 188 163的数据包,则指定元素<srcip>192.168.188.163</srcip>"。如果把它的值设为any.则表示检测源地址为任意的数据包。srcmask用于指定源地址的掩码,用于匹配IP地址端,和子网掩码的定义方式样。比如指定一个C类地址的掩码,则指定srcmask的值为255.255.255.0。dstip指定要检测的目的地址,它的值定义和srcip-样。dstmask用于指定目的地址的掩码,它的值定义和srcmask-样。srcpor时指定要检测的源端口,它是从0到65535的一个值,如果指定它为any.则表示检测源端口为任意的数据包。dstport指定要检测的目的端口,它的值定义和srcport一样。direction表示检测数据包的方向.它有两个值single和dohle。值slngle表示只检测规则定义的从源到目的的数据包,值为double表示检测规则定义的目的到源和源到目的双向的数据包。ttl用于检测数据包的ttI值,设定该值的目的是检测网络中的tracerouter尝试。toS用于检测数据包特定的tos值,某些攻击数据包可能会把tOs位设定为特定的值,以达到某些目的。identity用于检测数据包的id值,某些攻击数据包可能会把id位设定为特定的值,以达到不同的目的。比如某些黑客喜欢把他们制作的攻击数据包的id值设为31 337。dsize用于检测TCP和UDP数据包的paytload长度flags用于检测TCP数据包的flags值,比如我们要检查一个syn包,则把flags值设为2。seq用于检测TCP数据包的seq号。ack用于检测TCP数据包的ack号。Windows用于检测特定的TCP窗口值大小。conTent用于检测payload中的关键字.它是检测规则的子规则,每个检测规则可以有多个content规则。content规则的定义是使用类型匹配型IDS的最重要的功能,它是检测规则描述攻击特征的关键手段。
payload指定要检测的payload中的关键字,它可以用明文表示.也可以用十六进制的形式表示,以表达一些复杂的字符串。当使用字符的十六进制形式来描述关键字时,应该把它们放到“I“和“l”之间。比如表示一个长度为4的空串,则使用"100 00 00 001",程序将自动对其进行翻译。明文和十六进制不能在同一条content规则中的payload元素中混合使用。offset指定payload中检测关键字的偏移量.比如指定offset为5.则从payload的第5位开始检测。depth指定检测深度,比如指定oepth为20时则检测到payload的第20位为止。disiarice指定从payload后面算起的偏移量。nocase指定是否忽略关键字的大小写,指定为true时表示忽略大小写,false则表示不忽略大小写。msg指定当规则匹配时.iDS返回的警报信息。
我们的检测规则使用XML表示,因此在程序要使用相应的方法来识别和读取XML内容。我们使用CMARKUP类来对定义规则的XML文件进行操作,具体的使用方法在Http://www.firstoblectcom/dn_rnarkup.htm中有详细的介绍,由于这不是本IDS设计的重点,就不再赘述了。iDS程序在开始检测时,先要把规则读入程序中,所以在程序里也要有相应的结构来存放规则信息,检测规则的结构在程序中表示如下。
其中"ContentRule content[100].用于存放content子规则信息,它是个结构数组,定义如下。
我们定义一个规则结构数组“Rulerules[1000]”,初始化1000条规则,使用loadrule( rule*rules)函数把XML规则读A规则结构数组中。读入规则后.IDS进入数据包检测状态。数据包分析和检测的实现基于模式匹配的iDS的工作原理是把数据包各数据段和规则定义互相比较以匹配规则。在程序里面的具体实现就是把捕获到temp的内容和读取到rule中的内容进行匹配比较。我们在函数checkdatagram中实现该过程。
因为我们的检测面对TCP和UDP两种数据包,所以在checkdatagram中按TCP和UDP两种情况进行分析。对送入checkdatagram中的数据包先检查其proto位,然后根据其值为IPPROTO_TCP和lPPROTO_UDP分两个过程对数据包和规则进行匹配,这也达到了简单协议分析的目的。
程序将temp包含的lP报头各数据位和rule定义容进行比较.然后根据数据包的类型将temp包含的TCP报头或者UDP报头各数据位和rule定义内容进行比较,这个过程是比较显式的,只是一个数值比较过程。最后,程序根据content子规则的定义在数据包的payload中搜寻攻击关键字,这也是实现IDS功能中的关键步。
寻找数据包中的关键字的过程实际上是一个在数据包中寻找子串的过程。slrstr函数是标准库中在字符串中寻找子串的函数。数据包的内容是一个字节串,所以它可能包含”0 0“的字符。这个字符在一般的字符串中是用来做字符串结束的标记的。如果串中含有这个字符.那么在字符串处理函数中会把这个串截断,因此,我们不能使用c++的标准字符串操作函数strstr来实现我们的功能。memcmp是一个标准库函数.它的功能是把两个字节串,包括“0 0”的内容进行比较匹配。我们通过这个函数来对strstr函数进行改写,实现一个在字节串中寻找子串的函数memmem。该函数的具体实现如下。
特定的攻击数据包的payload内容具有一定的特征,如果IDS能够把这些特征精确地定位出来,那么就可以发现网络中的攻击行为。Payload检测功能在heckdatagram中用子函数checkpayload实现。它根据contenl子规则定义的各种条件使用memmem函数在数据包字节串中进行关键字搜索。搜索条件包括大小写、检测深度、偏移量等,它能比较好地描述攻击数据包特征.使精确定位攻击数据包成为可能,减少了DS对攻击事件的误报率并且,大小写、检测深度、偏移量等搜索条件也很好地降低了IDS的运算量,提高了检测效率。比如我们检测一个灰鸽子上线发出来的数据包,该包在payload偏移为0的地方有长度为4的关键字hgz5.那么可以用rriemmem函数寻找该关键字,如下所示:
该函数返回值不为空,则表明在该数据包的payload找到了灰鸽子数据包的攻击特征.IDS就定位了一次灰鸽子木马事件,检测出网络中有灰鸽子木马的活动踪迹。
数据包检测分析过程是我们的IDS发现安全事件的关键过程,也是模式匹配IDS设计的原理所在,它承载了IDS的大部分运算量,其好坏直接影响着IDS的性能,所以在些大型商业的IDS中,这个过程一般由汇编语言或者硬件实现。由于我们的IDS只做简单的实现,只把它应用于较为简单的网络环境,算法速度和效率的要求比较低。所以这里不对它进行进一步的研究和探讨。
安全事件报警和记录的实现
当IDS检测到安全事件的发生时,应该有报警并记录事件的机制,以便我们对发生的安全事件进行了解和查询。我们使用c++的标准输入输出来达到我们的目的。程序检测到一个数据包和检测规则完全匹配后会做出响应,使用标准输出把对事件的警报在程序控制台上显示出来。警报的内容包括事件发生时间、源P.目的jp、事件具体信息等。事件具体信息也就是匹配规则中的msg元素内容。程序显示警报的同时,我们还需要它把该警报写入一个文本文件alert.txt中记录该事件,作为iDS的安全事件日志.起到一个简单的安全事件数据库的目的。
功能测试
程序在编译通过后会产生3个文件主程序、rule.xml、alert.txt。为了测试程序的功能.我们把一些Snort的规则翻译过来写入rule.xrn。把程序复制到一台windows主机上,双击启动主程序,就可以对经过本机网卡的流量进行检测了,如图2所示。
我们可以看到程序载入了199条检测规则。并开始对本机IP为192.168.1 88.163的网卡流量进行检测。我们在网络中制造些攻击流量,在1 92.168.188.1 63向外发送灰鸽子攻击数据包,可以看到IDS的报警,如图3所示。
通过它,我们能比较直观地了解网络中发生的安全事件.定位事件发生的源头.方便我们对安全事件进行处理和解决。在测试过程中,发现它在100M流量的网络中能够比较稳定地工作,达到了预期的设计目标。
总结
本文以提出并解决问题为目的,从程序设计的角度对1DS的设计原理进行了说明,简单地实现了一个轻量级的IDS。代码做得比较乱.读者可以根据自己的喜好对程序进行修改和加强。
本文内容所提及均为本地测试或经过目标授权同意,旨在提供教育和研究信息,内容已去除关键敏感信息和代码,以防止被恶意利用。文章内提及的漏洞均已修复,作者不鼓励或支持任何形式的非法行为。