本文最后更新于 2024-09-05,文章内容可能已经过时。

(NIDS)suricata安装和配置详解

1、何为NIDS?

​ (百度百科)网络入侵检测系统(network intrusion detection system,NIDS),是指对收集漏洞信息、造成拒绝访问及获取超出合法范围的系统控制权等危害计算机系统安全的行为,进行检测的软件与硬件的组合基于流量的入侵检测系统(NIDS)

即基于流量的入侵检测系统(NIDS)

  • HIDS-----NIDS
  • HIDS基于主机的入侵检测
  • 主机日志、命令、安全评估、配置文件等等
    • 主机日志:
      • apache的post请求主体内容在access日志中是没有,开启apache的调试模式,post的主体内容可以在error日志中显示,但是会产生大量的调试信息,耗费服务器的资源,生成环境下一般不开
      • MySQL的查询日志,默认也是不开的
  • 从主机层面无法检测的内容,就只能从流量层面来进行检测(NIDS)(NIPS)
  • WAF:一套基于流量的入侵检测响应系统,但是只对http和https流量进行检测

image-20240902172529121

image-20240902172542133

  • 入侵检测系统(IDS):基于流量的入侵检测系统,为了保证效率,采用旁挂方式来进行检测

    HIDS : 主机 检测 旁挂

    NIDS : 流量 检测 串联

  • 入侵防御系统(IPS):基于流量的入侵检测系统并进行响应,因为要做到响应,一般采用串联方式部署

  • 数据库审计系统(DAS):基于流量的审计系统,只针对数据库的语句进行审计

image-20240902172626776

2、Suricata简介

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

二、主要特点

1.IDS/IPS – Suricata 是一个基于规则的入侵检测和防御引擎,它利用外部开发的规则集(例如Talos规则集和新兴威胁 Suricata 规则集)来监控网络流量中是否存在任何恶意活动、策略违规和威胁。
2.自动协议检测——Suricata 引擎自动检测 HTTP 和 HTTPS 等协议。任何端口上的 FTP 和 SMB,并应用适当的检测和日志记录逻辑。这在检测恶意软件和 CnC 通道时派上用场。
3.Lua 脚本——Suricata 可以调用提供高级恶意软件检测的Lua脚本,以检测和解码原本难以检测的恶意软件流量。
4.多线程——Suricata在确定网络流量时提供速度和重要性。该引擎旨在应用现代多核硬件芯片组提供的增强处理能力。

三、工作模式

  1. single模式

image-20240902172823028

single只支持一个网卡设备,只有一个work线程

  1. work模式

image-20240902172846694

Work工作模式,每个网卡默认对应cpu数个工作线程(或者按照配置文件配置的线程数),每个工作线程取对应的网卡队列中数据包

  1. autofp工作模式

image-20240902172928659

3、部署安装Suricata

  • 安装
sudo yum install -y epel-release yum-plugin-copr
sudo yum copr enable @oisf/suricata-7.0					#导入存储库可能会失败,可以不用管
sudo yum install suricata								#如果导入存储库失败,安装的默认是4.1.10版本
  • 查看软件包名和安装路径
rpm -qa suricata  # 查看软件包名

rpm -ql 软件包名  # 查看安装路径
  • 安装完成后直接启动会报错
启动命令:
suricata -c /etc/suricata/suricata.yaml -i ens33  
-c   表示指定配置文件
-i	 表示指定监听的网卡接口或IP地址 ens33 : 这是监听的网卡 或者写主机的IP

image-20240902173121746

解决办法:

查看配置文件vi /etc/suricata/suricata.yaml

image-20240902173147388

创建规则文件并写入告警规则

cd /var/lib/suricata
rm -f  suricata.rules
mkdir rules
cd rules
touch suricata.rules

写入一条告警规则到我们的规则文件

alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"出现404错误"; content: "404"; http_stat_code; sid:561001;)	
  • 修改主配置文件vim /etc/suricata/suricata.yaml

下图是/etc/suricata/suricata.yaml中的IP和端口配置

image-20240902173312661

  • 配置完成后进行启动
suricata -c /etc/suricata/suricata.yaml -i ens33  
-c   表示指定配置文件
-i	 表示指定监听的网卡接口或IP地址 ens33 : 这是监听的网卡 或者写主机的IP
  • 查看告警日志信息
tail -f /var/log/suricata/fast.log

Http的请求方式 :

