在宗派林立的检测技术武林中,语义化检测引擎近两年已成热门绝学。它的力量在于,让攻击检测更精确、更聪明、更人性化。目前,硬件WAF中,国内已经有数家厂商部署了该技术;云WAF中,阿里云云盾也在上周发布了语义智能检测引擎的选项。
“智能语义检测”这门武艺的江湖故事,要从它的前辈“基于规则的检测引擎”开始说起。
10几年里,基于规则的引擎一统江湖。直到现在,江湖上大多数的WAF是基于规则的WAF。其原理是每一个会话都要经过一系列的安全检测,每一项检测都由一个或多个检测规则组成,匹配了检测规则,请求就会被认为非法而拒绝。
听起来很简单?其实对于运维者和企业客户来说,规则检测的软肋就在于他的“道法复杂,不变通”。
基于规则的WAF能有效的防范已知安全问题。但安全运维者首先必须知道攻击的全部特点,根据这些特点制定规则。所以基于规则的WAF需要一个强大的规则库支撑,并且规则库需要及时更新来应对最新的攻击。
对于安全运维人员来说,规则的条目就会变得繁多而复杂,导致规则库维护起来相当困难。并且,运维人员经常发现,过了一段时间后,都不知道某些规则的含义以及当初为什么这么写的了。例如下边这条规则:
在很多攻防对抗的场景下,会发现正则的缺陷和短板。以一个简单的SQL注入攻击请求为例:
www.vuln.com/?id=1’ union select version() from dual
这个SQL注入攻击请求是读取数据库版本信息的攻击请求,能够描述这个攻击的正则表达式,可以写为:
union\s+select\s+version\(\)\s+from\s+dual
\s+的作用是匹配一个或多个不可见字符,如空格、换行等符号。显然的,熟悉SQL语句的攻击者,可以利用一些数据库特性绕过这个正则的检查,例如:用注释符/11/替换空格、利用注释符号--%0替换空格,根据这个特性,完善后的正则表达式可以写为:
union(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)select(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)version\(\)(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)from(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)dual
可以明显看到,更新之后的正则表达式的复杂度已经明显提高了,逻辑看起来也不是非常直观明了,更重要的是,这样的防护规则,仍然可以被绕过!
经过简单的fuzz挖掘,可以发现mysql新的“特性”,在Mysql函数调用中,正常结构为function_name() 这样的格式,同时还支持其他的语法特性,function_name/*111111*/()
、function_name ()
、function_name()
、function_name--%0a()
、function_name/**/ ()
、function_name/*111*/--11%0()
这样都是等价的写法!
于是上述正则规则又有了升级版:
union(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)select(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)version(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a|`)\(\)(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)from(\s+|/\*[\s\S]*\*/|--[\s\S]*?\x0a)dual
从这个简单的例子可以看出,使用正则表达式去描述SQL注入这样的攻击,存在明显的短板:维护成本高、逻辑性低、条理性低。往往一个新”特性”的发现,意味着运营人员需要批量更新上百条的规则,这是一个相当艰难的过程,因此使用正则作为检测方式的引擎,或多或少存在被绕过的风险。
总而言之,基于规则的检测不能有效防御未知的威胁,比如攻击变体,0day攻击。除此之外,对于企业安全运维人员来说,正则引擎的维护压力大,成本高,各派武林人士都在YY:“有没有一种检测引擎和算法,不需要人去维护规则,也可以应对千变万化的攻击!?”
智能引擎检测这个武林绝学,就在这样的江湖背景下,千呼万唤始出来
语义检测引擎的内功在于,会把自然语言中的语义、顺序和场景,纳入考虑范围;知道一个特征,在这个场景、顺序下可能是攻击,在另一个中则不是。延续刚才“大道至简”的例子:
只用“至”、“简”“!”来判定一个请求是否是攻击。漏报误报率高
1、“大道至简!”是攻击
2、“至繁归于至简!”因为场景和顺序不对,不是攻击
3、通过机器学习,能分辨出“大道无为”是“大道至简”的变体
这样一来,大家就可以一目了然看出二者的根本区别了。智能化语义检测引擎,就像手握一把离门剑,“每一招中皆能在刹那间作二十五种变化,独步剑林。”(参考萧逸《十二神拳》)。对于防范未知威胁,0day攻击尤其有效。
那么,智能语义化检测的武功究竟如何使出来?我们再往下探究。
把同类攻击行为的同类行为特征归并起来。即,同一类的攻击行为和攻击特征聚合为一个攻击特征,这就是归一化的过程。攻击的多个行为特征组成特定的排列组合,来表示同一类攻击,这样我们就可以用自然语言的语义来理解并且描述同一类攻击。攻击特征的排列组合就是攻击的语义化。
这样就能抛却各种复杂的攻击和它们的变形,把攻击行为语义化了。
以下是一个sql注入攻击实现语义化的例子,先对sql语句进行归一化的语义分析,然后在异常攻击集中查找分析结果,若找到说明是sql注入攻击。
比如以下这条规则:
(select|from|\band|\bor|\bxor|=|,|;)[\s\+\(`)*?(sleep[\s\+`]*?\(|version[\s\+`]*?\(|pg_sleep[\s\+`]*?\(|extractvalue[\s\+`]*?\(|updatexml[\s\+`]*?\(|dbms_pipe.receive_message\(|st_latfromgeohash\(|st_longfromgeohash[\s\+`]*?\(|analyse[\s\+`]*?\(|gtid_subset[\s\+`]*?\(|gtid_subtract\(|st_pointfromgeohash\(|convert[\s\+`]*?\(|md5[\s\+`]*?\(|count[\s\+`]*?\(|char[\s\+`]*?\(|benchmark[\s\+`]*?\(|hex[\s\+`]*?\(|@@version|db_name[\s\+`]*?\(|user[\s\+`]*?\(|cast[\s\+`]*?\(|concat[\s\+`]*?\(|unhex[\s\+`]*?\(|floor[\s\+`]*?\(|length[\s\+`]*?\(|ascii[\s\+`]*?\(|substring[\s\+`]*?\(|substr[\s\+`]*?\(|substring_index[\s\+`]*?\(|instr[\s\+`]*?\(|left[\s\+`]*?\(|right[\s\+`]\()
通过归一化后可以描述为:select from 敏感关键字 函数运算(),可以用“abcde”五个字符表示,即这类攻击用语义可描述为:具有敏感关键字和函数运算的sql类型表达式。复杂的规则维护,瞬间变得简单了。
仅仅防范已知的WEB安全问题,是被动且滞后的,基于异常的防护会更加有效。
异常防护这一招的基本观念是:根据合法应用数据检测建立统计模型,以此模型为依据判别实际通信数据是否是攻击。
理论上,此招一出,系统就能够探测出任何的异常情况。这样,就不再需要规则库,0day攻击的检测也不再是问题了。
例如,阿里云云盾的WAF智能语义异常攻击集,是基于云盾自己的运营数据,对正常的Web应用建模,从正常的模型里边区分出异常的情况,再从繁多的Web攻击中提炼出来的异常攻击模型,形成异常攻击集。
未来,智能语义化检测引擎这门绝学,将进化成实时大数据分析引擎。招式进化的关键,就在于算法的优化,计算的能力和成本,还有数据聚类和清洗的技术,等等
江湖风云变幻,大数据的时代已经成为主流。WAF防御的技术如果想要继统治武林,向智能化、语义化的方向发展则是必然。未来,可以预见大部分的WAF检测和防御都会通过机器学习自动来完成,再加上很少的人工确认工作,就可以确定异常攻击集 —— 从容应对现实中的安全威胁以及未来的安全威胁,从根本上解决Web服务系统所面临的各种安全挑战。
大道至简,大有可为。