专业编程基础技术教程

网站首页 > 基础教程 正文

WAF研发领域,语义分析相对于正则表达式先进性的研究

ccvgpt 2024-12-14 10:21:34 基础教程 3 ℃

多年以来,WAF对攻击的检测,通常使用正则表达式,典型的如ModSecurity。作为老牌的WAF,其拥有庞大的正则规则库。其检测率高,但也正因为规则数量庞大,正则逐一匹配,此过程速度慢,性能低。

对于同步检测的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也存在与正则类似的可能被绕过的问题,其关键是规则的维护。在开发中,也需注意逻辑处理的严密性。

扩展参考资料:

最近发表
标签列表