suricata的线程和模块功能

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了suricata的线程和模块功能相关的知识,希望对你有一定的参考价值。

参考技术A

suricata中tv、slot和tm的关系必须要搞清楚。

在源码中找到这三者的定义。

在threadvars.h中,有 ThreadVars 定义:

在tm-thread.h中,有 TmSlot 的定义:

在tm-modules.h中,有 TmModule 的定义:

三者的关系如下图所示:

每个线程都包含一个slot的链表,每个slot结点都悬挂着不同的模块,程序执行时会遍历slot链表,按照加入顺序执行模块。

SuricataMain函数中开头就有函数InitGlobal,该函数体内调用了一个 RunModeRegisterRunModes 函数,我们找到这个函数的定义:

其中每一种运行模式调用RunModeRegisterNewRunMode注册各自的Custom mode。例如

RunModeFilePcapRegister 函数:

RunModeRegisterNewRunMode函数会将回调函数(RunModeFilePcapSingle、RunModeFilePcapAutoFp)添加到runmodes全局数组中。

RunModes类型的全局数组==runmodes==保存运行模式,存储结构如下图:

注:这张图应该比较老了,现在只有single、autofp和workers三种自定义模式。

RunMode和RunModes结构体的定义如下:

同时也可以看到,suricata有 single, autofp和workers 这几种不同的自定义模式。这三种模式,在下文会细说。

在suricata.c中找到 RegisterAllModules 的定义,如下所示:

选择其中一个注册函数打开:

可以发现模块被保存到了 tmm_modules 数组中,是模块类型TmModule的数组。

存储结构如下图所示:

模块初始化的函数是 TmModuleRunInit ,定义如下:

该函数执行了模块全局初始化函数Init()。

RunModeDispatch 函数的功能主要如下:

这个回调函数主要做了这些事:

首先,三种自定义模式的运行流程图如下:

单工作线程完成所有工作。首个模块完成抓包,其他模块依次处理,没有后续队列。

根据监听网卡数量和每个网卡可启用的并行抓包线程数量确定工作线程数量。每个工作线程与single模式单线程工作流程一样,互不影响。

两种数据包处理线程,分别是收包线程和检测线程。收包线程和检测线程间通过PacketQueue传递数据包进行处理,每个检测线程对应一个队列,多个检测线程时需要为数据包选择队列以确保同一个流的数据包按顺序传递给同一个检测线程。

其中的autofp模式是最复杂的,也是默认的自定义模式。如下所示:

同线程内的模块之间主要是以参数的形式进行数据传递,不同线程之间以共享队列的方式进行数据传递。

每个线程由ThreaVars结构体来抽象,ThreadVars对象指定线程输入数据队列inq和输出数据队列outq。

这些队列在多个线程之间进行共享,一个线程的输出队列可能是另一个线程的输入队列。

[图片上传失败...(image-3ca5b5-1627459445094)]

绿色线条表示数据的走向。从输入队列获取数据包packet,经过slot函数(模块函数)的处理后,再将加工后的packet放到输出队列中。

以上三张图都是autofp模式下的运行流程图。

从上面"autofp"模式中可以看出RX thread所处的位置和包含的功能模块。它主要用于收集packets并对其进行解码,将处理后的packets放到pickup queue中,以供下个模块使用。

RX thread的作用体现为线程函数 TmThreadsSlotPktAcqLoop ,主要执行的任务为:

从上面"autofp"模式中可以看出W thread所处的位置和包含的功能模块。它主要由FlowWorker模块和一些log模块组成, 主要完成数据检测和特定格式特定数据的日志输出。

W thread的作用体现为线程函数==TmThreadsSlotVar==,主要执行的任务为:

TX thread的功能就是根据Detect模块检测的结果,对Verdict模块和RespondReject模块对标记的包进行相应的处理。

蓝色线条表示packet的传递路径。

Suricata规则配置

Suricata 规则配置



IDS/IPS/WAF


