suricata源码中的packet prefilter 以及payload prefilter

suricat主要分为引擎和规则。对于引擎功能比较多,包括协议的解码,规则的加载和解析,以及规则的识别。总的来检测的成功率主要体现在规则上。规则会随着需求的增加而增长,当规则很多的时候,识别的效率就会非常的突出。如果让每一个报文去匹配所有的规则,那么识别的效率是远远满足不了实际的要求的。因此为了提高检测效率,suricata引入了prefilter机制。

每一条规则有很多的匹配条件,只取该条规则中的其中一个匹配条件放入prefilter中,在该规则匹配命中之后,才会在后续的流程继续匹配剩下的条件;如果没有命中,则该条规则后续的条件也不会再去匹配检测,从而节省匹配的时间。

选择一条规则中哪一个匹配条件放入prefilter中,suricata提供了两种方式:

1,显示的指定匹配条件放入prefilter。针对字符串的匹配,即使用MPM多模匹配算法的匹配,使用fast_pattern关键字进行指定。例如,content:"IMSTSWebProxy"; nocase; fast_pattern;content:"IMSTSWebProxy";会被方放入prefilter中。针对于非字符串的匹配,即non-MPM的匹配,使用prefilter关键字,例如,ttl:123; prefilter;,则ttl:123; 会被方放入prefilter中。

2,使用默认的方式。如果没有像1中的显示指定prefilter,则suricata会根据自己内部的一套方法来选择默认的prefilter。如下:

1,总的原则是肯定的匹配条件优先级高于否定的匹配条件(否定的匹配指的是条件中带有!的匹配)。
2,suricata内部定义了一些关键字buffer的优先级,例如http_method优先级高于http_cookie,在http_method和http_cookie条件同时存在的时候,优先选择http_method作为prefilter。关于这些关键字buffer的优先级,这里
3,对于像http_uri以及http_host这样具有相同优先级的buffer,则使用匹配条件中长度较长的content作为prefilter.
4,如果第三步中仍然无法确认prefilter,则根据匹配条件content的字符复杂程度进行判断,更为复杂的字符作为prefilter。关于字符串复杂度的判断算法,这里
5,第4步中仍然无法确认的话,则根据buffer注册的id来进行判断,注册顺序建步骤2的链接。在源码中,buffer部分注册的如下:

 /* NOTE: the order of these currently affects inspect
     * engine registration order and ultimately the order
     * of inspect engines in the rule. Which in turn affects
     * state keeping */
    DetectHttpUriRegister();
    DetectHttpRequestLineRegister();
    DetectHttpClientBodyRegister();
    DetectHttpResponseLineRegister();
    DetectHttpServerBodyRegister();
    DetectHttpHeaderRegister();
    DetectHttpHeaderNamesRegister();
    DetectHttpHeadersRegister();
    DetectHttpProtocolRegister();
    DetectHttpStartRegister();
    DetectHttpRawHeaderRegister();
    DetectHttpMethodRegister();
    DetectHttpCookieRegister();
    DetectHttpRawUriRegister();

6,如果第五步还未能选出prefilter,则根据规则编写的顺序进行判断,即一条规则中先出现的作为prefilter,即左侧的规则优先作为prefilter。

根据上述的1,2,3,4,5,6个步骤依次进行判定,直至选出最终的prefilter。prefilter的处理方式也是引擎加规则,只是引擎是prefilter的引擎,如上所述,总计分为三中类别的prefilter引擎,如下:

typedef struct SigGroupHeadInitData_ {
    MpmStore mpm_store[MPMB_MAX];

    uint8_t *sig_array; /**< bit array of sig nums (internal id's) */
    uint32_t sig_size; /**< size in bytes */

    uint8_t protos[256];    /**< proto(s) this sgh is for */
    uint32_t direction;     /**< set to SIG_FLAG_TOSERVER, SIG_FLAG_TOCLIENT or both */
    int whitelist;          /**< try to make this group a unique one */

    MpmCtx **app_mpms;

    PrefilterEngineList *pkt_engines;//传输层以下的packet prefilter
    PrefilterEngineList *payload_engines;//其他的传输层以上的载payload prefilter
    PrefilterEngineList *tx_engines;//TLS,HTTP,DNS等应用层事物的 tx prefilter

    /* port ptr */
    struct DetectPort_ *port;
} SigGroupHeadInitData;

