3.4.2 预处理模块 入侵检测系统在初始化完成之后,在进入检测引擎模块(处理前面两个模块传过来的网络封包)之前,需要对数据包进行预处理。这次IDS的插件结构允许开发者扩展入侵检测系统的功能。另外,循环抓包是在snort.c 主流程的InterfaceThread函数中实现,该函数调用libpcap 库中的pcap_loop循环抓包函数,这个函数有个回调函数ProcessPacket,这个回调函数先通过上一个包解码模块得到的相应的解码函数对抓到的数据包进行解码(实现语句是: (*grinder) (&p, pkthdr, pkt); ),下一步判断snort.c 文件中的runMode全局遍变量,若 SNORT工作在包记录模式,则调用输出插件CallLogPlugins函数;否则工作在IDS模式,继而进入预处理Preprocess函数。 paper51.com 该预处理函数遍历在初始化预处理插件后得到的PreprocessKeywordList链表,调用配置文件中要求的预处理插件函数对所抓的数据包进行预处理。函数实现如下: 内容来自论文无忧网 www.paper51.com paper51.com idx = PreprocessList; copyright paper51.com while(idx != NULL) paper51.com { 内容来自www.paper51.com
assert(idx->func !=NULL); copyright paper51.com idx->func(p); 内容来自www.paper51.com idx = idx->next; 内容来自论文无忧网 www.paper51.com } paper51.com 预处理器在调用检测引擎之前,在数据包被解码之后运行。通过这种机制,snort可以以一种out of band的方式对数据包进行修改或者分析。以下是几个常用的预处理插件: copyright paper51.com (1)HTTP解码预处理模块用来处理HTTPURI字符串,把它们转换为清晰的ASCII字符串。这样就可以对抗evasice web URL扫描程序和能够避开字符串内容分析的恶意攻击者。 内容来自www.paper51.com
(2)frag2模块 :使snort能够消除IP碎片包,给黑客使用IP碎片包绕过系统的检测增加了难度。 paper51.com
(3)stream4插件为snort提供了TCP数据包重组的功能。在配置的端口上,stream4插件能够对TCP数据包的细小片段进行重组成为完整的TCP数据包,然后snort可以对其可疑行为进行检查。 http://www.paper51.com (4)Portscan预处理程序的用处: 向标准记录设备中记录从一个源IP地址来的端口扫描的开始和结束。端口扫描可以是对任意IP地址的多个端口,也可以是对多个IP地址的同一端口进行。可以处理分布式的端口扫描(多对一或多对多)。端口扫描也包括单一的秘密扫描(stealth scan)数据包,比如NULL,FIN,SYNFIN,XMAS等。 copyright paper51.com (5)Portscan2模块将检测端口扫描。它要求包含Conversation预处理器以便判定一个会话是什么时间开始的。它的目的是能够检测快速扫描,例如,快速的nmap扫描。 内容来自www.paper51.com (6)Conversation 预处理器使Snort能够得到关于协议的基本的会话状态而不仅仅是由spp_stream4处理的TCP状态。当它接收到一个网络不允许的协议的数据包时,它也能生一个报警信息。要做到这一点,请在IP协议列表中设置你允许的IP协议,并且当它收到一个不允许的数据包时,它将报警并记录这个数据包。 paper51.com (7)Http Flow模块可以忽略HTTP头后面的HTTP服务响应。 内容来自论文无忧网 www.paper51.com
3.5 检测模块 内容来自论文无忧网 www.paper51.com 这次设计的IDS的检测模块设计特点是其在初始规则链表的基础上,重新构造了一套快速匹配的数据结构,并采用了多模式匹配搜索引擎,可使用户根据具体情况选择不同的匹配模式。大体上按其功能可分三个步骤: copyright paper51.com (1)构造初始的规则链表结构,将用户自定义的规则导入到规则链表结构中。这部分功能由ParseRule函数实现。 内容来自www.paper51.com (2)读入规则链表各节点,并构造用快速匹配的新的数据结构,这是在初始化各个插件和建立三维链表之后,在调用处理模块函数InterfaceThread之前完成的。它是由fpcreate.c文件中的fpCreateFastPacketDetection函数完成的。 copyright paper51.com (3)对当前数据包执行具体的快速规则匹配任务,该功能主要在fpEvalPacket()上实现。 http://www.paper51.com 由于这个模块的数据结构比较复杂,所以对于上面的3个步骤,其中第1、2个需要进行说明。 paper51.com 3.5.1 三维链表 内容来自www.paper51.com 在处理规则文件后,这次设计的IDS仿照snort使用一个三维链表来存储信息。以便和所抓的封包进行数据查找匹配,借次来判断所抓的数据包是安全的还是危险的。 paper51.com 三维链表的关系如图所示: 内容来自www.paper51.com
内容来自www.paper51.com
next 内容来自www.paper51.com
RuleLists copyright paper51.com RulelistNode RulelistNode RulelistNode copyright paper51.com
http://www.paper51.com
copyright paper51.com 图6 snort的三维链表 内容来自论文无忧网 www.paper51.com RuleList是parser.c文件中的一个全局变量。该指针是一串RuleListNode结构的头指针。每个RuleListNode结构中都有一个指向ListHead结构的指针。每个ListHead结构又包括四个RuleTreeNode结构(IpList/TcpList/UdpList/IcmpList)的指针和两个_OutputFuncNode结构(LogList/AlertList)的指针。LogList/AlertList是OutputFuncNode结构链表的头指针,是在plugbase.c文件中AddFuncToOutputList函数实现的。该函数被初始化输出插件函数InitOutputPlugins调用。这两个链表被用于SNORT调用输出插件输出信息(记录日志或报警)。 paper51.com 四个RuleTreeNode结构的头指针如图所示: http://www.paper51.com Rtn_tmp http://www.paper51.com
paper51.com
copyright paper51.com
…… copyright paper51.com 图7 RuleTreeNode结构的头指针 copyright paper51.com 以上就是三维链表结构,这是由parse.c文件中的ParseRule函数(调用ProcessHeadNode函数和ParseRuleOptions函数)实现的。 内容来自论文无忧网 www.paper51.com 3.5.2 ParseRule初始化函数 http://www.paper51.com ParseRule函数对配置文件的每一行(从ParseRuleFile 函数传过来)进行解析。可以分成两大部分解析:规则头和规则体。举例来说: paper51.com alert tcp any 1234 -> 192.168.1.0/24 80 (content:”|00 01 86 a5|”; msg:”mountd access” 内容来自www.paper51.com
规则头包括:规则动作(alert/log/pass/activate/dynamic),协议(tcp),源地址(any),源端口(1234),方向操作符(“->”),目的地址(192.168.1.0/24),目的端口(80)。规则选项组成了snort入侵检测引擎的核心,既易用又强大还灵活。snort中有42个规则选项关键字,如msg/logto/ipoption/content/classtype等,要提请注意的是选项content、content-list和uricontent,它们允许用户设置规则在包的净荷中搜索指定的内容并根据内容触发响应。当进行content选项模式匹配时,Boyer-Moore模式匹配函数被调用,并且对包的内容进行检查(很花费计算能力)。如果包的净荷中包含的数据确切地匹配了参数的内容,这个检查成功并且该规则选项的其他部分被执行。这就是模式匹配(基于特征的规则匹配),也是检测模块的重点。 copyright paper51.com 下面是对ParseRule源码的一些说明: 内容来自论文无忧网 www.paper51.com
void ParseRule(FILE*rule_file, char *prule, int inclevel) copyright paper51.com
{ 内容来自论文无忧网 www.paper51.com toks = mSplit(rule, "", 10, &num_toks, 0); copyright paper51.com /* toks[0]对应于配置文件每一行的第一个关键字,可分为四类: */ 内容来自论文无忧网 www.paper51.com /* 第一类:alert/log/pass/activate/dynamic (这由include语句引入) */ copyright paper51.com
/* 第二类:preprocessor/output 分别对应预处理插件和输出插件,举例 */ 内容来自www.paper51.com
/* 如:output database: log, mysql, user=root dbname=db host=localhost */ 内容来自www.paper51.com
/* 第三类:设置网络参数如:var ORACLE_PORTS 1521 */ copyright paper51.com /* 第四类:配置和命令行选项参数 如:config logdir:/var/log/snort */ 内容来自www.paper51.com /* 第五类:自定义规则集,RULE_DECLARE/RULE_UNKNOW */ http://www.paper51.com rule_type =RuleType(toks[0]); copyright paper51.com switch(rule_type) 内容来自论文无忧网 www.paper51.com
{ 内容来自www.paper51.com
/* 先处理规则头 */ 内容来自论文无忧网 www.paper51.com /* 以下五条语句ProcessHeadNode形成三维链表的表头 */ 内容来自www.paper51.com caseRULE_ALERT: 内容来自论文无忧网 www.paper51.com ProcessHeadNode(&proto_node, &Alert, protocol); paper51.com caseRULE_LOG: 内容来自论文无忧网 www.paper51.com ProcessHeadNode(&proto_node, &Log, protocol); copyright paper51.com caseRULE_PASS: 内容来自www.paper51.com ProcessHeadNode(&proto_node, &Pass, protocol); http://www.paper51.com
caseRULE_ACTIVATE: 内容来自www.paper51.com ProcessHeadNode(&proto_node, &Activation, protocol); 内容来自www.paper51.com
caseRULE_DYNAMIC: paper51.com ProcessHeadNode(&proto_node, &Dynamic, protocol); 内容来自www.paper51.com caseRULE_PREPROCESS: ParsePreprocessor(rule); //处理预处理插件 内容来自www.paper51.com caseRULE_OUTPUT: ParseOutputPlugin(rule); //处理输出插件 内容来自www.paper51.com
/* 以下的parse函数源码 */ 内容来自论文无忧网 www.paper51.com case RULE_CONFIG: ParseConfig(rule); copyright paper51.com case RULE_DECLARE: ParseRuleTypeDeclaration(rule_file, rule); http://www.paper51.com
case RULE_INCLUDE:ParseRulesFile(tmp, inclevel + 1); 内容来自论文无忧网 www.paper51.com case RULE_VAR:VarDefine(toks[1], toks[2]); copyright paper51.com case RULE_UNKNOWN:ParseDeclaredRuleType(rule); copyright paper51.com } 内容来自www.paper51.com ProcessIP(); //解析地址 http://www.paper51.com ParseProt(); //解析端口 paper51.com strcmp("->", toks[4]) &&!strcmp("<>", toks[4]); //解析方向 copyright paper51.com /* 再处理规则选项*/ 内容来自论文无忧网 www.paper51.com
ParseRuleOptions(rule, rule_type, protocol); http://www.paper51.com
} paper51.com 上面用到的ProcessHeadNode函数的第二个参数是Alert/Log/Pass/Activation/Dynamic是parser.c文件中定义的五个ListHead全局指针(分别对应五个规则动作),它们都包含RuleTreeNode结构的四个链表IpList/TcpList/UdpList/IcmpList,RTN链表这是三维链表的第一维。ProcessHeadNode函数遍历RTN表头(如:Alert->IpList ),调用SetupRTNFuncList函数初始化RTN链表,该函数是通过调用不同参数的AddRuleFuncToList函数来实现的,最后得到规则函数指针链表,表头是RTN->RuleFpList类型。这是三维链表的第三维之一。 内容来自论文无忧网 www.paper51.com |