互联网安全建设从0到1
上QQ阅读APP看书,第一时间看更新

1.4 开源网络入侵检测工具Suricata

Suricata[1]是一款免费、开源、成熟、快速、健壮的网络入侵检测工具,能够进行实时入侵检测(IDS)、入侵预防(IPS)、网络安全监控(NSM)和离线pcap包处理。Suricata使用强大而广泛的规则和签名来检查网络流量,并提供强大的Lua脚本支持来检测复杂的威胁信息。使用标准的输入和输出格式(如YAML和JSON),使用现有的SIEMs、Splunk、Logstash/Elasticsearch/Kibana和其他数据库等工具进行集成,非常简单。Suricata项目和代码由开放信息安全基金会(OISF)拥有和支持,OISF是一个非营利基金会,致力于确保Suricata作为一个开源项目的开发和持续成功。类似工具还有著名的SNORT,两者的规则互相兼容。

想要更好地提升抓包效率,我们不得不提到PF_RING技术,PF_RING是一种新型网络套接字,能显著提高包捕获速度,并且有如下特征:

·可以用于Linux 2.6.32以上的内核。

·可以直接应用于内核,不需要给内核打补丁。

·可以指定上百个头过滤到BPF中。

·可以工作在混杂模式(经过网卡的报文全部可以被捕获到)。

其核心解决方案便是减少报文在传输过程中的拷贝次数,从而提高数据包处理效率。产品分为Vanilla PF_RING(免费版)和使用了零拷贝技术的PF_RING ZC(收费版)。更多内容及其工作原理,可以参其考官方网站:https://www.ntop.org/products/packet-capture/pf_ring/

[1] 官方网站为https://suricata-ids.org/。

1.4.1 Suricata安装

由于Suricata是开源软件,使用方法都靠自己摸索,笔者也是经过很多实验才了解应用方法,下面就先介绍Suricata(standard模式)如何安装。

1)更新系统内核:


yum install kernel-devel

2)安装必需的rpm包:


yum install pcre pcre-devel libyaml libyaml-devel file-devel lz4-devel
jansson-devel cargo deltarpm
yum install gperftools jemalloc jemalloc-devel

3)下载PF_RING安装包并编译内核模块:


git clone https://github.com/ntop/PF_RING.git
cd PF_RING/kernel/
make
make install
cd ../userland
make
make install

4)加载模块。首先看一下pf_ring.ko的位置,命令如下:


find / -name pf_ring.ko

结果如下:

笔者的目录是/usr/lib/modules/1.10.0-957.el7.x86_64/kernel/net/pf_ring/pf_ring.ko。

使用insmod命令加载这个模块:


insmod /usr/lib/modules/1.10.0-957.el7.x86_64/kernel/net/pf_ring/pf_ring.ko

5)设置开机自动加载模块:


modprobe pf_ring (同时写入/etc/rc.local)

此时可以使用lsmod查看是否加载成功:

6)连接系统相关的lib包:


ln -s /usr/local/lib/libpfring* /usr/lib64/
ldconfig

这里需要说明一下,standard模式中是不需要卸载网卡驱动的。只有在高级的ZC模式下,才需要卸载网卡驱动,加载PF_RING编译后的网卡驱动。

7)下载Suricata安装包并编译(以4.1.2为例):


wget https://www.openinfosecfoundation.org/download/suricata-4.1.2.tar.gz
tar zxvf suricata-4.1.2.tar.gz
./configure --prefix=/usr/local/suricata --enable-suricata-update --enable
-pfring
--with-libpfring-includes=/usr/include --with-libpfring-libraries=/
usr/lib64/
make
make install
make install-conf

Suricata主要文件夹简介:

·bin:可执行文件。

·etc:配置文件、参考文件、阈值设置等。

·share:规则文件。

·var:包含suircata的日志文件。

1.4.2 Suricata suricata.yaml配置介绍

suricata.yaml主要有5部分:

·网络配置:包括配置监控网络、内/外部网络、定义端口/端口组等。这里除了HOME_NET要设置成实际网络外,其余采用默认配置即可。

·输出配置:包括各种log的输出,输出到redis设置等。

·通用抓包设置:例如设置抓包网卡,指定bpf过滤器等。

·应用层协议配置:配置应用层的一些参数。

·高级配置:配置运行用户、用户组、内存使用、规则位置、规则加载、报警阈值等高级配置,如果使用了PF_RING技术,那么在这里配置网卡。

