一. 概述
suricata是一款开源的流量检测引擎,支持实时入侵检测(IDS)、内联入侵预防(IPS)、网络安全监控(NSM)和离线pcap处理,通过编写suricata配套的snort规则能够对实时的网络流量进行威胁检测,及时发现网络流量中存在的威胁和风险。以下针对实施入侵检测的snort规则编写进行方法的梳理。
二. 规则组成及常用字段说明
一条完整的suricata snort规则主要分为三部分,动作(action)、规则头(header)、规则可选项(options)。如下图所示:
红色部分表示动作,绿色部分表示头,蓝色部分表示规则可选项。
2.1.动作(action)
当snort规则命中流量中的关键数据是,需要执行的操作,主要有告警动作(alert)、丢弃动作(drop)。实时入侵检测以威胁告警为主,规则使用的是alert字段。
2.2.规则头(header)
主要定义匹配的网络流量的协议、IP地址、端口、流量方向。
2.2.1. 规则头协议
支持的基础协议为:tcp、udp、icmp、ip。更加上层的协议为:
http、ftp、tls (包括ssl)、smb、dns、dcerpc、ssh、smtp、imap、msn、modbus (默认关闭该协议的支持)、dnp3 (默认关闭该协议的支持)、enip (默认关闭该协议的支持)、nfs (默认关闭该协议的支持)、ikev2 (默认关闭该协议的支持)、krb5 (依赖rust语言环境)、ntp (依赖rust语言环境)、dhcp (依赖rust语言环境)。
2.2.2. IP地址和方向
IP地址支持以常量、变量、范围域、非运算符方式来定义匹配流量,参考:
示例 | 解释 |
---|---|
!1.1.1.1 | 所有的IP地址除去1.1.1.1 |
![1.1.1.1, 1.1.1.2] | 所有的IP地址除去1.1.1.1,1.1.1.2 |
$HOME_NET | 在suricata.yaml配置文件中设置的局域网范围,IP地址变量 |
[$EXTERNAL_NET, !$HOME_NET] | 外部网络变量 除去局域网变量 |
[10.0.0.0/24, !10.0.0.5] | 所有10.0.0.0/24(10.0.0.1-10.0.0.255)网段的ip 除去10.0.0.5 |
"->" 表示流量的方向,流量流向箭头指向的方向。
"<>" 表示双向流量都可以进行匹配。
端口与IP地址书写配套使用,支持常量,变量,任意端口的匹配,参考:
示例 | 解释 |
---|---|
[80, 81, 82] | 匹配80,81,82中的任意端口 |
[80: 82] | 匹配从80到82之间的任意端口 |
[1024: ] | 匹配1024一直到65535的最大端口 |
!80 | 匹配所有端口除去80 |
[80:100,!99] | 匹配80到100端口,除去99端口 |
[1:80,![2,4]] | 匹配1到80端口,除去2到4端口 |
$HTTP_PORTS | 匹配在suricata.yaml配置文件中设置$HTTP_PORTS对应的端口 |
2.3.规则可选项(options)
对于规则可选项部分(options)部分有以下常用字段。
2.3.1. sid
snort规则的编号,确保每条规则编号的唯一性
2.3.2. rev
规则的版本,默认使用1,如果规则有调整,可以增加1
2.3.3. reference
规则相关信息,如参考链接等
2.3.4. classtype
规则分类,在classification.config中进行配置使用,确保classification.config存在对应规则类别,否则规则将无法生效。
classification.config内容配置示例:
config classification: web-application-attack,Web Application Attack,1config classification: not-suspicious,Not Suspicious Traffic,3
2.3.5. flow
数据流状态,从服务端到客户端,常用值如下:
to_client
流量数据从服务端到客户端
to_server
流量数据从客户端到服务端
from_client
流量数据从客户端来 (与to_server效果相同).
from_server
流量数据从服务端来 (与to_client效果相同).
established
匹配已经建立连接的流量数据,对于tcp协议,为三次握手之后的流量数据,对于udp协议,为两端都存在数据传输之后的流量数据.
not_established
匹配未建立连接的流量数据,该值可以用户检测端口扫描行为,端口扫描存在大量的未开放端口,因此都不能正常建立连接.
stateless
匹配已经建立为为建立连接的流量数据,这个应该是用来约束流数据或者报文数据协议的,一般指tcp/udp协议.
2.3.6. target
攻击目标,可选择值,src_ip|dest_ip,如果被攻击者是源ip,则target:src_ip,默认被攻击者是目的ip
2.3.7. msg
规则信息说明,可以在规则中丰富对规则的说明描述。例如,某cve编号对应漏洞的检测规则,某个木马家族名称对应的上线包等
2.3.8. content
需要匹配的网络流量。支持16进制及明文字符串匹配,使用示例:
content:"a|0D|bc";
content:"|61 0D 62 63|";
content:"a|0D|b|63|";
默认content匹配的内容为字符串敏感,
2.3.9. nocase
nocase与content配套使用,申明content大小写字符串不敏感,使用示例:
content: "abc"; nocase;
2.3.10. offset
匹配网络流量的偏移位置。偏移位置起始位置为标准协议头之后的数据载荷payload,使用示例:
content:"def"; offset:3; depth:3;
2.3.11. depth
匹配网络流量的长度,一般与offset字段搭配使用,使用示例:
2.3.12. distance
与content配套使用,本次匹配内容与上次匹配payload内容的间距,同时确保不同的content匹配内容存在匹配的顺序,distance生效的content为距离distance最近的左侧content。举例:
content:"abc"; content:"def";distance:0;
2.3.13. pcre
正则表达式匹配,遵循标准正则表达式的书写方法,此处不做展开。相关链接。https://redmine.openinfosecfo...
示例:
pcre:"/<regex>/opts";
/i表示正则表达式字符串大小写不敏感。
2.3.14. dsize
匹配的通信流量payload大小。示例:
dsize:>268; payload大于268 字节
dsize:<268; payload小于268 字节
dsize:268; payload等于268 字节
dsize:200<>268; payload在200字节和268字节之间
三. 常用snort威胁检测规则示例分析
当拿到威胁流量pcap包后,要提取snort规则,首先需要分析通信包的具体内容,从中提取固定的可以作为通信特征的标识。以下将选取两种场景进行pcap通信包的分析与特征规则提取。
3.1.木马通信上线包
3.1.1. wireshark数据流的跟踪
使用Wireshark流量分析工具打开离线pcap包,
如果木马使用TCP协议进行通信,一般上线包的会出现在TCP 三次握手之后,因此可以对TCP三次握手之后的数据包进行查看和分析,要获取整个木马通信的数据流可以使用WireShark的数据流跟踪功能,如下图所示:
使用追踪功能后可以得到和本次上线通信连接有关的所有数据包数据,如下图所示:
3.1.2. payload载荷特征分析
使用数据流追踪得到了可读的字符串流数据,红色数据表示socket客户端向服务端发送的数据,蓝色数据表示socket服务端向客户端的返回数据。通过对字符串流数据的观察,socket客户端也就是木马程序像服务端上传了操作系统、CPU性能等计算机配置数据,这个是典型的获取计算机配置并进行上传的木马上线行为。下方重复出现的信息,疑似木马的向控制端发送的心跳包。可以使用WireShark查看每个通信包的大小以及服务端的端口如下图所示:
3.1.3. snort通信特征提取分析
alert:将该规则定义为发生告警动作的规则。
tcp:通过抓包分析,木马通信属于tcp协议。
any(ip):客户端为任意ip。(*如果重点监测内网木马上线,可以将any换成,$HOME_NET,缩小匹配范围、控制精度有利于降低规则的误报,同时要结合snort规则的使用场景,如果snort规则检测的目标是蜜罐服务,suricata引擎(实时入侵检测功能)部署在蜜罐系统处,非大流量出口则可适当放宽规则扩大检出范围,如果位于大流量并且存在大量白流量的流量口,则需要更加精确的控制规则)。
any(port):客户端为任意端口
->:网络数据流向。
any(ip):服务端为任意ip。通过分析得到的服务端IP和端口可以作为C2 IOC情报,本次分析的PCAP包为生成器生成,C2端属于演练环境IP,不做IOC提取。
any(port):服务端为任意端口,木马控制端的端口同家族存在一些相似性,在大流量的环境下,可以控制木马控制端端口的精度,采用精确的木马控制端端口,例如:48080,如果指定某些常用的高位端口范围,例如:[40000:60000]
msg:规则相关说明及附件信息木马家族信息等,通过病毒检测引擎已经明确产生该通信包的家族为Dofloo家族。
content:"|56 45 52 53 4F 4E 45 58 3A 4C 69 6E 75 78|"; "VERSONEX"的16进制表达方式。
offset:0; 偏移为0,从载荷payload处开始匹配
depth:14; 匹配深度为14个字节
content:"|4D 48 7A 7C|"; "MHz|"的16进制表达方式"
pcre: "/MHz|[0-9]{1,}MB|[0-9]{1,}MB|Hacker/i"; 正则表达是匹配可变的数字配置,配置单位为固定值保持不变,Hacker为固定值保持不变,大小写不明感
distance:0; 配置相关匹配内容的顺序出现在 VERSIONEX之后
dsize: < 1025; 载荷payload的大小1025个字节
sid:10017115; 规则id
flow:established,to_server; 流量方向为socket客户端到服务端,并且匹配已经建立连接的流量。
target: src_ip; 由于木马上线包是被控制的受害机器发出的,因此受害者是是源ip
3.2.漏洞规则REC攻击包
3.2.1. wireshark数据流的跟踪
使用Wireshark流量分析工具打开离线pcap包,
由于该漏洞为HTTP请求,因此可进行HTTP的数据流跟踪
点击后得到HTTP请求相关数据流数据
3.2.2. payload载荷特征分析
如果流量数据的漏洞是已知漏洞,可以通过网上发布的一些漏洞分析和复现文章了解漏洞利用的原理,有利于提取漏洞利用的关键流量特征。该漏洞利用对应的CVE编号为CVE-2015-1427,对应的分析文章链接:
https://jordan-wright.com/blo...
https://www.secpulse.com/arch...
漏洞原理是es9200服务对应的api脚本查询模块,由于搜索引擎支持使用脚本代码(MVEL),作为表达式进行数据操作,攻击者可以通过MVEL构造执行任意java代码。具体Exp如下:
提取关键要素:
1.es 9200端口服务
2.http api
3.脚本查询模块
4.白名单中的类获取Class对象
5.java Runtime exec执行,exec执行
通过上述要素提取snort特征。
3.2.3. snort通信特征提取分析
alert:将该规则定义为发生告警动作的规则。
tcp:通过抓包分析,木马通信属于tcp协议,也可以写成http协议,通过snort规则编写和使用suricata引擎检测,保持其他条件不变,存在tcp协议能够检出,http不能检出的情况,视具体情况而定。
any(ip):客户端为任意ip。(*如果重点监测内网木马上线,可以将any换成,$HOME_NET,缩小匹配范围、控制精度有利于降低规则的误报,同时要结合snort规则的使用场景,如果snort规则检测的目标是蜜罐服务,suricata引擎(实时入侵检测功能)部署在蜜罐系统处,非大流量出口则可适当放宽规则扩大检出范围,如果位于大流量并且存在大量白流量的流量口,则需要更加精确的控制规则)。
any(port):客户端为任意端口
->:网络数据流向。
any(ip):服务端为任意ip。通过分析得到的服务端IP和端口可以作为C2 IOC情报,本次分析的PCAP包为生成器生成,C2端属于演练环境IP,不做IOC提取。
any(port):9200 es api默认的端口为9200。一般编写漏洞规则填写默认端口,从以往经验来看,公网的漏洞攻击和漏洞扫描也只针对默认端口进行漏洞扫描。
msg:规则相关说明及附加信息CVE编号漏洞描述信息等,通过相关分析已经明确该漏洞对应的CVE编号为CVE-2015-1427。
content:"POST"; http的请求方式为POST请求
offset:0; 载荷payload为偏移为0,http请求的开始几个字节为请求方式。
depth:5; 匹配深度为5确保常用的web请求方式能够被匹配到。
content:"/_search"; 匹配查询的api uri
distance:0; 确保本次匹配的顺序为上一次匹配的内容之后
content:"script_fields"; 匹配脚本相关字符串
distance:0; 确保本次匹配的顺序为上一次匹配的内容之后
pcre:"/class.forName.java.lang.Runtime..getRuntime().exec/i"; 匹配白名单类中的forName, .表示使用符号原本的字符表示,不允许正则表达式转义. 否则.在正则表达是表示匹配任意单个字符。其他表示引用java中的Runtime并且执行
sid:130000030; 规则id
flow:established,to_server; 流量方向为socket客户端到服务端,并且匹配已经建立连接的流量。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。