get (查询)、post (插入)、put(修改)、delete(删除)

trace、options

form的提交的媒体类型 :

  1. application/x-www-form-urlencoded 提交正常数据
  2. application/json 提交json的数据
  3. multipart/form-data 文件上传的提交类型

4、规则编写

以下是一些规则编写的格式:

  • 格式
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"出现404错误"; content: "404"; http_stat_code; sid:561001;rev:1;)

第1个字段:动作,取值alert(告警),drop(丢弃,无法单独使用,需要和iptalbes进行结合)

第2个字段:协议,取值网络层及其上层协议(网络层、传输层、应用层协议)

第3和6字段:地址,字段3一般是源IP,字段6一般是目的IP

第4和7字段:端口,字段4一般是源IP携带的端口,源IP携带的端口普遍为随机,所以一般取值any;字段7是目的IP的端口,一般是服务器所开放的端口,固定编写

第5个字段:方向,取值(->:表示请求,<>:表示双向)

后面()包裹:具体的规则编写

msg:触发规则后的提示信息
sid:唯一标识一条规则的
rev:版本号
classtype:规则具体分类
priority:优先级(数字越小,越严重)
content:检索的关键字
nocase:不区分大小写

另一个规则的例子:

alert http $HOME_NET any -> $EXTERNAL_NET any (msg:"HTTP Content-Type Request Example"; flow:established,to_server; http.content_type; content:"multipart/form-data|3b 20|"; startswith; classtype:bad-unknown; sid:95; rev:1;)
flow:established,to_server; #意思是建立连接成功
http.content_type;#检测请求头中content_type的内容
content:"multipart/form-data|3b 20|";startswith;  # content_type内容中以multipart/form-data开头,注意:两个竖线中间的部分是特殊字符,要使用16进制,并且放在两个竖线中间

5、检测web攻击

  • 目录扫描:多次404错误,疑似web扫描攻击
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"疑似web目录扫描"; http.stat_code; content:"404"; classtype:dir-scan; threshold: type threshold, track by_src, count 5, seconds 20; sid:561002; rev:1;)
  • sql注入

get型的:

# get请求,通过uri判断sql注入
alert http $EXTERNAL_NET any-> $HOME_NET 80 (msg:"GET请求SQL注入"; http.uri; pcre:"/union|select|and|user()|database()|information_schema/i";classtype:sql-injection; sid:561003;rev:1;)

post型的:

# post请求,通过request_body判断sql注入
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"POST请求SQL注入"; http.request_body; pcre:"/union|select|and|user()|database()|order|20| by|information_schema/i"; classtype:sql-injection; sid:561004;rev:1;)
  • xss攻击
# xss攻击检测
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"xss攻击告警"; http.uri; pcre:"/<script|javascript/i"; sid:561005;)
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"xss攻击告警"; http.uri; content:"<script"; classtype:xss-attack;sid:561006;rev:1;)
  • ssrf
# ssrf攻击检测
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"SSRF攻击告警"; http.uri; content:"file=gopher"; sid:561007;)
  • web爆破(针对特定业务场景)
# web爆破
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"web爆破攻击检测"; http.uri; content:"login.php"; http.method; content:"POST"; threshold: type threshold, track by_src, count 5, seconds 20;  sid:561008;)
  • 文件上传预警

Http的请求方式 :

get (查询)、post (插入)、put(修改)、delete(删除)

trace、options

文件上传请求的形式:

form的提交的媒体类型 : (enctype)

  1. application/x-www-form-urlencoded 提交正常数据
  2. application/json 提交json的数据
  3. multipart/form-data 文件上传的提交类型
<form action="url" method="post" enctype="multipart/form-data">

	username : <input type="text" name="uname" />  <p />
    
    头像  :<input type="file" name="myImg"  />  <p />
    
    <input  type="submit"  value="提交"  />
</form>

利用suricata预警文件上传 :

  1. 文件上传 必须是POST请求
  2. 文件上传他的媒体类型必须是 multipart/form-data (Content-Type)
# 检测文件上传 
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"检测到文件上传"; http.method; content:"POST";http.content_type;content:"multipart/form-data";nocase;sid:561008;)

  • 文件上传预警,检测是否有木马
# 检测文件中是否 有木马
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"检测到木马文件上传"; http.method; content:"POST";http.content_type;content:"multipart/form-data";nocase; http.request_body;pcre:"/assert|eval|exec/i";sid:561008;)

