Suricata-流關(guān)鍵字

Thank Zhihao Tao for your hard work. The document spent countless nights and weekends, using his hard work to make it convenient for everyone.
If you have any questions, please send a email to zhihao.tao@outlook.com


1. flowbits

flowbits由兩部分組成:

  • 第一部分描述將要執(zhí)行的動作案疲,
  • 第二部分是flowbits的名稱虾宇。

有多個數(shù)據(jù)包屬于一個流盅抚。Suricata將這些流保存在內(nèi)存中产镐。flowbits可以確保在兩個不同的數(shù)據(jù)包匹配時才將生成警報。僅當(dāng)兩個數(shù)據(jù)包匹配時才會生成警報挠乳。

因此寝蹈,當(dāng)?shù)诙€數(shù)據(jù)包匹配時榆骚,Suricata必須知道第一個數(shù)據(jù)包是否也匹配。如果數(shù)據(jù)包匹配浪读,則flowbits會標(biāo)記流昔榴,因此當(dāng)Suricata“知道”第二個數(shù)據(jù)包也匹配時,它將生成警報碘橘。

示例:
當(dāng)你看第一條規(guī)則時互订,你會注意到如果它匹配,如果不是在規(guī)則末尾的flowbits:noalert痘拆,它就會生成一個警報仰禽。該規(guī)則的目的是檢查userlogin上的匹配項,并在流中進行標(biāo)記纺蛆。因此吐葵,無需生成警報

如果沒有第一條規(guī)則桥氏,第二條規(guī)則將無效温峭。如果第一個規(guī)則匹配,flowbits將設(shè)置流中存在的特定條件∽种В現(xiàn)在凤藏,使用第二條規(guī)則,可以檢查前一個數(shù)據(jù)包是否滿足第一個條件堕伪。如果此時第二條規(guī)則匹配揖庄,將生成警報∏反疲可以在規(guī)則中多次使用流位蹄梢,并組合不同的功能。

flowbits

void DetectFlowbitsRegister (void)
{
    sigmatch_table[DETECT_FLOWBITS].name = "flowbits";
    sigmatch_table[DETECT_FLOWBITS].desc = "operate on flow flag";
    sigmatch_table[DETECT_FLOWBITS].url = DOC_URL DOC_VERSION "/rules/flow-keywords.html#flowbits";
    sigmatch_table[DETECT_FLOWBITS].Match = DetectFlowbitMatch;
    sigmatch_table[DETECT_FLOWBITS].Setup = DetectFlowbitSetup;
    sigmatch_table[DETECT_FLOWBITS].Free  = DetectFlowbitFree;
    sigmatch_table[DETECT_FLOWBITS].RegisterTests = NULL;
    /* this is compatible to ip-only signatures */
    sigmatch_table[DETECT_FLOWBITS].flags |= SIGMATCH_IPONLY_COMPAT;

    DetectSetupParseRegexes(PARSE_REGEX, &parse_regex, &parse_regex_study);
}

1.1 flowbits安裝

  1. 解析flowbits具有的6種不同的動作:
    • noalert
    • isset
    • isnotset
    • set
    • unset
    • toggle
