10.10.1. Suricata 快速模式匹配机制详解¶
若规则中显式设置了 'fast_pattern' 关键字,Suricata 将直接采用该内容作为快速模式匹配项。每条规则中 'fast_pattern' 关键字仅能设置一次。若未设置,Suricata 会自动选择最合适的内容作为快速模式匹配项。
下文将阐述 Suricata 自动确定快速模式匹配项的逻辑规则。
需注意:当规则中存在正向(非否定)内容匹配项时,否定型内容匹配项在快速模式选择过程中会被忽略。反之,则会纳入考量范围。
快速模式选择标准如下:
Suricata 首先识别规则中具有最高"优先级"的所有内容匹配项。优先级基于匹配的缓冲区类型,通常应用层缓冲区具有更高优先级(数值越小优先级越高)。但 http_method 缓冲区例外,其优先级低于常规的 content 缓冲区。
在步骤1筛选出的最高优先级内容匹配项中,选择字符/字节长度最长的作为快速模式匹配项。
若多个内容匹配项具有相同最高优先级且长度相同,则选择字符/字节多样性得分("模式强度")最高者作为快速模式匹配项。具体算法详见 附录A。
若多个内容匹配项具有相同最高优先级、相同长度及相同模式强度,则选择缓冲区("list_id")注册时间最晚者作为快速模式匹配项。
若多个内容匹配项具有相同最高优先级、相同长度、相同模式强度且属于同一缓冲区(即list_id相同),则选择规则中从左到右最先出现的匹配项作为快速模式匹配项。
值得注意的是,对于具有相同优先级、长度和模式强度的内容匹配项,'http_stat_msg'、'http_stat_code' 和 'http_method' 会优先于常规 'content' 匹配项被选中。
10.10.1.1. 附录¶
10.10.1.1.1. 附录A - 模式强度算法¶
算法实现位于 detect-engine-mpm.c。模式强度"得分"初始为零,从左至右扫描字节数组中的每个字符/字节:若该字符/字节首次出现,字母字符加3分;可打印字符或0x00/0x01/0xFF加4分;其他字符加6分。若字符/字节重复出现则加1分。最终返回总分。
/** \brief 计算模式强度值
*
* 字符多样性高的模式得分更高
* 字母字符得分较低
* 其他可打印字符及特定控制码得分中等
* 其余字符得分最高
* 长模式优于短模式
*
* \param pat 模式字节数组
* \param patlen 模式长度
*
* \retval s 模式强度得分
*/
uint32_t PatternStrength(uint8_t *pat, uint16_t patlen) {
uint8_t a[256];
memset(&a, 0 ,sizeof(a));
uint32_t s = 0;
uint16_t u = 0;
for (u = 0; u < patlen; u++) {
if (a[pat[u]] == 0) {
if (isalpha(pat[u]))
s += 3;
else if (isprint(pat[u]) || pat[u] == 0x00 || pat[u] == 0x01 || pat[u] == 0xFF)
s += 4;
else
s += 6;
a[pat[u]] = 1;
} else {
s++;
}
}
return s;
}