Snort Rules——使用pcre进行规则匹配

题目描述
if snort see two packets in a TCP flow with

  • first packet has " login " or " Initial " in payload, destination port is 3399;
  • and second packet has a " IPv4Address:Port " string (E.g.123.45.6.7:8080) in payload. destination port is 3399;
  • output a alert with msg " bot founded " and sid 1000001

参考资料:
Snort规则详解
PCRE正则表达式语法
php pcre正则表达式完全教程——pcre官方文档
正则表达式校验IP地址
使用正则表达式验证IPv4地址


我们把题目中的几个难点拆分出来:

难点一:两条规则均命中,构成一个攻击事件

解决方法:设置flowbits字段(flowbits使用规范

在第一条检测规则中,我们设置一个标志位botlogin,同时设定不发出警报

flowbits:set,botlogin;flowbits:noalert;

在第二条规则中,我们检测标志位是否为1

flowbits:isset,botlogin;

难点二:first packet has " login " or " Initial " in payload

这是一个逻辑或的内容匹配,我们可以使用pcre规则实现

快速浏览一下PCRE正则表达式语法后,我们可以捏出来一个规则雏形:

pcre:"login|Initial";

实际上,这个 " 显而易见 " 规则,就可以解决第二个难点了,但还存在一点点语法错误
参考一下pcre中分隔符和元字符的使用方法,我们可以在前后加上小括号让pattern看上去更优美完整,再使用分隔符进行限定即可

这里是否需要这么多限定pattern界限的符号,我并不确定
不过保险起见,就都写上了

pcre:"/(login|Initial)/";

难点三:has a " IPv4Address:Port " string (E.g.123.45.6.7:8080) in payload

IPv4地址

IPv4地址:0-255.0-255.0-255.0-255
我们先来解决0-255如何表示为pattern
最简单的想法,将0-255拆分成:0-9,10-99,100-199,200-249,250-255

([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])

可以注意到,表达式中出现了[0-9][0-9]的结构,我们可以用{x}表示之前紧邻的模式需要匹配几次

[0-9][0-9]  -->  [0-9]{2}

此外,我们也可以用\d代表[0-9]

(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])

在0-255这部分后面添加一个 " . "(注意需要使用转义符 " \ ")

((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.)

" 0-255. "重复匹配三次

((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}

完整的IPv4检测正则表达式

((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])

理论上,上述正则表达式就可以解决我们的问题

但是

我亲爱的同学遗憾地告诉我
在网上在线测评的时候,发现以上规则无法正确匹配255.255.255.255(最后一组的最后两个5无法匹配)
在这里插入图片描述
大概率是因为snort默认采用最短匹配
前三组有 " . " 的约束就会老老实实地挨个匹配
最后一组如图,首次匹配2成功了,一看是或关系,就直接跳到末尾了
在这里插入图片描述
这就可以解释为什么网上的很多文章," 无缘无故 " 会将确定性强(更特殊)的部分放到整个正则表达式的最前面
因此,保险起见,我们把IPv4的pcre规则更改为:

((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)

在这里插入图片描述

端口号

端口号:0-65535
还是先采用最简单的想法

[0-9]
[1-9][0-9]
[1-9][0-9][0-9]
[1-9][0-9][0-9][0-9]
[1-5][0-9][0-9][0-9][0-9]
6[0-4][0-9][0-9][0-9]
65[0-4][0-9][0-9]
655[0-2][0-9]
6553[0-5]

简化一下

\d
[1-9]\d
[1-9]\d{2}
[1-9]\d{3}
[1-5]\d{4}
6[0-4]\d{3}
65[0-4]\d{2}
655[0-2]\d
6553[0-5]

简单的,我们可以把0-9999(近似)表示为

\d{1,4}

完整的端口检测正则表达式

(\d{1,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])

同IPv4正则表达式描述的问题
以防万一我们可以把确定性高的表达式放到前面:

(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|\d{1,4})

最终的答案:

alert tcp any any -> any 3399 (msg:"bot login";pcre:"/(login|Initial)/";flowbits:set,botlogin;flowbits:noalert;sid:1000002;)
alert tcp any any -> any 3399 (msg:"bot founded";pcre:"/((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]):(\d{1,4}|[1-5]\d{4}|6[0-4]\d{3}|65[0-4]\d{2}|655[0-2]\d|6553[0-5])/";flowbits:isset,botlogin;sid:1000001;)

调整正则表达式顺序后:

alert tcp any any -> any 3399 (msg:"bot login";pcre:"/(login|Initial)/";flowbits:set,botlogin;flowbits:noalert;sid:1000002;)
alert tcp any any -> any 3399 (msg:"bot founded";pcre:"/((25[0-5]|2[0-4]\d|1\d\d|[1-9]\d|\d)\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9]):(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]\d{4}|\d{1,4})/";flowbits:isset,botlogin;sid:1000001;)

测试方法

snort读取外部数据方式

snort --pcap-dir="./pcap" -c test.rules -A fast
cat /var/log/snort/alert
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值