int DetectFlowbitSetup (DetectEngineCtx *de_ctx, Signature *s, const char *rawstr)
{
    DetectFlowbitsData *cd = NULL;
    SigMatch *sm = NULL;
    uint8_t fb_cmd = 0;
    char fb_cmd_str[16] = "", fb_name[256] = "";

    if (!DetectFlowbitParse(rawstr, fb_cmd_str, sizeof(fb_cmd_str), fb_name,
            sizeof(fb_name))) {
        return -1;
    }

    if (strcmp(fb_cmd_str,"noalert") == 0) {
        fb_cmd = DETECT_FLOWBITS_CMD_NOALERT;
    } else if (strcmp(fb_cmd_str,"isset") == 0) {
        fb_cmd = DETECT_FLOWBITS_CMD_ISSET;
    } else if (strcmp(fb_cmd_str,"isnotset") == 0) {
        fb_cmd = DETECT_FLOWBITS_CMD_ISNOTSET;
    } else if (strcmp(fb_cmd_str,"set") == 0) {
        fb_cmd = DETECT_FLOWBITS_CMD_SET;
    } else if (strcmp(fb_cmd_str,"unset") == 0) {
        fb_cmd = DETECT_FLOWBITS_CMD_UNSET;
    } else if (strcmp(fb_cmd_str,"toggle") == 0) {
        fb_cmd = DETECT_FLOWBITS_CMD_TOGGLE;
    } else {
        SCLogError(SC_ERR_UNKNOWN_VALUE, "ERROR: flowbits action \"%s\" is not supported.", fb_cmd_str);
        goto error;
    }
  1. noalert設(shè)置SIG_FLAG_NOALERT選項桨昙。
    switch (fb_cmd) {
        case DETECT_FLOWBITS_CMD_NOALERT:
            if (strlen(fb_name) != 0)
                goto error;
            s->flags |= SIG_FLAG_NOALERT;
            return 0;
        case DETECT_FLOWBITS_CMD_ISNOTSET:
        case DETECT_FLOWBITS_CMD_ISSET:
        case DETECT_FLOWBITS_CMD_SET:
        case DETECT_FLOWBITS_CMD_UNSET:
        case DETECT_FLOWBITS_CMD_TOGGLE:
        default:
            if (strlen(fb_name) == 0)
                goto error;
            break;
    }

  1. 分配flowbits id检号,并加入到簽名的匹配條件中腌歉。
    • issetisnotset加入DETECT_SM_LIST_MATCH組。
    • set齐苛、unsettoggle加入DETECT_SM_LIST_POSTMATCH組翘盖。
...
    cd = SCMalloc(sizeof(DetectFlowbitsData));
    if (unlikely(cd == NULL))
        goto error;

    cd->idx = VarNameStoreSetupAdd(fb_name, VAR_TYPE_FLOW_BIT);
    de_ctx->max_fb_id = MAX(cd->idx, de_ctx->max_fb_id);
    cd->cmd = fb_cmd;

    SCLogDebug("idx %" PRIu32 ", cmd %s, name %s",
        cd->idx, fb_cmd_str, strlen(fb_name) ? fb_name : "(none)");

    /* Okay so far so good, lets get this into a SigMatch
     * and put it in the Signature. */
    sm = SigMatchAlloc();
    if (sm == NULL)
        goto error;

    sm->type = DETECT_FLOWBITS;
    sm->ctx = (SigMatchCtx *)cd;

    switch (fb_cmd) {
        /* case DETECT_FLOWBITS_CMD_NOALERT can't happen here */

        case DETECT_FLOWBITS_CMD_ISNOTSET:
        case DETECT_FLOWBITS_CMD_ISSET:
            /* checks, so packet list */
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_MATCH);
            break;

        case DETECT_FLOWBITS_CMD_SET:
        case DETECT_FLOWBITS_CMD_UNSET:
        case DETECT_FLOWBITS_CMD_TOGGLE:
            /* modifiers, only run when entire sig has matched */
            SigMatchAppendSMToList(s, sm, DETECT_SM_LIST_POSTMATCH);
            break;

        // suppress coverity warning as scan-build-7 warns w/o this.
        // coverity[deadcode : FALSE]
        default:
            goto error;
    }

    return 0;

error:
    if (cd != NULL)
        SCFree(cd);
    if (sm != NULL)
        SCFree(sm);
    return -1;
}

1.2 flowbits匹配

  1. 如果DETECT_SM_LIST_MATCH有匹配項,進行注冊Match函數(shù)注冊凹蜂。
