suricata之规则去重

发布于:2025-05-11 ⋅ 阅读:(22) ⋅ 点赞:(0)

一、环境和背景

1.1 环境

OS: Ubuntu 22.04.5 LTS
IDE: vscode
suricata: suricata 7.0.5

1.2 背景

在添加规则时,为了给规则分类,将不同类别的规则写入不同的文件。
在规则加载时两条不同的规则却被认为是重复的,因此记录一下去重逻辑。

a.rule

alert ip any any -> any any (msg:"SURICATA Applayer Mismatch protocol both directions"; flow:established; app-layer-event:applayer_mismatch_protocol_both_directions; flowint:applayer.anomaly.count,+,1; classtype:protocol-command-decode; sid:2260000; rev:1;)

b.rule

alert http any any -> any any (msg:"SURICATA HTTP unknown error"; flow:established; app-layer-event:http.unknown_error; flowint:http.anomaly.count,+,1; classtype:protocol-command-decode; sid:2260000; rev:1;)

suricata.yaml

rule-files:
    - a.rule
    - b.rule

请添加图片描述

二、 Suricata 规则去重

suricata 规则通过一个hashtable进行去重。

2.1 hashtable 建立

// src/suricata.c
PostConfLoadedDetectSetup
    // src/detect-engine.c
    -> DetectEngineCtxInit
        // src/detect-engine.c
        -> DetectEngineCtxInitReal
            // src/detect-parse.c
            -> DetectParseDupSigHashInit
    // src/suricata.c
    -> LoadSignatures
int DetectParseDupSigHashInit(DetectEngineCtx *de_ctx)
{
    de_ctx->dup_sig_hash_table = HashListTableInit(15000,
                                                   DetectParseDupSigHashFunc,
                                                   DetectParseDupSigCompareFunc,
                                                   DetectParseDupSigFreeFunc);
    if (de_ctx->dup_sig_hash_table == NULL)
        return -1;

    return 0;
}

2.2 检测重复

// src/detect-parse.c

Signature *DetectEngineAppendSig(DetectEngineCtx *de_ctx, const ch
{
    // 1. 解析规则
    Signature *sig = SigInit(de_ctx, sigstr);
    if (sig == NULL) {
        return NULL;
    }

    // 2. 检测重复
    /* checking for the status of duplicate signature */
    int dup_sig = DetectEngineSignatureIsDuplicate(de_ctx, sig);
    ...
}

static inline int DetectEngineSignatureIsDuplicate(DetectEngineCtx
                                                   Signature *sig)
{
    /* we won't do any NULL checks on the args */

    /* return value */
    int ret = 0;

    SigDuplWrapper *sw_dup = NULL;
    SigDuplWrapper *sw = NULL;

    /* used for making a duplicate_sig_hash_table entry */
    sw = SCMalloc(sizeof(SigDuplWrapper));
    if (unlikely(sw == NULL)) {
        exit(EXIT_FAILURE);
    }
    memset(sw, 0, sizeof(SigDuplWrapper));
    sw->s = sig;

    /* check if we have a duplicate entry for this signature */
    sw_dup = HashListTableLookup(de_ctx->dup_sig_hash_table, (void *)sw, 0);
    /* we don't have a duplicate entry for this sig */
    if (sw_dup == NULL) {
        ...
    }
    ...
}

2.3 重复条件

static char DetectParseDupSigCompareFunc(void *data1, uint16_t len1, void *data2,
                                  uint16_t len2)
{
    SigDuplWrapper *sw1 = (SigDuplWrapper *)data1;
    SigDuplWrapper *sw2 = (SigDuplWrapper *)data2;

    if (sw1 == NULL || sw2 == NULL ||
        sw1->s == NULL || sw2->s == NULL)
        return 0;

    /* sid and gid match required */
    if (sw1->s->id == sw2->s->id && sw1->s->gid == sw2->s->gid) return 1;

    return 0;
}

sidgid作为重复条件,全部相等时则认为重复,不看具体的规则内容。

三、总结

  1. suricata规则通过sidgid进行去重,并不关注规则中的具体内容
  2. 通过sidgid唯一区分规则,整个工程里对规则的处理相较于字符串,整数值处理更简单高效
  3. 如果需要将规则拆分成多个文件时,需要注意sid的值

网站公告

今日签到

点亮在社区的每一天
去签到