实际测试

环境:centos7 (192.168.52.5)

搭建好了lampp,在/opt/lamm/htdocs中搭建了pikachu靶场

Suricata 4.1.10

配置文件目录:

规则文件:/var/lib/suricata/rules/suricata.rules

核心配置文件:/etc/suricata/suricata.yaml

编写配置文件

vi /var/lib/suricata/rules/suricata.rules

测试目录扫描

# 目录扫描
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"疑似web目录扫描"; http.stat_code; content:"404"; classtype:dir-scan; threshold: type threshold, track by_src, count 5, seconds 20; sid:561002; rev:1;)

image-20240902180052514

保存退出后验证

 suricata -c /etc/suricata/suricata.yaml -T

启动suricata:

suricata -c /etc/suricata/suricata.yaml -i ens33

监听日志:

tail -f /var/log/suricata/fast.log 

启动lampp,在页面中输入错误的url地址后,连续刷新

image-20240902180548831

测试sql注入

get型:

vi /var/lib/suricata/rules/suricata.rules

# GET请求,通过URI判断SQL注入
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"GET请求SQL注入"; http.uri; pcre:"/union|select|and|user()|database()|information_schema/i"; classtype:sql-injection; sid:561003; rev:1;)

image-20240902181128727

保存退出后验证

 suricata -c /etc/suricata/suricata.yaml -T

启动suricata:

suricata -c /etc/suricata/suricata.yaml -i ens33

监听日志:

tail -f /var/log/suricata/fast.log 

启动lampp,到pikaqiu靶场页面的sql注入一页

http://192.168.52.5/pikachu/vul/sqli/sqli_str.php#

image-20240902181422511

随便输入一条sql语句测试

?and 1=1-- -

点击查询后查看日志信息:

image-20240902181520672

post型

vi /var/lib/suricata/rules/suricata.rules

# post请求,通过request_body判断sql注入
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"POST请求SQL注入"; http.request_body; pcre:"/union|select|and|user()|database()|order|20| by|information_schema/i"; classtype:sql-injection; sid:561004;rev:1;)

image-20240902181800271

同样保存退出后验证,再启动suricata,监听日志

回到pikachu靶场页面,到post型sqk注入页面测试:

http://192.168.52.5/pikachu/vul/sqli/sqli_id.php

image-20240902182309983

点击查询后查看日志信息;

image-20240902182331429

测试xss攻击

vi /var/lib/suricata/rules/suricata.rules

# xss攻击检测
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"xss攻击告警"; http.uri; pcre:"/<script|javascript/i"; sid:561005;)
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"xss攻击告警"; http.uri; content:"<script"; classtype:xss-attack;sid:561006;rev:1;)

同样保存退出后验证,再启动suricata,监听日志

image-20240902182529473

到pikachu的xss攻击的页面进行测试

image-20240902182859116

输入简单的xss脚本<script>alert(1)</script>后查询,查看日志

image-20240902182949160

测试ssrf

# ssrf攻击检测
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"SSRF攻击告警"; http.uri; content:"file=gopher"; sid:561007;)

image-20240902183028450

同样保存退出后验证,再启动suricata,监听日志

到pikachu靶场的ssrf页面进行测试

image-20240902183703562

查看日志:

image-20240902183724319

测试web爆破(针对特定业务场景)

# web爆破
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"web爆破攻击检测"; http.uri; content:"login.php"; http.method; content:"POST"; threshold: type threshold, track by_src, count 5, seconds 20;  sid:561008;)

image-20240902183753667

同样保存退出后验证,再启动suricata,监听日志

在靶机页面输入url测试,这里没有login.php没有关系,post参数随便填,连续Execute提交五次(20秒内)

image-20240902185258128

查看日志信息:

image-20240902185407713

测试文件上传

# 检测文件上传 
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"检测到文件上传"; http.method; content:"POST";http.content_type;content:"multipart/form-data";nocase;sid:561008;)

image-20240905011120051

测试文件上传是否有木马

# 检测文件中是否 有木马
alert http $EXTERNAL_NET any -> $HOME_NET 80 (msg:"检测到木马文件上传"; http.method; content:"POST";http.content_type;content:"multipart/form-data";nocase; http.request_body;pcre:"/assert|eval|exec/i";sid:561008;)

对冰蝎流量的预警

image-20240905020553598

通过wireshark 抓包 ,抓取到他的内容,通过http的stream流 :

