网站首页 > 基础教程 正文
多年以来,WAF对攻击的检测,通常使用正则表达式,典型的如ModSecurity。作为老牌的WAF,其拥有庞大的正则规则库。其检测率高,但也正因为规则数量庞大,正则逐一匹配,此过程速度慢,性能低。
对于同步检测的WAF产品,部署并对网站提供防护后,会带来不小的访问性能影响。
新兴的WAF产品,渐有使用语义分析引擎取代正则表达式检测。
其优势究竟何在,性能又能提升多少?以此为目标,本文进行研究记录。以供确定是否在WAF中使用语义分析替换掉正则匹配检测。
如果换用语义分析作为SQL注入、XSS等常见网络攻击检测,目的有两点:
一、提升检测效率,缩短检测耗时;二、降低误报率。前者为重点。
研究进程:
一、语义分析性能是否高于正则表达式
研究方法:
查阅语义分析相关资料、通过开源产品分析,明确语义分析的检测原理。
libinjection是著名的开源SQL注入语义分析引擎,对其分析较有价值。
2020年底,曾进行过一次初步了解,为更进一步明确细节,现做再次分析。
注:libinjection是C语言所开发。这也可能是其性能高的原因之一。如果转为NodeJS,执行性能必然不如C语言一些,当然,这只是一方面。
以上libinjectiony主框架流程图。
注:上为非最新版,此前的版本,逻辑更清晰一些,可参考大意。
以下为最新版函数执行逻辑:
libinjection_sqli_init()函数初始化检测所需的结构体,将 SQL注入识别特征码加载进结构体,并完成各种内置变量的初始化。
如下图,将参数赋予了sf:
之后通过libinjection_is_sqli()函数进行具体分析,判断是否检测到特征。大体流程非常简明。
libinjection对特征码(或称为指纹)的定义:
libinjection将输入的数据依据上述的定义进行转换,之后就会得到SQL注入识别特征,然后通过二分查找算法,在特征库中进行匹配,匹配到则报SQL注入漏洞。
例如,输入常用的SQL注入的检测语句 :' and 1=1
libinjection会将其转换为s&1,其中单引号依据定义被转换为s,and被转换为&,数字被转换为1。
又如语句:' UNION ALL SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL--
libinjection会将其转换为sUEvc,其中单引号依据定义被转换为s,UNION ALL被转换为U,SELECT被转换为E,NULL被转换为v,后面相同的NULL合并为一个v,--注释符被转换为c
libinjection在转换完后,通过二分查找算法对内置的特征进行匹配,匹配到则将SQL注入识别特征复制进fingerprint变量并返回。
截至2021年3月26日,转码为:9千多个。
可以说,它也有规则库,就是如上图的文件,是内置的。
在更新升级时,也可以对其进行维护。
在规则阶段,并没有看出语义分析比正则的优势之处,因为同样是使用规则库的。
然后重点来了,性能的优势来源是什么?
SQL注入语义好就好在,要想满足他的匹配规则,一般来说必须满足三个特征以上,比如s&1或者sUEvc,而每个特征要么是特殊字符,要么是SQL语句的保留字。
简单的来说,即:用大量的if分支,大大减少检测次数。
举例说明:
假如规则库内容如下:
2-345678
2-345666
...
1-234567
1-334567
1-456789
...
总量假设为100条。
如果检测的字符串内容是:123456;
同样进行匹配,正则要检测每一条规则,可能需要检测100次,如果运气好的话,也可能只检测第几次就遇到,但是小概率,一般忽略;而如果用所谓"语义",只需要检测3条。
再如果检测的字符是4567890,语义分析一次都不用检测,而正则需要检测100次。
这就是性能差异的主要原因。
注:类似于杀毒软件中杀毒引擎与病毒库。因熟悉杀毒软件开发,故对此方面有较清晰的理解。在以往的杀毒软件研发中,在20万病毒库特征码量的情况下,曾用过类似的二分法,可成几何倍数的提升扫描速度。
由此得出:语义分析(也可以叫其它名称),在性能上,优势确实很大。在WAF中,相比正则匹配,确实检测速度会快非常多。
注:规则量同等、且量较大的情况下,如几千、几万。如果是几十几百则无多少差异。
除非正则也有突破性的进展,比如异步方式,方可跟"语义分析"匹敌。或对正则引擎进行质变式的升级,能性能与语义同等级。
那么,WAF在使用正则匹配的情况下,该如何实现转为语义分析呢?
目前WAF是在NodeJS环境中开发。
1、在NodeJS中实现一个语义分析引擎,是个大工程。
可参考libinjection,重点内容:
libinjection能被Nodejs直接调用吗,目前研究来看,不行。还需进一步分析。比如是否可以实现成dll形式的调用,nodejs有对c库的调用。
正则的突破,正则在匹配上是无法实现跨越了,只能老老实实的一条条的匹配。但在用法上,正则异步的可行性、正则if多分枝、二法分的应用有待后续再研究。但诚意地说,应该不及用语义。只是基于现状,实现语义引擎需要不短的时间和成本。
那么短期内,从现实的角度考虑,要对WAF进行检测阶段的性能优化,可以一边对正则算法使用的规则库进行优化。一边开启语义分析引擎的研发。
NodeJS实现语义分析的准备工具。
NodeJS语义分析实现,可借助的库:js-sql-parser、sql-parse,可以分离、分析SQL 语法。如测试代码:
效果如下:
注意事项
语义分析,也并非全是优势。也会被攻破、绕过,如:
又如:
对libinjection的检测模式分析,有如下六种:
1. 无符号 标准SQL 模式
2. 无符号 MySQL模式
3. 单引号 标准SQL 模式
4. 单引号 MySQL 模式
5. 双引号 MySQL 模式
6. 双引号 标准模式
为什么# "ad1n'– %a%0aunion select 1,database(),user() — " 这么一个简单的可以绕过呢。首先他是吧 admi' 先进入无符号的标准SQL 然后发现有一个' 后面就转到单引号的标准SQL。单引号标准SQL 首先获取的admn' 然后break继续到了下一层碰到了一个 – 那么走到parse_dash函数中。
也就是,语义分析在性能上虽好,但如libinjection也存在与正则类似的可能被绕过的问题,其关键是规则的维护。在开发中,也需注意逻辑处理的严密性。
扩展参考资料:
- 上一篇: 正则表达式获取body内容
- 下一篇: 小心别落入正则回溯陷阱
猜你喜欢
- 2024-12-14 分享 5 个正则表达式的实际应用场景案例
- 2024-12-14 正则表达式:汉字与阿拉伯数字间的转换技巧,让亿万数字变得轻松
- 2024-12-14 小心别落入正则回溯陷阱
- 2024-12-14 正则表达式获取body内容
- 最近发表
- 标签列表
-
- gitpush (61)
- pythonif (68)
- location.href (57)
- tail-f (57)
- pythonifelse (59)
- deletesql (62)
- c++模板 (62)
- css3动画 (57)
- c#event (59)
- linuxgzip (68)
- 字符串连接 (73)
- nginx配置文件详解 (61)
- html标签 (69)
- c++初始化列表 (64)
- exec命令 (59)
- canvasfilltext (58)
- mysqlinnodbmyisam区别 (63)
- arraylistadd (66)
- node教程 (59)
- console.table (62)
- c++time_t (58)
- phpcookie (58)
- mysqldatesub函数 (63)
- window10java环境变量设置 (66)
- c++虚函数和纯虚函数的区别 (66)