基于ARM的嵌入式蠕虫检测系统设计与实现*
2013-07-20鲍娟,刘娜,魏刚
鲍 娟,刘 娜,魏 刚
(1.湖北医药学院计算机教研室,十堰 442000;2.湖北医药学院附属人民医院,十堰 442000)
1 引言
随着互联网应用的普及和深入,计算机病毒、木马程序、网络蠕虫等恶意程序,对计算机系统和网络的安全威胁日益增加。与传统病毒不同,蠕虫病毒以计算机为载体,以网络为攻击对象。在扫描漏洞主机的过程中,蠕虫病毒会产生巨大的网络流量,导致整个网络瘫痪,造成经济损失。
Linux 操作系统作为目前流行的开源操作系统,为许多硬软件产品的开发提供了良好的平台。开发者可对内核进行裁减和修改,定制最适合的操作系统平台。文中结合嵌入式设备成本低、体积小的特点,提出了一种适合移植到嵌入式系统上的蠕虫病毒检测方法。
2 蠕虫检测技术分析
蠕虫检测可以分为误用检测和异常检测[1]。目前较常用的蠕虫检测方法是误用检测,通过蠕虫代码特征来检测蠕虫的存在。该方法只能在蠕虫爆发后,通过对相应蠕虫进行分析得到检测特征,但是无法检测未知蠕虫,无法实现对蠕虫的有效防范。
另一蠕虫检测方法是异常检测,通过检测主机的异常行为或者流量的异常模式来确定蠕虫的存在。
文献[2]提出通过判断失败连接数是否达到阈值来检测远程蠕虫。通常该阈值的选择是比较困难的:过低则提高误报率,过高则提高漏报率。
目前,主流的开源检测系统包括Snort 和Bro[3]。
Snort是轻量级的入侵检测系统,通过用户态的Libpcap,从内核中获取数据包。但数据包流量较大时,大量的数据包就会被丢弃,从而导致Snort 系统的效率大大降低。
Bro 也是通过Libpcap 库来获取网络数据包,Libpcap 包捕获机制的原理是在数据链路层增加一个旁路处理,通过系统调用把数据包从内核空间传入到用户空间再进行分析处理[4],这增加了内存拷贝次数,影响系统捕包的性能。因此如何减少内存拷贝次数及系统调用、能快速的检测是关键所在。
为了减少内存拷贝及系统调用时间,降低用户态存储空间的需求。文中设计实现了一个基于Linux 内核、Netfilter 框架的内核流量采集和分析模块,并且同时能够进行内网的蠕虫检测,通过动态加载功能模块的方式,运行在Linux 内核空间,所有的包截获分析、蠕虫检测等任务都是在内核空间完成,因此比起其他的运行在用户空间的网络监控应用程序,该模块大大降低了从内核空间到用户空间的内存拷贝操作,因此极大地提高了位于内网的检测系统的整体性能。
3 系统设计
3.1 基于Netfilter 框架的流量采集模块
在混杂模式下,利用Netfilter 框架,当数据包被传递到Hook 中时便开始进行采集。Hook 函数接收到的数据有:skbuff 结构、网络设备的数据结构指针。skbuff 中包括了链路层、网络层及传输层包头,通过分析这些包头信息可以得到该数据包的源地址、目的地址和协议类型,Netfilter 通过Hook 函数的返回值决定该包的去向。文中选择PRE_ROUTING和POST_ROUTING参考点注册回调函数,并设置其优先级最高,并以NF_ACCEPT为返回值告诉Netfilter,即到目前为止该数据包一直被接收。
3.2 基于主机级别的蠕虫检测模块
蠕虫主机流量主要由FCC(第一次连接)流量组成。而这些连接请求大多数是不能成功的,或者没有应答,或者被拒绝(RST 包)。根据实验分析,网络蠕虫连接请求失败的概率在80%左右。根据蠕虫检测算法,设计了蠕虫检测模块。该模块的基本流程图如图1 所示。
当某台主机判断为失败连接时,先计算该主机发起的FCC 数是否到达给定阈值NCE,若达到了阈值,再判断这台主机的FCC 失败连接比率是否达到给定阈值。若真,则该主机被判断为蠕虫;否则,考察该主机的FCC是否具有正常主机的重尾分布特性。若真,则该主机被认为是正常主机,反之,该主机被认为是蠕虫。
图1 蠕虫检测流程图
4 系统实现
将设计和实现的蠕虫检测系统移植到ARM 开发板上,在搭建的内网环境中运行,用来进行本地局域网的蠕虫检测。嵌入式实现的原因如下:
(1)前面提到的系统是在PC 机上SUSE 10.3(Linux2.6 内核)运行实现的,内核比较庞大,但是通过内核的裁剪和重编译,可以在ARM 开发板上运行,以解决资源问题。
(2)移植到开发板上以后,开发板的网口可以直接连到交换机上,监测局域网的流量异常情况,携带方便,占用空间更小。
4.1 系统硬件平台
本系统的开发板是EP9315(Cirrus Logic 公司出品)处理器,基于ARM920T 内核,内带MMU,16KB的指令 cache,16KB的数据 cache 和 Maverick Crunch。主频200MHz,系统总线100MHz,可提供工业级;两片Flash 共32MBNorFlash,64MB SDRAM。
4.2 嵌入式linux 系统的软件平台构建
嵌入式Linux 系统的构建主要分为五个步骤[5]:①交叉编译环境的建立;②引导程序Bootloader的开发;③Linux 内核的开发;④根文件系统的定制;⑤文件烧写。
下面主要介绍Linux 内核编译、制作根文件系统和文件烧写。
4.2.1 嵌入式Linux 内核编译
内核配置完后进行Linux 内核编译。
(1)执行如下指令,删除过时的文件#make clean
(2)执行如下指令,生成可执行内核映像文件#make zImage
执行完后,会在arch/arm/boot/下生成一个内核映像文件vmlinux。
嵌入式内核编译的不同之处在于之后还要将vmlinux 转换成可以下载到嵌入式系统板上运行的内核映像vmlinux.gz.img。
4.2.2 根文件系统
对于一个实际的嵌入式应用系统来说,仅包含Linux 内核是不够的,还必须有文件系统的支持。在嵌入式Linux 内核启动后,需要加载根文件系统,以支持系统与用户交互。下面描述如何制作根文件系统[6]。
对于嵌入式Linux 来说,最简单最常用的根文件系统是RAMDISK。RAMDISK是指使用系统的一部分内存空间来模拟一个用户熟悉的磁盘分区。
(1)从开发系统提供商获得一个RAMDISK,复制压缩文件ramdisk.gz 到工作目录/home/work。
解压该文件,#gzip-d ramdisk.gz
(2)将文件RAMDIAK 挂载到一个临时目录,如ram_disk,执行如下命令:
之后用户可以查看文件ramdisk 包含的所有子文件系统内容。
(3)根据需求对文件进行增减,操作完毕后卸载目录ram_disk 与文件RAMDISK的连接。并对新的RAMDISK 文件进行压缩。执行如下命令:
此时,有了嵌入式Linux 内核和根文件系统,一个完整的嵌入式Linux 系统就编译完成了。下面将生成的内核映像文件vmlinux.gz.img 和ramdisk.gz.img 下载到系统的FLASH 中,就形成了一个完整的嵌入式系统。
4.2.3 文件烧写
一般情况,目标机上的Bootloader 通过串口与主机之间进行文件传输,但是,串口传输的速度是有限的,因此通过以太网连接并借助TFTP 协议来下载文件是个更好的选择。
通过以下命令将u-boot.bin,vmlinux.gz.img,ramdisk.gz.img 烧写到开发板上。
三个文件烧写到目标板上后,就可以运行用户自己的程序(交叉编译环境编译),例如在嵌入式Linux 内核态,动态加载检测局域网内的蠕虫主机模块。
内核模块的动态装载性使得内核映像的尺寸保持在最小,并且具有最大的灵活性,而且不需重新编译内核及重新引导。
4.3 内核与用户态的通信
在Linux 2.4 版以后的内核中,几乎全部的中断过程与用户态进程的通信都是使用Netlink 套接字实现的。Netlink 套接字的最大特点是对中断过程的支持,它在内核空间接收用户空间数据时,不再需要用户启动一个内核线程,而是通过另一个软中断调用用户事先指定的接收函数。使用软中断而不是内核线程来接收数据,这样就可以保证数据接收的实时性。
下面将阐述Linux 内核中Netlink 消息机制的实现,并且通过Netlink 消息通信机制,实现用户态与动态加载的内核模块之间的消息交互。
4.3.1 Netlink 通信机制
Netlink 用于在内核空间和用户空间之间传递信息,它提供了一种内核与用户的双向异步通信机制。它包括为用户进程设计的标准套接口和基于内核模块设计的内核API。内核与用户空间之间传递的消息保存在Socket 缓存队列中,发送消息只是把消息保存在接收者的Socket 接收队列,而不需要等待接收者收到消息,是一种全双工无阻塞通信方式。具体方法是在用户态下使用标准的Socket API,在内核空间使用特殊API 来实现。
那么内核是如何识别用户进程的呢?
以内核模块和用户进程之间单播通信为例。
内核模块向用户进程单播时,对目的用户进程的识别是以进程pid 作为依据的。因此在各自创建了套接字后,用户进程需要首先将自身的pid 发送给内核模块,内核模块(回调函数)保存此pid,供以后向用户进程发送数据时使用。
下面将从内核态和用户态两方面具体描述如何相互实现消息传递。
4.3.2 内核态工作
如图2 所示,运行在内核态的蠕虫检测模块实时监测内网的流量情况,若发现蠕虫病毒,将检测到的蠕虫机信息,传递到用户态,进行结果显示。
图2 内核与用户态的Netlink 通信
4.3.3 用户态工作
用户态使用标准的socket API:socket(),bind(),sendmsg(),recvmsg()和close()就能很容易地使用Netlink socket,与内核进行通信。
用户态主要实现两方面的功能:①发送数据到内核,即自身的进程pid 传给内核;②接收内核发送的数据并在用户态显示接收结果。
5 系统测试
5.1 搭建内网环境
(1)路由器上配置两个网段,分别是192.168.1.0 内网段和192.168.2.0 外网,测试网段192.168.1.0 到192.168.2.0 网段进行Web 页的访问(见图3)。
(2)内网段(192.168.1.0)分布:查看测试结果的PC 机(IP:192.168.1.101)、ARM 开发板、蠕虫主机(IP:192.168.1.102)和其它主机(IP:192.168.1.103)分别连接内网的交换机。
位于内网段的ARM 板,在192.168.1.0 网段内的交换机上端口进行了端口镜像。
(3)蠕虫主机上运行avserve2.exe,使得该主机感染振荡波蠕虫。
(4)外网段(192.168.2.1)分布:两台Web 服务器连接交换机,IP是:192.168.2.102、192.168.2.103。
图3 测试连接图
5.2 运行与测试结果
利用tftp,下载*.ko 文件和与之对应的用户态程序到ARM 板上。
在开发板的shell 下,先执行insmod *.ko 文件,启动该检测系统;再运行用户态程序,例如./user,创建Netlink 套接字与内核模块交互信息。加载模块、运行用户态程序如图4 所示。
内核态模块检测到内网的蠕虫机后,内核态传递蠕虫主机的源IP 地址到用户态,并使用打印函数输出信息到控制台,进行终端显示。内核检测结果和用户态接收到的结果如图5 所示。
图4 加载检测模块和用户态程序
图5 内核和用户态显示结果
6 结束语
创新点:蠕虫检测系统移植到ARM 开发板上,在搭建的内网环境中运行,进行蠕虫检测,并显示了测试结果。实验证明,系统进行相关的裁减和编译后,烧写到开发板上,捕捉内网的数据包,实现蠕虫流量检测。最后在嵌入式开发板上实现了内核态的蠕虫检测系统与用户态的消息交互。
[1]蒋建春,马恒太,任党恩,等.网络安全入侵检测:研究综述[J].软件学报,2000,11(11):1460-1466.
[2]Seth Robertson,Eric V.Siegel,Matt Miller,Salvatore J.Stolfo.Surveillance detection in high bandwidth environments[C].Proc.of DARPA DISCEX III Conference,2003:130-139.
[3]Bro intrusion detection system[EB/OL].http://bro-ids.org/.
[4]杨建华,谢高岗,李忠诚.基于Linux 内核的流量分析方法[J].计算机工程,2006,32(8):67-69.
[5]王亚军,刘金刚.Linux 运用于嵌入式系统的技术分析[J].计算机应用研究,2005,20(5):102-104.
[6]李驹光,郑耿,江泽明.嵌入式Linux 系统开发详解—基于EP93XX 系列ARM(第一版)[M].北京:清华大学出版社,2006.