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)结合使用,使告警日志可视化。