image-20240905020718480

image-20240905020756702

# 请求告警
alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"检测到了疑似来自冰蝎的攻击,请及时检查"; http.request_body;content:"3Mn1yNMtoZViV5wotQHPJ";sid:561010;)

alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"检测到了疑似来自冰蝎的攻击,请及时检查~~~~"; content:"3Mn1yNMtoZViV5wotQHPJ";http_request_body;sid:561010;)

image-20240905023156480

冰蝎的流量是随时更换的,要更具具体情况将特殊字符转换成16进制

image-20240905024308810

对菜刀流量的预警

构建一句话木马,菜刀进行连接

<?php @eval($_POST['a']);?>

image-20240905024914454

wireshark抓取中国菜刀的流量

image-20240905025210979

image-20240905024456865

Form item: “” = “@eval\001(base64_decode($_POST[z0]));”

可以很清晰的看到菜刀的流量是分为三段(其中a为设置的密码,可能有变化,z0和z1都不会改变)a=,z0=,z1=,每一段后面都有一大串加密的密文

编写规则

alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"检测到了疑似来自菜刀的攻击,请及时检查"; http.request_body;pcre:"/|40|eval|01 28|base64_decode/i";sid:561012;)

image-20240905030900271

对蚁剑流量的预警

同样构造一句话木马,<?php @eval($_POST['a']);?>,蚁剑进行连接

image-20240905031359484

wireshark进行抓取流量,分析流量特征

