suricata中的单模匹配和多模匹配

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村中少年原创文章,转载记得加上原创出处,博主链接这里

猜你喜欢

转载自blog.csdn.net/javajiawei/article/details/106924309