snort源代码情形分析
Snort 系统是一个开放源代码的网络入侵检测系统,最初由Martin Roesch 编写。分析snort源码不仅可以让我们对入侵检测的具体实现有深刻的理解,也可以让我们学习到软件设计的一些思想,特别是它的体系结构非常的模块化,源码布局也遵循相应的标准,很容易理解。
在这里,通过对一个个具体的情形来分析snort的源码,这样更容易理解,特别是各个函数间的关系,我们试图对snort的总体结构作全面的剖析,对于具体的源代码中的语句和库函数的调用,我们会放在附录中详细讲解,这样不至于让读者淹没在复杂的细节中
本 文写作目的有两个:一是面向有志于研究入侵检测的专业人员,通过阅读源代码,可以构建出自己的入侵检测系统框架,方便研究后续的检测算法,做验证比较实验 等;二是面向程序设计爱好者,特别是对网络数据包的分析和处理感兴趣的读者,通过阅读源码,可以借鉴其中的编程规范,模块化设计,插件思想等,也可以培养 自己的阅读源代码的能力。
本文有以下几部分组成:
1. snort基本框架
2. snort初始化情形分析
3. 获取一个数据包后预处理和检测情形分析
4. 附录 一 源码中库函数和具体函数详解
5. 附录 二 设计自己的检测算法
******************************************************************************
声明:
本文件可以自由传播,不经作者同意不得用于任何商业活动
由于本人水平有限,恳请大家不吝赐教,任何批评建议和意见都是给我工作的莫大鼓励
注:没有把本文写完,一来是自己时间有限,而且水平有限。二来是希望得到读者的批评和建议以对以后的写作有所改进。本文所要达到的目的:熟悉snort ,可以根据自己的需求设置自己的snort框架,可以方便的添加不同的算法引擎以验证算法的优劣,也就是建立所谓的test bed。由于是针对做研究实验用的,没有太多的商业价值。最后由于snort具有很好的编程风格,笔者想通过这一途径学习期优秀的编程方法
个人简历:
He Jialang Male 1984.8
nanjing university of science & technology (NJUST)
working for Ph.d at information security / IDS in Ad hoc network
studying in IDS Ad hoc network/snort implementation/ FreeBSD OS implementation /
related works : Date Mining / WaveLet / IA / statistics of random processes
email/MSN : jialanghe@hotmail.com or hejialang@gmail.com
一 snort基本框架
Snort包括主控模块(snort.c),包捕获模块,包解码模块(decode.c),规则处理模块(rule.c), 预处理模块(spp_*.c),处理模块(sp_ *.c), 输出模块。
主控模块实现模块和全局变量的初始化,通过读取命令行参数进行一些设置。然后调用包捕获函数,之后进行解码,处理,匹配等操作。下面是snort运行的流程:
二 snort初始化情形分析
下面就从程序的入口分析,具体说明程序如何完成初始化的。
在说明初始化过程之前,我们要明确什么是需要初始化的。
1. 要初始化snort运行的模式,pass、log、or alert。
2. 要确定网络的链路
3. 要形成规则树用于匹配
4. 要设定好响应模式
下面具体看一些初始化:
我们从main.c(snort.c)开始。(请对照源码看)
开始是初始化信号处理,子网掩码,抓包数量(/* initialize the packet counter to loop forever */ pv.pkt_cnt = -1;)等。接下来调用的是处理命令行参数,根据用户输入的命令行参数具体初始化 --------ParseCmdLine(argc, argv);----------- 该函数解析命令行参数,然后设置全局变量pv,这个函数十分的简单,大家可以看看源代码
然后打开raw socket : libnet_open_raw_sock(IPPROTO_RAW) 其中 IPPROTO_RAW意味着 IP_HDRINCL 处于激活状态,也意味着接收所有 IP 协议. 这个可以不管,只要知道这个就是打开接受IP包的开关就好了。
接下来是通过对pv.readmode_flag的判断决定是从网络接口还是从文件接受数据包,具体表现为 语句 /* open up our libpcap packet capture interface */ OpenPcap(pv.interface); 和语句 OpenPcap(pv.readfile); (二者通过if语句选其一)。
然后/*创建一个保存进程标识等相关信息的文件*/ CreatePidFile(pv.interface); 接下来做一些相关目录检查,是否记录日志,是否进入daemon模式 等。
SetPktProcessor();设置端口的解码函数,然后如果应用规则(if (pv.use_rules) ) 就安装相关插件 InitPreprocessors(); 安装预处理插件
InitPlugIns(); 安处理插件
InitOutputPlugins(); 安装输出插件
通过ParseRulesFile 处理规则文件,然后是加入相关log ,alert的处理函数(通过AddFuncToOutputList 函数加入)。
呵呵,到这里初始化工作就结束了。
接下来就是 pcap_loop(pd, pv.pkt_cnt, (pcap_handler)ProcessPacket, NULL) 捕获并处理数据包了, ProcessPacket就是处理数据包的回调函数。所有的检测过程都是在这个函数中完成的。首先ProcessPacket调用解码和预处理函数,然后调用规则检测函数Detect(),然后通过规则树查找函数找到相应的规则列表,规则头匹配,规则选项匹配,产生告警,记录日志….
精彩内容,请带下回分解
三 获取一个数据包后预处理和检测情形分析