suricata的主要功能就是将规则和指定的报文进行匹配。有的是二进制协议的字段匹配,主要就是数值的比较。有的是针对传输层协议的内容匹配,主要是字符串的匹配查找。其中字符串的匹配分单模匹配以及多模匹配,本篇就简单的聊聊这两种匹配在suricata中的体现。
单模匹配即用单个字符串去匹配报文的的内容部分,例如payload。多模匹配即多个字符串同时去匹配报文的payload部分。其中多模匹配主要发生在prefilter阶段,而单模匹配发生在单条规则的匹配阶段。
多模匹配
为什么说prefilter阶段是单模匹配呢?在Prefilter
函数中,执行的匹配函数代码为engine->cb.Prefilter
,而该函数是在PrefilterPktPayloadRegister
函数中注册的,详细的见我前面分析prefilter的文章,这里。在PrefilterPktPayloadRegister
函数中,注册的匹配函数为PrefilterPktPayload
,其中mpm_table即多模匹配的算法函数,可以是AC的多模匹配算法,也可以选择HS的多模匹配算法。匹配的内容是p->payload
,匹配的多模模式是pectx
。那么多模的模式是怎么构建的呢?
模式的来源即每一个规则的fast pattern构成,在规则被加载解析之后,会进行规则的build,在规则的build阶段就会将这些fast pattern构建成多模的模式。具体构建多模模式的函数为MpmStorePrepareBuffer
,该函数针对不同的分组进行多模模式的建立。首先通过MpmStoreLookup
查找模式是否存在,如果不存在通过MpmStoreSetup
建立。在MpmStoreSetup
中,最重要的是找到符合条件的fast pattern,即 const DetectContentData *cd = (DetectContentData *)s->init_data->mpm_sm->ctx;
,然后将其加入到 ms->mpm_ctx
中,即:
PopulateMpmHelperAddPattern(ms->mpm_ctx,cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
前面提到,多模模式的个数是由系统的分组决定的,在一个多模的模式创建完成之后,会将该模式加入de_ctx->mpm_hash_table
哈希表进行统一的管理,即MpmStoreAdd
函数的内容。
单模匹配
单模的匹配主要是将规则的一个个pattern依次去匹配报文的payload部分,即DetectRulePacketRules->DetectEnginePktInspectionRun
。DetectEnginePktInspectionRun
函数中e->v1.Callback
回调函数的注册位于DetectEnginePktInspectionSetup
处。可以看到匹配函数为DetectEngineInspectRulePayloadMatches->DetectEngineInspectPacketPayload->DetectEngineContentInspection->SpmScan
。同样的在SpmScan函数中,spm_table可以采用AC的单模匹配算法也可以采用HS的单模匹配算法,匹配的内容sbuffer通常是报文的payload部分,匹配的字符串cd->spm_ctx
即规则解析阶段的每个规则中的一个个字符串pattern。
多模匹配的消耗通常要高于单模的匹配,同时经过prefilter阶段的匹配之后,符合条件的规则数量会大大的减少,在单模匹配阶段的消耗也会变的更少。这也是在测试性能的时候,规则检测阶段性能消耗最大的往往是prefilter函数。
本文为CSDN村中少年原创文章,转载记得加上原创出处,博主链接这里。