IPS、IDS和WAF分别是入侵防御系统和入侵检测系统以及WEB应用防火墙的简称,很多人说这些玩意不就是盒子吗已经过时了,其实不是,SIEM其实是有效的正规的打法,对于内网安全监控室非常必要的东西。之前大家的方式都是摒弃盒子思维,觉得盒子不靠谱防御不了真正的攻击行为。这样的理解难说不是国内众多盒子厂商(本人待过很多)走低价竞争路线的一个恶性的结果。其实在数据驱动安全的几天,盒子的作用绝不是简单的匹配规则阻断攻击这么简单的了,而是成为内网信息收集的一个Agent节点,作为云化的安全能力中心节点的触角存在,这都是非常有意义而且有必要的。

当然,我们还需要其他的更多的日志,不仅是网络层面的,需要主机层的日志信息、服务应用的日志信息等等。

规则和验证脚本


那么作为云的触角和云的核心节点(安全能力节点)有两种能力是必须具备的。第一脆弱性的发现能力(POC、EXP);第二就是威胁的监控能力,就是匹配规则。二者都来源于对攻击的理解。POC和EXP是模仿攻击的操作。规则是攻击行为的特征,是检测威胁的有效手段。废话不多说了,今天我们来学习Suricata规则。

Suricata规则范式


  alert tcp any any -> any any (msg:"";content:"";sid:1;rev:1;)

其实格式就是:
动作 协议 源地址 源端口 方向 目的地址 目的端口 (规则内容)
备注1:规则内容前面称为规则头部分
备注2:规则内容用分号分割,每一项都是一个key-value的键值对 ,如上图示例

Suricata 规则头


  • 动作:

    • alert 告警
    • log 记录
    • pass 通过
    • drop 丢弃
  • 协议:

    • TCP
    • UDP
    • ICMP
    • IP
    • Any
  • 源和目的IP:

    • IP地址 举例 10.1.1.1 或者 ! 10.1.1.1 或则[1.1.1.1 , 1.1.1.2] 或者! [1.1.1.1 , 1.1.1.2]
    • IP地址段(CIDR)[10.0.0.0/24]
    • Any
  • 元和目的端口:

    • 端口 80 或者 [80,443] 当然 ! 80 或者 ! [80,443] 再有 [1:80,![2,3]] [80:82]
    • Any
  • 方向:

    • 单项 ->
    • 双向 <>

Suricata 规则内容


Meta-settings

  • msg:"description"; 描述字段,报警的时候的一些描述信息,比如某某某攻击等的
  • sid: 1; 签名ID编号 1-
  • rev: 3; 修订版本 1-
  • gid: 2; 组ID
  • classtype:trojan-activity; 查看classification.config文件中的配置,后面有优先级。
  • reference: bugtraq, 123; http://www.securityfocus.com/bid 或者 reference: url, www.info.nl
  • priority:1; 优先级1-255 1-4常用 优先级越小越优先
  • target:[src_ip|dest_ip] 报警时候回上报这个格式的,含义是[攻击源|攻击目标]

Header-Keyword

  • ttl:10 数据包中的ttl
  • ipopts:
    • rr 记录路由
    • eol list最后
    • nop
    • ts
    • sec
    • esec
    • lsrr
    • ssrr
    • satid
    • any
  • sameip;当数据报文的源和目的IP相同时候
  • ip_proto:<name|id>
    • 1 ICMP
    • 6 TCP
    • 17 UDP
  • id:1 每一个IP报文发送后id+1,一个IP报文的多个分片ID一致
  • geoip
    - geoip: src, RU;
    - geoip: both, CN, RU;
    - geoip: dst, CN, RU, IR;
    - geoip: both, US, CA, UK;
    - geoip: any, CN, IR;
  • TCP关键字:
    • ack:0;
    • seq:0;
    • window:55808;
    • 等等...
  • ICMP关键字:
    • itype:8;
    • itype:>10;
    • icode 和itype类似
    • icmp_id 和 icmp_seq
  • fragbits和fragoffset

