首页
社区
课程
招聘
Suricata引擎二次开发之命中规则定位
发表于: 2024-6-24 14:32 1827

Suricata引擎二次开发之命中规则定位

2024-6-24 14:32
1827

二开背景

suricata是一款高性能的开源网络入侵检测防御引擎,旨在检测、预防和应对网络中的恶意活动和攻击。suricata引擎使用多线程技术,能够快速、准确地分析网络流量并识别潜在的安全威胁,是众多IDS和IPS厂商的底层规则检测模块。

前段时间搭了个suricata引擎播包测试流量规则,发现原生的suricata引擎并不能获取规则匹配的位置、命中的字符串等信息。因suricata引擎并不会输出命中的信息,遂修改源码,改了命中详情(下文简称高亮)出来,今天想跟大家分享一下修改和使用的过程。

1、suricat编译安装

参考官方文档https://docs.suricata.io/en/suricata-6.0.0/install.html#install-advanced

先装库,装rust支持,装make

然后下载源码make

编译后的二进制程序在/src/.libs/suricata查看依赖库,然后补齐到默认so库目录中即可运行。

2、vscode+gdb调试suricata环境搭建

然后就是装插件,除了必备的c语言插件全家桶之外还需要装GDB Debug这个插件。

接着任意新建一个运行配置。


修改lauch.json为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
         
        {
            "name": "(gdb) Launch",
            "type": "cppdbg",
            "request": "launch",
            "program": "${fileDirname}/../src/.libs/suricata",
 
            //以下为监听网卡模式。
            // "args": [
            //     "-i", "ens33", "-c", "/home/lalala/Desktop/suricata/6/suricata.yaml", "-v", "-l","/home/lalala/Desktop/suricata/6/log6/","--runmode", "single"
            // ],
             
            //以下为读包模式。
            "args": [
                "-r", "/home/lalala/Desktop/suricata/6/6-27/48040.pcap", "-c", "/home/lalala/Desktop/suricata/6/suricata.yaml", "-v", "-l","/home/lalala/Desktop/suricata/6/log6/","--runmode", "single"
            ],
            "stopAtEntry": true,
            "cwd": "${fileDirname}",
            "environment": [],
            "externalConsole": false,
            "MIMode": "gdb",
            "setupCommands": [
                {
                    "description": "Enable pretty-printing for gdb",
                    "text": "-enable-pretty-printing",
                    "ignoreFailures": true
                },
                {
                    "description": "Set Disassembly Flavor to Intel",
                    "text": "-gdb-set disassembly-flavor intel",
                    "ignoreFailures": true
                }
            ]
        },
         
    ]
}

选择配置好的配置运行,看到断在入口,调试环境完成。

3、suricata流程分析,寻找关键位置

流程过于复杂,简单理解就是匹配和记录日志的地方是分在不同线程,但是又有结构体可以从匹配带到那里。

4、关键位置代码分析,获取高亮内容

根据流程,在初始化后慢慢摸索找到关键函数DetectEngineContentInspection

smd为传入规则,根据type的不同走不同的代码块儿匹配。本次加高亮重点关注CONTENT和PCRE这两个最常用的类型。

CONTENT代码块里,重点在于这个found。分析得出最后两个else里都是命中。

根据原字符串,偏移,长度即可组合出高亮字符串。

f为flow结构体也就是会带到打印日志那边的结构体,在结构体中新加一个字符串,即可达成带数据到日志流程的目的。

高亮函数代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
static int Get_gaoliang(const char* data,u_int32_t end, u_int32_t len,char* res){
    char tmp[1024] = "";
     
    if (len<1024)
    {
        memcpy(tmp, data + end-len, len);
    }else{
        memcpy(tmp, data + end-len, 1024);
    }
    strncat(res, tmp,4096);
    strncat(res, "\n\0",4096);
    return 1;
}

pcre同理,在命中流程中加入写高亮字符串即可。

5、高亮加到日志

高亮字符已经写入到了flow结构体。下一步就是在打印日志的时候读到,写出来。

最优先的当然是fastlog,因为fastlog本就是触发规则会进行输出的日志,且没有其他干扰。

从Packet结构体找到flow结构体找到其中的gaoliang字符串,打印即可。

最终效果,fastlog会在正常展示命中的同时,讲高亮内容展示。

6、修改汇总

汇总代码放在github 上链接https://github.com/webraybtl/suricata_gaoliang

修改文件详情:

alert-fastlog.c

加打印

修改 AlertFastLogger

添加如下代码:

1
PrintBufferData(alert_buffer, &size, MAX_FASTLOG_ALERT_SIZE, "=========ruleid:%" PRIu32 "高亮字段展示=======:\n%s====================================\n",pa->s->id,p->flow->gaoliang);

detect-engine-content-inspection.c

加Get_gaoliang函数

修改DetectEngineContentInspection函数 加入 写入高亮字符串逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
static int Get_gaoliang(const char* data,u_int32_t end, u_int32_t len,char* res){
    char tmp[1024] = "";
      
    if (len<1024)
    {
        memcpy(tmp, data + end-len, len);
    }else{
        memcpy(tmp, data + end-len, 1024);
    }
    strncat(res, tmp,4096);
    strncat(res, "\n\0",4096);
    return 1;
}
  
  
  
int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx,
                                  const Signature *s, const SigMatchData *smd,
                                  Packet *p, Flow *f,
                                  const uint8_t *buffer, uint32_t buffer_len,
                                  uint32_t stream_start_offset, uint8_t flags,
                                  uint8_t inspection_mode)
{
    ...
    ...
    ...
            if (found == NULL && !(cd->flags & DETECT_CONTENT_NEGATED)) {
                if ((cd->flags & (DETECT_CONTENT_DISTANCE|DETECT_CONTENT_WITHIN)) == 0) {
                    /* independent match from previous matches, so failure is fatal */
                    det_ctx->discontinue_matching = 1;
                }
  
                goto no_match;
            } else if (found == NULL && (cd->flags & DETECT_CONTENT_NEGATED)) {
                goto match;
            } else if (found != NULL && (cd->flags & DETECT_CONTENT_NEGATED)) {
                if(f){
                Get_gaoliang((char*)buffer,match_offset,cd->content_len,f->gaoliang);
  
                }
  
                SCLogInfo("content %"PRIu32" matched at offset %"PRIu32", but negated so no match", cd->id, match_offset);
                /* don't bother carrying recursive matches now, for preceding
                 * relative keywords */
                if (DETECT_CONTENT_IS_SINGLE(cd))
                    det_ctx->discontinue_matching = 1;
                goto no_match;
            } else {
                match_offset = (uint32_t)((found - buffer) + cd->content_len);
                if(f){
                    Get_gaoliang((char*)buffer,match_offset,cd->content_len,f->gaoliang);
                    }
  
    ...

flow.h

flow结构体加一个gaoliang字符串成员。

1
2
3
4
5
6
7
8
9
typedef struct Flow_
{
    ...
    ...
    ...
      
    char gaoliang[4096]; 
  
} Flow;

**
遗留问题

1、因只开辟了4096字节存高亮字符,会有溢出。

2、直接按字符串打印展示出来的,对十六进制展示不理想,00会导致打印不全。

原文链接


[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 0
支持
分享
最新回复 (1)
雪    币: 12
活跃值: (3735)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
gaoliang
2024-6-24 15:34
0
游客
登录 | 注册 方可回帖
返回
//