5、Linux下的实现
5.1 系统框架
HereLine是一个在Linux下运行的基于标识检测的网络IDS。从逻辑上分为数据采集、数据分析和结果显示三部分,符合CIDF的规范。
从实现结构上看,HereLine分成三个应用程序,它们分别是:
1、数据收集及分析程序(watcher) ;
2、告警信息收集程序(listener);
3、告警信息显示程序(console)。watcher是数据采集和数据分析的合体;listener接收watcher发出的告警信息,并将接到的信息存储为日志;console为管理员提供了更友好的观察日志的图形界面。
同大多数商业IDS一样,HereLine采用了分布式的结构。运行HereLine建议采用两台PC机,一台运行watcher,另一台运行listener和console.
与其他同类程序相比,HereLine的优点主要有:
1、提供了完整的框架,可以灵活的应用于各种环境并扩充;
2、采用数据分析与告警程序分离,便于在大规模的网络环境下集中管理;
3、已经实现了对分片的处理,解决了利用分片逃避检查的问题;
4、数据分析部分不完全依赖已有攻击程序,而是分析其核心特征以察觉其变种攻击;但同时依靠已有攻击程序的细节来评估判别的准确性。以上设计增加了告警的可靠性。
各部分的实现流程及重要问题说明
5.1.1 数据采集部分
watcher采用了Linux2.2内核中提供的PF_PACKET类型的socket(并未采用libpcap提供的API接口) ,直接从链路层获取数据帧。(直接采用操作系统提供的接口主要是考虑高效性,但为了将来的移植问题,以后仍然可能会改为使用libpcap库提供的函数接口。)根据Linux的要求,建立这样的一个socket需要root权限,即uid=0。从packet socket读到的数据是链路层格式的数据,但经过处理(socket函数的第二个参量SOCK_DGRAM表示要去掉第二层的数据头,第三个参量ETH_P_IP表示只接收ipv4的数据包)后,缓冲区内的内容是个完整的IP包(未经任何其它处理)。分析工作交由数据分析程序去做。
数据采集部分还做了一项工作就是将网卡置于混杂模式,这样可以监听到整个网段的数据。
HereLine的这种实现,实际是通过socket将数据拷贝到应用层。这种结构比较灵活与安全(应用程序崩溃不会导致系统崩溃),但频繁的应用态与核心态的转换浪费了CPU。还有一种办法就是采用Linux中的模组(modular)的办法,将IDS作为内核的一部分。《Building Into The Linux Network Layer 》提供了一个内核中的sniffer的框架。可以利用其结构实现嵌入内核的、更加高效的入侵检测系统。HereLine可以很容易的转移到这种方式,但考虑到其对操作系统稳定性的影响和调试的难度,目前未采用。
需要指出的是,watcher只是监听数据包,并不参与操作系统协议栈的处理。如果操作系统被攻击导致拒绝服务,watcher也将无法运行。因此,首先要保证起所运行的系统是安全的。有些商业入侵检测系统(如NFR)将数据采集部分放在专门的、经过改进的、高度安全的系统之上,以保证IDS这一系统中的重要程序正常工作。对于HereLine本身来说,建议采用增加了stackguard功能的gcc编译器,减少潜在的缓冲区溢出(buffer overflow)漏洞。
watcher将数据读到缓冲区之后,首先将其封装为sbuff结构,当数据在程序中传递时,均采用此结构。其定义为:
struct sbuff
{
union{
struct tcphdr *tcph;
struct udphdr *udph;
struct icmphdr *icmph;
struct igmphdr *igmph;
} h;
union{
struct iphdr *iph;
} nh;
unsigned char *data;
} ;
sbuff中定义了指向协议头的指针,子程序可根据这些指针快速的定位数据头位置。
5.1.2 数据分析
数据分析部分事实上与数据采集部分作为一个进程(watcher)存在,主要是为了简化程序设计的复杂性。在得到数据帧之后,watcher模拟操作系统的TCP/IP堆栈对数据进行处理并与已知攻击行为的特征进行比较,从中发现异常行为,并向控制台告警。
在分析的过程中,首先对数据包进行协议分析、过滤,根据协议、端口等信息将数据包送到不同的检测流程(如只有HTTP协议的包才进行CGI检查),这样使检查的过程尽量缩短,提高了程序的工作效率。当进入相应的检测流程后,则按照线性的顺序工作。
数据分析部分设计为模拟TCP/IP堆栈的流程处理数据包,从中发现异常行为(如分片重合、异常标志等)。这样主要是为了减少误报与漏报,从攻击的核心特征发现它,而不是象许多其他系统那样,只检查攻击包的表面特征。HereLine中包括了IP分片处理,包括了TCP状态转换。通过这种结构,可以准确的判别诸如teardrop等碎片攻击的各种变种。
对一些常见攻击手法的描述和处理方法见附录1。
HereLine目前可以处理以下攻击:
1) land
2) winnuke
3) ping of death
4) source routing
5) 若干种CGI攻击
6) 各种OS detection
7) 各种类型的端口扫描
8) syn flood
9) smurf
10) teardrop及其所有变种
11) jolt
若识别出有异常行为,则向控制台告警(采用类似IAP的协议)。HereLine此时分出一个单独的进程处理与控制台的交互,而原进程则继续处理新的数据包。
5.1.3 控制台
控制台部分分为两个程序,listener和console。 listener绑定6543端口(目前似乎没有和其他程序冲突),接收从分析程序发出的分析结果和其他信息,并根据其类型转化到不同文件存储。此时的文件为用户可读。其实watcher和listener两者便已经形成了一个完整的IDS。
console为一用GTK+图形库编制的一个窗口程序,目的主要是给用户一个更方便友好的界面来浏览警告信息。
因为listener已经将报警信息以明文格式存储,因此也可以采用将其转换成HTML文件,用浏览器查看。当然也可以采用windows应用程序。因HereLine不是一个商业软件,对界面的考虑并不多。
HereLine的日志采用了类似UNIX系统日志的格式,包括time(事件发生时间),host(被攻击的主机名或IP),watcher(发现此攻击的watcher的名字或IP),event(攻击的具体描述)这些项。各项之间用空格分开,每个记录用一行,每项之中不能有空格,若有,用下划线代替(以上语法约定均是为了方便处理)。下面是一个例子:
Feb_27_20:30:31 172.18.172.18 watcher01 Port_Scan_From_evil.com
Feb_27_20:31:07 web_server watcher02 OS_fingerprint_from_12.18.1.1
在设计日志格式时我曾经考虑过许多方案,主要是想分出更多的项,如记录两端的端口信息,加入可信度和计数,这样在以后可以很方便的排序和查找,但最终还是采用了这种简单的格式。其原因主要是各种不同的事件需要记录的项千差万别,唯一又共性的便是time,host,watcher这三项,其余之处可都放到event项中去说明。我可以举一个例子:攻击的源地址似乎应该单列出来,但是现在假冒源地址进行的攻击实在太普遍了,land攻击便将源地址设为与被攻击者相同,此时记录源地址没有任何意义;syn flood往往随机的生成源地址,如果因源地址不同而单列出一个记录的话,只会使日志迅速膨胀,而其记录的内容与只简单记录发生了syn flood没有多大区别。
设计日志时还有一大问题便是连续不断的相同攻击会产生大量相同的日志,HereLine对此采取的办法也与UNIX的syslogd相同:设立一专门的计数器count,每当有新的事件出现的时候先比较是否与上一事件重名,若不重名则马上记录(保证报警的迅速),否则对计数器加一,直到有不重名的事件发生才真正写日志,此时记录的event项的内容为:
The_last_messages_repeated_$count_times
除生成日志告警外,系统不采取任何其他行动,是否采取相应的措施由系统管理员自行决定。
由于时间关系,程序完成的不是很完善,有很多跟理想的有一些差别:
(1)无法灵活的升级:所有的入侵检测部分都以编译后的程序的形式提供(可以高效处理,但同时失去了灵活性)用户必须完全或部分更新原有程序才能实现升级。以后应该采用类似脚本语言的办法。
(2)所处理的攻击数还需有很大的提高。
(3)控制台程序尚没有加入对采集分析程序的控制,也没有加入对分析结果作进一步处理的功能(如排序、过滤、查找等)。
(4)磁盘定额:对日志过大以后的情况尚没有人为规定,不过目前可以用Linux自身的quato功能实现(写满一定磁盘定额后覆盖)。
(5)集中控制:控制台应该加入配置watcher的功能(如暂停其某项检测)。
(6)无法动态的载入和卸载检测规则。(很快会加入)
(7)未采用IAP:现在watcher与listener的通信仍采用明文传输,这种局面急需改变。但IAP设计的过于复杂,且是否会成为标准尚不明朗,所以暂时可能先设计一个简单点的协议来实现加密和验证。
IDS系统面临的一个矛盾便是性能与功能的折衷。对数据进行全面复杂的检验,对实时性的要求构成了很大的挑战。
由于仅仅进行了开发,没有对HereLine进行性能测试,对HereLine而言,其可能影响性能的有三个地方:内核到应用层的转换(涉及数据拷贝);数据分析(大量的数据匹配操作);记录日志(IO操作)。