prefilter 预过滤

prefilter之前的规则属于预过滤规则

payload 关键字

  • content: ”............” ->
    • content:“a|0D|bc”;
    • content:”|61 0D 62 63|";
    • content:”a|0D|b|63|”;
  • pcre:""
    • content:"index.";|http_uri;pcre:"";就可以匹配出content符合 index.的payload
  • nocase; 忽略大小写
  • depth:3 payload出现的具体位置
  • offset:4 便宜量
  • distance:2
    • content:"abc";content:"dev";distance:"1" -> payload:"abcsdev" 匹配成功
  • within:4 判断 payload -> "abcxxxdefxxxddsew" content:"abc";content:"def";within:3 -> 第二个匹配段的结尾与第一个匹配段的结尾的距离在within的的数值之内。
    • content:"abc";content:"def";distance:4;within:9 -> abcxxxxdef 匹配成功 xxxx 距离4 f到从的距离是xxxx+payload2的长度 = 3+4 = 7
  • isdataat:8 看看content结尾字符后面第isdataat位置是否还有数据
  • dsize:345; payload长度,也可以是>或者<
  • rpc 和RPC相关
    • rpc:100009,*,*;
  • replace:"asd"; content:"abvd";replace:"abcd" 替换,只能用于IPS之中
  • fast_pattern 略

HTTP 关键字

请求字段

Keyword Sticky or Modifier Direction
http_uri Modifier Request
http_raw_uri Modifier Request
http_method Modifier Request
http_request_line Sticky Buffer Request
http_client_body Modifier Request
http_header Modifier Both
http_raw_header Modifier Both
http_cookie Modifier Both
http_user_agent Modifier Request
http_host Modifier Request
http_raw_host Modifier Request
http_accept Sticky Buffer Request
http_accept_lang Sticky Buffer Request
http_accept_enc Sticky Buffer Request
http_referer Sticky Buffer Request
http_connection Sticky Buffer Request
http_content_type Sticky Buffer Both
http_content_len Sticky Buffer Both
http_start Sticky Buffer Both
http_protocol Sticky Buffer Both
http_header_names Sticky Buffer Both

响应字段

Keyword Sticky or Modifier Direction
http_stat_msg Modifier Response
http_stat_code Modifier Response
http_response_line Sticky Buffer Response
http_header Modifier Both
http_raw_header Modifier Both
http_cookie Modifier Both
http_server_body Modifier Response
file_data Sticky Buffer Response
http_content_type Sticky Buffer Both
http_content_len Sticky Buffer Both
http_start Sticky Buffer Both
http_protocol Sticky Buffer Both
http_header_names Sticky Buffer Both

以上用法

content:"xxxxxx";http_xxxx;
特例:

  • uricontent:"xxxx";
  • urilen:10 > <也可以
  • http_header 不包含URI部分

流信息关键字

  • flow:to_client 关键字:

    • to_client
    • to_server
    • from_client
    • from_server
    • established
    • not_established
    • stateless
    • only_stream
    • no_stream
    • only_frag
    • no_frag
  • stream_size

    • >
    • <
    • =
    • !=
    • >=
    • <=

文件关键字

  • filename:"a.php";
  • fileext:"jpg";
  • filemagic:"";
  • filestore:[request|response],[file|tx|ssn]
  • filenmd5:[!]filename; filenmd5:md5-blacklist;
  • filesize:5 > < 也可以

阈值

  • threshold: type <threshold|limit|both>, track <by_src|by_dst>, count , seconds
    • threshold: type threshold, track by_src, count 10, seconds 60;
  • detection_filter: track <by_src|by_dst>, count , seconds

DNS关键字

dns_query;content:"域名"

以上是关于suricata的线程和模块功能的主要内容,如果未能解决你的问题,请参考以下文章

Suricata详解

在pfSense上设置Suricata

suricata -- 为Linux设置IPS/内联

(文档翻译)suricata的ips模式

suricata 程序架构

suricata 输出 - syslog 告警兼容性