image-20240905032021765

 [truncated]Form item: "a" = "@ini_set("display_errors", "0");@set_time_limit(0);$opdir=@ini_get("open_basedir");if($opdir) {$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);$oparr=preg_split(base64_decode("Lzt8Oi8="),$opdir);@array_push($oparr,
    Key: a
    Value [truncated]: @ini_set("display_errors", "0");@set_time_limit(0);$opdir=@ini_get("open_basedir");if($opdir) {$ocwd=dirname($_SERVER["SCRIPT_FILENAME"]);$oparr=preg_split(base64_decode("Lzt8Oi8="),$opdir);@array_push($oparr,$ocwd,sys_g

a=%40ini_set(%22display_errors%22%2C%20%220%22)%3B%40set_time_limit(0)%3B%24opdir%3D%40ini_get(%22open_basedir%22)%3Bif(%24opdir)%20%7B%24ocwd%3Ddirname(%24_SERVER%5B%22SCRIPT_FILENAME%22%5D)%3B%24oparr%3Dpreg_split(base64_decode(%22Lzt8Oi8%3D%22)%2C%24opdir)%3B%40array_push(%24oparr%2C%24ocwd%2Csys_get_temp_dir())%3Bforeach(%24oparr%20as%20%24item)%20%7Bif(!%40is_writable(%24item))%7Bcontinue%3B%7D%3B%24tmdir%3D%24item.%22%2F.a88e5676%22%3B%40mkdir(%24tmdir)%3Bif(!%40file_exists(%24tmdir))%7Bcontinue%3B%7D%24tmdir%3Drealpath(%24tmdir)%3B%40chdir(%24tmdir)%3B%40ini_set(%22open_basedir%22%2C%20%22..%22)%3B%24cntarr%3D%40preg_split(%22%2F%5C%5C%5C%5C%7C%5C%2F%2F%22%2C%24tmdir)%3Bfor(%24i%3D0%3B%24i%3Csizeof(%24cntarr)%3B%24i%2B%2B)%7B%40chdir(%22..%22)%3B%7D%3B%40ini_set(%22open_basedir%22%2C%22%2F%22)%3B%40rmdir(%24tmdir)%3Bbreak%3B%7D%3B%7D%3B%3Bfunction%20asenc(%24out)%7Breturn%20%24out%3B%7D%3Bfunction%20asoutput()%7B%24output%3Dob_get_contents()%3Bob_end_clean()%3Becho%20%22fd%22.%22466%22%3Becho%20%40asenc(%24output)%3Becho%20%228d99%22.%2238ec%22%3B%7Dob_start()%3Btry%7B%24D%3Dbase64_decode(substr(%24_POST%5B%22v0cdf6ee862887%22%5D%2C2))%3B%24F%3D%40opendir(%24D)%3Bif(%24F%3D%3DNULL)%7Becho(%22ERROR%3A%2F%2F%20Path%20Not%20Found%20Or%20No%20Permission!%22)%3B%7Delse%7B%24M%3DNULL%3B%24L%3DNULL%3Bwhile(%24N%3D%40readdir(%24F))%7B%24P%3D%24D.%24N%3B%24T%3D%40date(%22Y-m-d%20H%3Ai%3As%22%2C%40filemtime(%24P))%3B%40%24E%3Dsubstr(base_convert(%40fileperms(%24P)%2C10%2C8)%2C-4)%3B%24R%3D%22%09%22.%24T.%22%09%22.%40filesize(%24P).%22%09%22.%24E.%22%0A%22%3Bif(%40is_dir(%24P))%24M.%3D%24N.%22%2F%22.%24R%3Belse%20%24L.%3D%24N.%24R%3B%7Decho%20%24M.%24L%3B%40closedir(%24F)%3B%7D%3B%7Dcatch(Exception%20%24e)%7Becho%20%22ERROR%3A%2F%2F%22.%24e-%3EgetMessage()%3B%7D%3Basoutput()%3Bdie()%3B


image-20240905032626512

编写规则:

alert http $EXTERNAL_NET any <> $HOME_NET 80 (msg:"检测到蚁剑的流量特征";http.request_body;pcre:"/function|20|asoutput|28|/i";sid:5001002;)

image-20240905032350949

ICMP流量检测

ICMP有四个特征 :其中我们使用 itype消息类型 :

匹配时选择使用 8以上的类型 。

alert icmp $EXTERNAL_NET any <> $HOME_NET any (msg:"icmp流量检测"; itype:8;threshold: type threshold,track by_src,count 10,seconds 20;sid:561013;)

PING目标主机(ping使用的就是ICMP协议)

image-20240905033307109

TCP协议检测

(1)、预警TCP连接过高(全连接)

编写规则:

alert tcp $EXTERNAL_NET any <> $HOME_NET any (msg:"tcp连接过高,请及时检测!(全)"; flow:established,to_server;threshold: type threshold,track by_src,count 20,seconds 10;sid:561014;)

测试:

在kali中使用如下命令安装wrk:
apt install wrk

利用 wrk模拟攻击 :
wrk -c 300 -t 4 -d 600 http://192.168.91.10/pikachu

-c, 跟主机保持连接数量
-d, 测试持续时间
-t, 开启线程数

image-20240905034025500

日志信息:

image-20240905034016553

Mysql爆破的预警

加一条对mysql端口的检测vi /etc/suricata/suricata.yaml

image-20240905034624439

MySQL爆破检测

Suricata默认并没有提供对MySQL的应用层协议的支持,所以只能使用TCP协议。

#MySQL登录失败
alert tcp any any <> any $MYSQL_PORTS (msg:"MySQL登录失败"; content:"Access denied for user"; nocase; sid:5620021;)

#MySQL登录失败
alert tcp any any <> any $MYSQL_PORTS (msg:"MySQL登录失败"; content:"|41 63 63 65 73 73 20 64 65 6e 69 65 64 20 66 6f 72 20 75 73 65 72|"; nocase; sid:5620028;)

#MySQL爆破攻击
alert tcp any any <> any $MYSQL_PORTS (msg:"MySQL爆破攻击"; content:"Access denied for user"; nocase; threshold: type threshold, track by_src, count 5, seconds 10; sid:5620020;)


image-20240905035212225

MySQL木马写入

#进入msql,use mysql,执行如下
select "<?php eval($_POST['code']); ?>" into outfile "/opt/shell.php";

编写规则

alert tcp any any <> any $MYSQL_PORTS (msg:"MySQL木马写入"; content:"into outfile"; nocase; pcre: "/eval|assert|system|_POST|_GET/i"; sid:5620004;)

image-20240905035815260

SSH连接和爆破预警

alert ssh any any <> $HOME_NET 22 (msg:"SSH登录"; content: "|15 00 00 00 00 00 00 00 00 00 00|"; sid:5622001;)
alert ssh any any <> $HOME_NET 22 (msg:"SSH爆破"; content: "|15 00 00 00 00 00 00 00 00 00 00|"; threshold: type threshold, track by_src, count 5, seconds 20; sid:5622002;)

其他终端ssh连接,多试几次后查看日志:

image-20240905040023452

抓取流量后可以看到特征

有很多New Keys

image-20240905040152346

最后一段可以看到尝试过的密码信息

image-20240905040216911