我们先注释掉下方所有系统默认规则,先使用自定义规则进行测试。注意,这里默认规则的路径是/usr/local/suricata/etc/suricata/rules。我们新建一条local.rules文件,内容如下:


alert http any any -> any any (msg:"testrule";content:"test.php"; http_uri; sid:99999;)

并在suricata.yaml文件中加载如下规则:

1.启动服务

要启动服务,输入如下命令:


cd /usr/local/suricata
LD_PRELOAD="/usr/lib64/libtcmalloc.so" ./bin/suricata --pfring -c /usr/
local/suricata/etc/suricata/suricata.yaml

可以看到启动成功,没有报错或者告警信息:

此时如访问http://192.168.1.52/test.php,fast.log便会显示告警信息:

说明suricata+pf_ring安装成功!

2.Suricata规则

规则对于Suricata是非常重要的功能,下面我们简单介绍一下Suricata的规则,一条完整的规则由以下部分组成:

·行为(action):规则匹配时的行为,有pass、drop、reject、alert 4种。

·协议:包括4~7层协议。

·方向与端口:包括源地址、源端口与目的地址、目的端口及方向。->表示单向,<>表示双向。

·具体规则:定义了规则的细节、规则的主要部分。

·其他:包括定义规则id、参考、版本及分组等。

一条完整的规则示例如下:


Drop tcp $HOME_NET any -> $EXTERNAL_NET any (msg:"ET TROJAN Likely Bot Nick in IRC (USA +..)"; flow:established,to_server; flowbits:isset,is_proto_irc; content:”NICK"; pcre:”/NICK .*USA.*[0-9]{3,}/i"; reference:url,doc.emergingthreats.net/2008124; classtype:trojan-activity; sid:2008124; rev:2;)

下面介绍具体规则中一些常见的主要参数。

元关键字:

·msg:自定义的规则名字、标识规则。

·sid:规则id。

·gid:规则分类id。

·classtype:标记规则分类。

·reference:标记相关参考文献。

IP关键字:

·ttl:检测ttl。

·sameip:检测源地址与目的地址是否一致。例如:


alert ip any any -> any any (msg:"GPL SCAN same SRC/DST"; sameip;
reference:bugtraq,2666; reference:cve,1999-0016; reference:url,www.cert.
org/advisories/CA-1997-28.html; classtype:bad-unknown; sid:2100527; rev:9;)

·fragbits:检测分片位,M为分片,D为不分片,R为保留位,例如检测分片:


fragbits:M

·Mfragoffset:检测分片偏移量。可以使用<、>或者!表明小于、大于或不存在指定数值,例如,检测有分片,且偏移量大于0,如下所示。


fragbits: M; fragoffset: >0

TCP关键字:

·seq:检测TCP序列号。

·ack:检测ack序列号。

·window:检测TCP窗口大小。

Payload关键字:

·content:检测数据包里包含的关键字,同时支持十六进制表示方法,例如,字母a可以用|61|表示;“:”可以用|3A|表示。另外,以下三个字符必须被转义:“;”“\”“"”。

·nocase:不区分大小写。

·depth:后面的数字表示检查数据包开头的字节数,如图1-18所示。

·offset:后面的数字表示检查数据包之后的字节数,如图1-19所示。

图1-18 depth关键字示意

图1-19 offset关键字示意

·distance:检测两个关键字之间相距的字节数,如图1-20所示。

图1-20 distance关键字示意

·pcre:Perl语言兼容的正则表达式,格式为pcre:"/<regex>/opts"。

flowbits关键字:

·flowbits:由两部分组成,第一部分表明执行的操作,第二部分是这个flowbit的名字。如果有多个数据包属于一个流,Suricata会将这些流量保存在内存中(可以通过suricata.yaml文件配置内存大小)。

可用的操作为:

·flowbits:set,name:设置初始条件。

·flowbits:isset,name:符合初始条件,则进行告警。

·flowbits:unset,name:取消设置条件。

·flowbits:toggle,name:逆置条件。

·flowbits:isnotset,name:如果未设置条件,则进行告警。

·flowbits:noalert:不进行告警。

其实,进行flowbits设置的主要目的是提高告警效率。例如,如果一个数据包里边有两个特征关键字key1与key2(也可以为其他条件),可以先使用“flowbits:set,name,”匹配key1关键字,然后在匹配key1的基础上再使用“flowbits:isset,name”;匹配key2这个关键字,如果匹配再进行告警,否则如果连第一阶段的key1都不满足,那就不用再去匹配key2了,这样可以大大提高数据包的处理效率。这本质上是用了内存换取时间的方式。我们来看实际的例子:


alert tcp any any -> any any (msg:"testflowrule1";content:"step1";flowbits:
set,flowtest;flowbits: noalert;sid:10000;)
alert tcp any any -> any any (msg:"testflowrule1";flowbits:isset,flowtest;
content:"step2";sid:10001;)

·sid 10000:如果关键字仅仅匹配到了step1,不告警,设置初始化条件,名字为flowtest,进行进一步匹配。

·sid 10001:在匹配了step1的情况下,又匹配到数据流中有step2关键字即告警,如下所示。

在上面的代码中分别发送了三次数据,因为第一次发送的step1step3和第三次发送的step3step2不符合规则,均不会产生告警,只有第二次发送的step1step2符合规则,会产生告警:

flow关键字:

标明数据流方向,可以有以下选项之一,或组合使用:to_client、to_server、from_client、form_server、established、not_established、only_frag,例如flow:to_client、flow:to_server或established。

HTTP关键字:

·http_method:检测HTTP方法,例如POST、GET、HEAD等。

·http_uri and http_raw_uri:检测HTTP中的uri信息。

·http_cookie:检测HTTP中的cookie信息。

·http_stat_code:检测HTTP状态码信息。

由于Surcicata关键字众多,本书无法一一介绍,如果想更加深入地了解,建议学习TCP/IP,了解数据包结构,这样可以更好地利用Suricata的关键字,设置更加精确的告警,更多关键字介绍可以参考官方文档https://suricata.readthedocs.io/en/suricata-4.1.4/rules/index.html

3.Suricata文件捕获

Suricata有一个很重要的功能,就是从流量中对文件进行捕获。启用这个功能,需要开启文件保存功能,并进行相关配置。注意,这里可能会有两个地方都有-file-store,要选择最后那个,如下所示:

再建立一条规则:


alert http any any -> any any (msg:"testfilestore"; fileext:"txt";filestore;sid:99999;)

这时,如果有txt文件被访问,文件就会被记录下来:

4.Suricata日志

Suricata日志功能包括:

·fast.log:记录了流量中匹配到签名的告警信息,包括时间、五元组信息、告警id、告警信息。

·eve.json:记录了告警信息、流信息、协议解析的信息(例如HTTP、DNS等),以及攻击的payload等。

5.Suricata规则更新管理

Suricata更新规则可以使用两个工具进行:suricata-update以及Oinkmaster,这里主要介绍suricata-update如何使用。默认情况下Suricata 4.1以上版本都会自带suricata-update工具,如果安装后没有该工具,可以使用pip install--upgrade suricata-update进行安装,安装完成后,将suricata-update文件复制到Suricata的bin目录下:

此时,执行一次suricata-update:

可以看到suricata-update使用的文件夹为/usr/local/suricata/var/lib/suricata/rules,并将规则写入/usr/local/suricata/var/lib/suricata/rules/suricata.rules中(不同的安装方式路径不同,也可以使用-o参数指定路径,可以根据实际情况调整),修改suricata配置文件suircata.yml,将默认的rules路径指向这里,并在rule-files下增加-suricata.rule,注释掉其他规则并保存,如下所示:

还可以更新规则源:

列出更新源列表:

启用或禁用规则源:


suricata-update enable-source(disable-source)规则源名称

例如,启用ptresearch/attackdetection的规则源:

列出当前使用的规则源:


suricata-update list-enabled-sources

更新规则源后,重新运行suricata-update命令:

更新完成后,可以根据提示运行surcata-T命令测试,通过测试后,可以重启Suricata,或用kill-USR2$(pidof suricata)命令发送USR2信号来重新加载Suricata规则:

如果某条规则属于误报,或者想禁用该规则,可以建立disable.conf文件:

可使用写sid、正则表达式或者规则组名的方式禁用规则。例如,上例中禁用2019401这条规则,需要去掉“#”,配置完成后,使用命令suricata-update-disable-conf disable.conf(注意路径),重启Suricata即可禁用该规则。

6.小结

Suricata还有很多功能这里没有介绍,读者可以通过官网看到更多内容。另外,除了Suricata外还有其他优秀的NIDS工具,工作原理大多异曲同工,主要技术核心为TCP/IP,因此针对攻击规则的设定,很大程度取决于对TCP/IP的理解与认知。因此希望读者打好基础,这样才能更好地使用这类技术,精准发现攻击。

在第6章中,会将Suricata与日志分析工具ELK(Elasticsearch、Logstash、Kibana)结合使用,使告警日志可视化。