int DetectEnginePktInspectionSetup(Signature *s)
{
...
    if (s->sm_arrays[DETECT_SM_LIST_MATCH]) {
        if (DetectEnginePktInspectionAppend(s, DetectEngineInspectRulePacketMatches,
                NULL) < 0)
...
}
  1. 遍歷DETECT_SM_LIST_MATCH中所有選項進行匹配馍驯。
static int DetectEngineInspectRulePacketMatches(
    DetectEngineThreadCtx *det_ctx,
    const DetectEnginePktInspectionEngine *engine,
    const Signature *s,
    Packet *p, uint8_t *_alert_flags)
{
...
        if (sigmatch_table[smd->type].Match(det_ctx, p, s, smd->ctx) <= 0) {
...
}
  1. 對不同類型的flowbits進行匹配。
int DetectFlowbitMatch (DetectEngineThreadCtx *det_ctx, Packet *p,
        const Signature *s, const SigMatchCtx *ctx)
{
    const DetectFlowbitsData *fd = (const DetectFlowbitsData *)ctx;
    if (fd == NULL)
        return 0;

    switch (fd->cmd) {
        case DETECT_FLOWBITS_CMD_ISSET:
            return DetectFlowbitMatchIsset(p,fd);
        case DETECT_FLOWBITS_CMD_ISNOTSET:
            return DetectFlowbitMatchIsnotset(p,fd);
        case DETECT_FLOWBITS_CMD_SET:
            return DetectFlowbitMatchSet(p,fd);
        case DETECT_FLOWBITS_CMD_UNSET:
            return DetectFlowbitMatchUnset(p,fd);
        case DETECT_FLOWBITS_CMD_TOGGLE:
            return DetectFlowbitMatchToggle(p,fd);
        default:
            SCLogError(SC_ERR_UNKNOWN_VALUE, "unknown cmd %" PRIu32 "", fd->cmd);
            return 0;
    }

    return 0;
}

1.2.1 flowbits: set, name

在流中設(shè)置條件/名稱(如果存在)玛痊。

static int DetectFlowbitMatchSet (Packet *p, const DetectFlowbitsData *fd)
{
    if (p->flow == NULL)
        return 0;

    FlowBitSet(p->flow,fd->idx);

    return 1;
}

1.2.2 flowbits: isset, name

可在規(guī)則中使用汰瘫,以確保在規(guī)則匹配且條件在流中設(shè)置時生成告警。

static int DetectFlowbitMatchIsset (Packet *p, const DetectFlowbitsData *fd)
{
    if (p->flow == NULL)
        return 0;

    return FlowBitIsset(p->flow,fd->idx);
}

1.2.3 flowbits: toggle, name

反轉(zhuǎn)當(dāng)前設(shè)置擂煞。因此混弥,如果設(shè)置了條件,則將不設(shè)置條件对省,反之亦然蝗拿。

void FlowBitToggle(Flow *f, uint32_t idx)
{
    FlowBit *fb = FlowBitGet(f, idx);
    if (fb != NULL) {
        FlowBitRemove(f, idx);
    } else {
        FlowBitAdd(f, idx);
    }
}

static int DetectFlowbitMatchToggle (Packet *p, const DetectFlowbitsData *fd)
{
    if (p->flow == NULL)
        return 0;

    FlowBitToggle(p->flow,fd->idx);

    return 1;
}

1.2.4 flowbits: unset, name

可用于取消設(shè)置流中的條件。

static int DetectFlowbitMatchUnset (Packet *p, const DetectFlowbitsData *fd)
{
    if (p->flow == NULL)
        return 0;

    FlowBitUnset(p->flow,fd->idx);

    return 1;
}

1.2.5 flowbits: isnotset, name

可在規(guī)則中使用蒿涎,以確保在規(guī)則匹配且條件未在流中設(shè)置時生成告警哀托。

static int DetectFlowbitMatchIsnotset (Packet *p, const DetectFlowbitsData *fd)
{
    if (p->flow == NULL)
        return 0;

    return FlowBitIsnotset(p->flow,fd->idx);
}

1.2.6 flowbits: noalert

此規(guī)則將不會生成告警。

static inline void DetectRulePacketRules(
    ThreadVars * const tv,
    DetectEngineCtx * const de_ctx,
    DetectEngineThreadCtx * const det_ctx,
    Packet * const p,
    Flow * const pflow,
    const DetectRunScratchpad *scratch
)
{
...
        if (!(sflags & SIG_FLAG_NOALERT)) {
            /* stateful sigs call PacketAlertAppend from DeStateDetectStartDetection */
            if (!state_alert)
                PacketAlertAppend(det_ctx, s, p, 0, alert_flags);
        } else {
            /* apply actions even if not alerting */
            DetectSignatureApplyActions(p, s, alert_flags);
        }
...
}


未完待續(xù)劳秋。仓手。。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末玻淑,一起剝皮案震驚了整個濱河市嗽冒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌岁忘,老刑警劉巖辛慰,帶你破解...
    沈念sama閱讀 221,331評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異干像,居然都是意外死亡帅腌,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,372評論 3 398
  • 文/潘曉璐 我一進店門麻汰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來速客,“玉大人,你說我怎么就攤上這事五鲫∧缰埃” “怎么了?”我有些...
    開封第一講書人閱讀 167,755評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長浪耘。 經(jīng)常有香客問我乱灵,道長,這世上最難降的妖魔是什么七冲? 我笑而不...
    開封第一講書人閱讀 59,528評論 1 296
  • 正文 為了忘掉前任痛倚,我火速辦了婚禮,結(jié)果婚禮上澜躺,老公的妹妹穿的比我還像新娘蝉稳。我一直安慰自己,他們只是感情好掘鄙,可當(dāng)我...
    茶點故事閱讀 68,526評論 6 397
  • 文/花漫 我一把揭開白布耘戚。 她就那樣靜靜地躺著,像睡著了一般操漠。 火紅的嫁衣襯著肌膚如雪收津。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,166評論 1 308
  • 那天颅夺,我揣著相機與錄音朋截,去河邊找鬼。 笑死吧黄,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的唆姐。 我是一名探鬼主播拗慨,決...
    沈念sama閱讀 40,768評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼奉芦!你這毒婦竟也來了赵抢?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,664評論 0 276
  • 序言:老撾萬榮一對情侶失蹤声功,失蹤者是張志新(化名)和其女友劉穎烦却,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體先巴,經(jīng)...
    沈念sama閱讀 46,205評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡其爵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,290評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了伸蚯。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片摩渺。...
    茶點故事閱讀 40,435評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖剂邮,靈堂內(nèi)的尸體忽然破棺而出摇幻,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 36,126評論 5 349
  • 正文 年R本政府宣布绰姻,位于F島的核電站枉侧,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏狂芋。R本人自食惡果不足惜棵逊,卻給世界環(huán)境...
    茶點故事閱讀 41,804評論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望银酗。 院中可真熱鬧辆影,春花似錦、人聲如沸黍特。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,276評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽灭衷。三九已至次慢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間翔曲,已是汗流浹背迫像。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瞳遍,地道東北人闻妓。 一個月前我還...
    沈念sama閱讀 48,818評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像掠械,于是被迫代替她去往敵國和親由缆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,442評論 2 359