而规则则是每一条规则中抽取的一个匹配条件形成的规则库。

1,pkt_engines 即传输层以下的packet prefilter。这类匹配主要针对的是传输层及以下的支持prefilter的协议字段,例如前面提到的TTL以及TCP的ACK等二进制协议字段,通常都是进行数字的比较。在suricata中,packet prefilter的匹配都会调用PrefilterSetupPacketHeader函数进行prefilter的注册,例如TCP ACK规则解析中prefilter就是调用了PrefilterSetupTcpAck进行prefilter的注册,具体的用于ACK字段的匹配函数为PrefilterPacketAckMatchPrefilterPacketAckMatch主要做了两件事情,其一就是直接将报文中的ACK字段和prefilter中的ACK进行比较,其二就是将成功匹配条件对应的rule id通过PrefilterAddSids函数加入到det_ctx->pmq中,供后续的该条规则对应的其他匹配条件进行匹配。TTL等字段同理,可以看到这类的prefilter并不是很多,有13个规则关键字支持这类的prefilter。

当然这些prefilter的规则都会通过PrefilterAppendEngine函数加入到PrefilterEngineList *pkt_engines中。在PrefilterAppendEngine函数中可以看到对于每个prefilter条件规则都生成了一个prefilter引擎,通过sgh->init->pkt_engines链表进行组织。在实际匹配的时候,会去逐个遍历匹配每个prefilter引擎中的规则。在规则检测部分Prefilter函数中,可以看到会去逐个两类prefilter引擎中所有的引擎,即packet引擎以及payload引擎(见第二部分所述)。

由于suricata针对传输层以下的协议也是提供了tcp.hdr以及udp.hdr等用于字符串比较的规则关键字,因此packet prefilter除了数字的直接比较方式,也是提供了字符串的匹配方式。例如PrefilterGenericMpmPktRegister函数就是注册这类的packet prefilter引擎。其匹配函数为PrefilterMpmPkt,和所有的多模匹配一样,就是用prefilter中的规则去匹配解码后的buffer。除了tcp.hdr buffer以及udp.hdr buffer之外,调用PrefilterGenericMpmPktRegister的还包括ipv4.hdr以及ipv6.hdr的buffer,都是这类的多模匹配。

2,payload_engines即传输层以上的载payload prefilter。suricata将一些应用层协议和无法解析的应用层协议的载荷匹配对应的prefilter称之为payload prefilter。

该种类型的prefilter通过PrefilterAppendPayloadEngine函数注册到payload_engines中。PrefilterAppendPayloadEngine的调用者保包括PrefilterPktStreamRegister以及PrefilterPktPayloadRegister。事实上从字面意思还是很容易明白的PrefilterPktStreamRegister使用与传输层是TCP的ayload prefilter的注册,PrefilterPktPayloadRegister既可以用TCP也可以用于UDP,这在更上层的调用函数PatternMatchPrepareGroup中有所体现。当然上述两者的区别在于他们的匹配函数,分别为PrefilterPktStream以及PrefilterPktPayload。PrefilterPktPayload函数就是简单的单包匹配,当一个报文送来的时候,将对应prefilter中的规则和报文的载荷进行多模匹配。具体使用哪些Prefilter呢?其实可以看到调用关系SigAddressPrepareStage4->PrefilterSetupRuleGroup->PatternMatchPrepareGroup->PrefilterPktPayloadRegister 中payload prefilter的注册其实是按照规则分组建立的。也就是说有多个个规则的分组group,就有多少个payload prefilter。因此具体的packet会根据packet所属的分组去匹配该分组的prefilter引擎下所有的规则(该分组每个规则取其中一个匹配条件形成的)。这里面可以看到分组能够减少无用的prefilter匹配,通常来说分组越多,匹配效率越高。

