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 an alert with msg “bot founded” and sid 1000001
题目要求检测包含两个包的特定流,需要通过设置标记位,即flowbits来实现。另外,题目中均要求检测特定的字符串或模式,所以还需要在pcre字段中通过正则表达式实现。
2.1 第一条检测规则-
匹配特定字符串
pcre:"/login|Initial/";
正则表达式的两端需要加上限界符
/
。 -
设置标志位,同时不发出警报。
flowbits:set,bot_founded;flowsbits:noalert;
IPv4Address:Port
-
IPv4Address
IPv4地址使用点分十进制表示时,分为4组,每组的范围均为[0,255]。即从0.0.0.0到255.255.255.255。
我们先分析单独一组的特点:
区间 限制 表示 0~99 没有任何限制\d{1,2}
100~199 后两位也没有任何限制1\d{2}
200~249 十位限制在0~4,个位没有限制2[0-4]\d
250~255 个位限制在0~525[0-5]
可以发现表格中前两种情况可以合并为
1?\d{1,2}
,所以可以用25[0-5]|2[0-4]\d|1?\d{1,2}
来匹配0~255;将其作为一个分组,再考虑到
.
,我们可以写出如下正则表达式匹配IPv4地址:((25[0-5]|2[0-4]\d|1?\d{1,2})\.){3}(25[0-5]|2[0-4]\d|1?\d{1,2})
值得说明的是:
这里我们认为数字前出现填充
0
的情况与非填充状态等价:如:
192.01.00.1
等价于192.1.0.1
。这种情况下才能使用
\d{1,2}
,因为可能会出现00
的情况。正则表达式的短路性质:
当
|
运算符分隔的多个表达式有一个匹配成功时,该表达式之后的表达式将不会继续匹配。如:
A|B|C|D
,B
匹配成功了,将不会再看C
和D
。所以上面匹配IPv4地址时,我们单独一个分组写成
25[0-5]|2[0-4]\d|1?\d{1,2}
而不是1?\d{1,2}|2[0-4]\d|25[0-5]
。后者匹配
255
时,只会匹配到25
和5
,而不会匹配到255
:同样后者构造的正则表达式去匹配
255.255.255.255
,只会匹配到255.255.255.25
,缺少最后一个5
:因为它匹配到最后一组的
25
时就判定匹配成功,直接跳到末尾,结束匹配。而前面几组255
正确匹配的原因是:如果只匹配25
, 发现剩下的5
和.
不匹配,之后会进行回溯,继续检查后面的条件,发现255
匹配成功且.
也匹配成功,不再回溯。
-
Port
端口号的范围是0~65535,我们同样可以分成不同的区间来匹配端口号。
区间 限制 表示 0~9999 没有任何限制\d{1,4}
10000~59999 后四位没有任何限制[1-5]\d{4}
60000~64999 千位限制在0~4,后三位没有任何限制6[0-4]\d{3}
65000~65499 百位限制在0~4,后两位没有任何限制65[0-4]\d{2}
65500~65529 十位限制在0~4,个位没有任何限制655[0-2]\d
65530~65535 个位限制在0~56553[0~5]
同样,我们可以将表格前两种情况合并为
[1-5]?\d{1,4}
。结合上面提到的短路性质,我们可以写出最终用于匹配端口号的正则表达式:6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]?\d{1,4}
flowbits:isset,bot_founded;
3. 检测规则
通过上述分析,我们可以写出如下检测规则:
alert tcp any any -> any 3399 (pcre:"/login|Initial/";flowbits:set,bot_founded;flowbits:noalert;sid:1000000)
alert tcp any any -> any 3399 (msg:"bot founded";pcre:"/((25[0-5]|2[0-4]\d|1?\d{1,2})\.){3}(25[0-5]|2[0-4]\d|1?\d{1,2}):(6553[0-5]|655[0-2]\d|65[0-4]\d{2}|6[0-4]\d{3}|[1-5]?\d{1,4})/";flowbits:isset,bot_founded;sid:1000001)