PrefilterPktPayloadRegister指的是单包的匹配,而PrefilterPktStreamRegister指的是传输层为TCP协议,有的规则针对的载荷不再是简单的单包匹配而是需要将将TCP报文重组之后(例如stream_size关键字),形成完整的内容在进行匹配。cong其PrefilterPktStream匹配函数中可以看到,是先进行重组内容的匹配,即StreamReassembleRaw函数中的StreamMpmFunc回调对重组后的数据进行匹配。如果改包不是重组包,即if ((p->flags & (PKT_NOPAYLOAD_INSPECTION|PKT_STREAM_ADD)) == 0),则进行单包匹配。

当然无论对于的是单包还是tcp reassemble之后的匹配,注册的prefilter引擎都会挂到sgh->init->payload_engines结构下,在检测阶段Prefilter函数中进行调用。可以看到Prefilter函数中只有两种类型的引擎,即packet prefilter以及payload prefilter。因为事物de prefilter是在DetectRunPrefilterTx中进行调用。由于tx_engines涉及到事物的概念,将在介绍事物概念之后再进行介绍。

本文为CSDN村中少年原创文章,未经允许不得转载,博主链接这里

### 回答1: 我不是很了解Suricata代码分析,但我可以给你一些建议。你可以通过阅读Suricata官方文档,以及搜索博客和技术文章来了解Suricata源代码的相关内容。此外,你还可以加入相关的讨论组,与其他Suricata开发人员一起分享和交流经验。 ### 回答2: Suricata是一种自由开源的入侵检测和预防系统(IDS/IPS),其源码分析是对其实现原理和功能的深入理解和研究。 Suricata源码分析包括对其整体架构的研究,了解其模块和组件之间的关系,以及其各个模块的实现细节。其,主要包括以下几个方面的内容: 1. 数据包解析:Suricata源码分析需要对其数据包解析模块进行深入研究,学习其对不同协议的解析方法和规则,了解具体的解析流程和实现细节。 2. 规则引擎:Suricata的规则引擎是其核心功能之一,对其源码进行分析需要了解规则引擎的设计思路和实现方式,包括规则的加载、匹配和执行等过程。 3. 异步处理:Suricata使用异步处理机制来提高性能,对其源码进行分析需要深入研究其异步处理框架和相关模块,学习其实现方式和优化技巧。 4. 日志和报告:Suricata生成的日志和报告对于事件追踪和安全分析非常重要,对其源码进行分析需要了解其日志和报告模块的实现细节,包括日志格式、输出方式和性能优化等。 通过对Suricata源码的深入分析,可以进一步了解其内部机制和工作原理,掌握其使用方法和扩展开发的技巧,以提高系统的安全性和性能。同时,源码分析也是学习和贡献开源项目的重要途径,可以为项目的改进和发展做出积极的贡献。 ### 回答3: Suricata是一种高性能的开源入侵检测系统(IDS),具有实时流量分析和威胁检测能力。对Suricata源码进行分析有助于深入了解其工作原理和实现方式。 Suricata源码分析主要包括以下方面: 1. 系统架构和模块组成:Suricata源码采用模块化设计,由多个核心模块组成,如引擎模块、解析器模块、规则引擎模块等,这些模块协同工作实现了对流量的检测和分析。 2. 流量解析过程:Suricata源码包含用于解析不同网络协议的代码,如TCP、UDP、HTTP等。通过对网络流量的深入解析,Suricata可以获取各个协议层的信息,以供后续的威胁检测和分析。 3. 规则引擎和特征匹配:Suricata源码实现了一套规则引擎,用于匹配流量的特征,通过对已定义的规则进行匹配,Suricata可以识别出潜在的威胁。该规则引擎基于高效的匹配算法,如AC自动机等。 4. 威胁检测和日志记录:Suricata源码包含了多种威胁检测算法和技术,如基于规则的检测、异步多线程处理等。通过对流量进行检测和分析,Suricata可以及时发现各种网络攻击和异常行为,并记录相关日志供后续分析。 5. 性能优化和扩展机制:Suricata源码注重性能优化和扩展性,采用了多种技术手段,如多线程处理、流量解析的优化等,以提高系统的吞吐量和并发处理能力。此外,Suricata还提供了插件机制,可以方便地扩展其功能和特性。 通过对Suricata源码的分析,可以更好地了解其工作原理和实现方式,掌握其使用和开发技巧。这对于开发人员和网络安全专家来说都非常重要,可以帮助他们深入理解和应用Suricata这一强大的网络安全工具。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

村中少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值