基于循环神经网络的Web 应用防火墙加固方案
2023-01-09朱思猛杜瑞颖
朱思猛,杜瑞颖,陈 晶,何 琨
(1.武汉大学国家网络安全学院 空天信息安全与可信计算教育部重点实验室,武汉 430072;2.武汉大学 日照信息技术研究院,山东 日照 276827)
0 概述
Web 应用程序部署在Web 服务器上,并通过Web 浏览器提供可访问的服务[1]。由于具有便利性,Web 应用程序在互联网上得到了广泛的应用,如网络邮件、网上银行等,同时也出现了针对Web 应用程序的各种网络攻击。研究报告显示[2],针对Web应用程序的攻击占所有网络威胁的32%以上,是最活跃的一类网络攻击。为了防御这类攻击,Web 应用防火墙(Web Application Firewall,WAF)被广泛应用[3-4]。WAF 通过检查传入的HTTP 流量来确定是拦截还是将流量转发到目标Web 应用程序。多数WAF 根据定义的规则来做出决策,这些规则可以具体表现为匹配恶意Payload 特征的正则表达式。随着针对Web 应用程序的攻击不断发展演变,WAF 的被动防御很难拦截新出现的攻击,因此,需要及时测试WAF 的安全防护能力,并更新其规则来进行加固,以此拦截新的攻击,并进一步阻止后续类似的攻击。
WAF 安全能力测试的关键步骤是生成有效的测试输入,其中可分为两类:白盒测试和黑盒测试。白盒测试需要访问相关源码[5],这在现实环境下很难实现。黑盒测试在不了解目标内部机制的情况下工作,可进一步分为基于突变的黑盒测试和基于生成的黑盒测试。基于突变的方法通过应用精心设计的突变操作组合来修改现有Payload,以获得测试输入[6-8],基于生成的方法则根据设计的攻击语法生成测试输入[9]。然而,基于突变和基于生成的方法都依赖对某种攻击的专业知识来设计突变操作或生成语法,且仅针对特定目标,效果不够理想,只适合已知的攻击检测,很难检测到新的或未知的攻击[10-11]。
本文基于循环神经网络(Recurrent Neural Network,RNN)设计一个自动化加固WAF 的方案,测试给定的WAF 并生成用于规则更新的加固签名。针对现有方案的局限性,以恶意攻击数据集为基础,利用RNN 模型生成更多的恶意攻击Payload,并将这些Payload 发送至被WAF 保护的应用程序,以发现WAF 存在的安全防护问题。在此基础上,对成功绕过WAF 的恶意Payload 生成加固签名,并设计简化的正则表达式作为表示加固签名的方式。
1 基础知识
1.1 Web 应用程序攻击
Web 应用程序是目前通过Internet 提供信息和服务最流行的平台之一。随着Web 应用程序越来越多地被用于关键服务,出现了很多针对Web 应用程序的攻击,如SQL 注入、跨站脚本(Cross-Site Scripting,XSS)、命令注入(Command Injection,CI)、cookie 盗窃、浏览器劫持等。由于许多Web 应用程序与后端数据库系统交互,因此针对Web 应用程序的攻击会导致严重的后果。本文主要研究SQL 注入、跨站脚本和命令注入这3 种典型的攻击[12-14]。
SQL 注入攻击用于攻击数据驱动的应用程序。在这些应用程序中,恶意SQL 语句被插入到字段中执行,数据库信任Web 应用程序并执行应用程序发出的查询。使用这类攻击,攻击者可以操纵SQL 查询并导致意外执行。
跨站脚本攻击是一种注入类型的攻击。攻击者可以利用这类攻击在网站上注入恶意的客户端代码,当被攻击者登陆网站时就会自动运行这些恶意代码,从而攻击者可以突破网站的访问权限,冒充被攻击者。
命令注入攻击的目标是通过易受攻击的应用程序在主机操作系统上执行任意命令。当应用程序将不安全用户提供的数据传递给系统shell 时,就会发生这类攻击。
1.2 循环神经网络
循环神经网络(RNN)用于对序列数据建模[15],如用于文本处理、程序分析等[16-18],一般由输入层、隐藏层和输出层组成。RNN 使用隐藏状态作为携带时间步之间信息的短期记忆,能够很好地处理序列信息。
然而,RNN 存在梯度消失和梯度爆炸的问题,会导致消耗大量的时间并难以做进一步优化。对此,HOCHREITER 等提出了长短时记忆(Long Short Term Memory,LSTM)网络。LSTM 网络通过引入单元状态弥补了原始RNN 的缺陷,利用遗忘门、输入门和输出门,分别控制上一时刻的单元状态保留到当前时刻、当前时刻网络的输入保存到单元状态以及单元状态输出保留到LSTM 当前输出的数量。另一种流行的RNN 结构是门控循环单元(Gated Neural Unit,GRU)[19],其仅使用2 个门,即更新门和重置门。GRU 在LSTM 网络的基础上做了很多简化,同时能够保持与LSTM 网络相同的效果。
2 相关研究
关于提升WAF 安全防护能力的研究,目前主要集中在检测恶意攻击[20-21]方面,对WAF 的安全测试和评估则不够深入,无法解决许多实际问题。相关研究较少的原因在于WAF 是一个to-B 产品,主要影响企业用户而不是消费者,导致其受众面相对狭窄,同时研究者也很难找到专业的WAF 进行测试。
对于WAF 的安全测试,文献[9,22]结合决策树模型和进化算法将Web 攻击的Payload 分解为切片,并使用进化算法进一步生成恶意Payload,但具体攻击的语法规范需要人工总结,在测试过程中也存在一些限制,如生成的Payload 仅源于自己总结的语法规范,不能涵盖新出现的攻击,此外,方案仅对单个WAF 有用。文献[7]提出了突变的方案,但加固目标是基于机器学习的WAF 而不是真正的WAF。当前,多数WAF 都是黑盒的,不仅使用机器学习方法进行防御,而且混合使用多种方法,而上述方案都需要预先设计突变操作或语法,复杂耗时并且只对特定的WAF 有效。因此,本文提出一种可应用于各种类型攻击的WAF 加固方案。
3 WAF 自动化加固方案
本文提出一种WAF 自动化加固方案,其可发现绕过给定WAF 的恶意Payload,并生成加固签名来修复相应安全防护漏洞。
如图1 所示,本文方案的系统框图主要由Payload 生成器和签名生成器2 个部分组成。首先,发送收集到的数据集到被WAF 保护的应用程序,得到被WAF 拦截的恶意攻击Payload 作为Payload 生成器的输入,通过RNN 生成更多恶意攻击Payload。然后,签名生成器利用其中可以绕过WAF 的Payload,通过评分函数找到对WAF 判别有重要影响的字符串,生成可以匹配绕过攻击的加固签名。在这其中一个重要前提是,系统从恶意Payload 中生成Payload,这些生成的Payload 应视为具有恶意的。
图1 本文方案的系统框图Fig.1 System block diagram of the proposed scheme
3.1 Payload 生成器
Payload 生成器负责生成针对WAF 的恶意攻击Payload。该模块接收恶意的Payload,并在原始Payload 上产生微小扰动,输出更多恶意Payload。笔者认为,由于Payload 是否恶意取决于上下文,因此其中应选用能够学习序列结构的神经网络。由于传统基于n-gram 的方法受有限长度上下文的限制,因此本文选择使用RNN。RNN 允许学习任意长度的上下文来预测下一个字符序列,给定恶意Payload 的语料库,RNN 模型能够以无监督的方式进行训练来生成新的恶意Payload。由于RNN 每个时刻隐藏层的输出都会传递给下一时刻,因此每个时刻的网络都会保留一些来自之前时刻的历史信息,并结合当前时刻的网络状态一并传给下一时刻,这一过程可以表示为:
其中:it是输入;ht和ht-1是隐藏状态向量是时刻t的输出;fh是激活函数;fo用于计算当前隐藏层输出的概率分布。
为了使输入能够被神经网络处理,Payload 生成器要将输入进行向量化,转换成适合处理的结构。首先,需要将字符串映射为数字。设X={x1,x2,…,xN}为输入序列,其中xt∈N|1 ≤t≤N表示输入序列中位置t处字符的自然数。然后,将xt转换为N维的one-hot 向量,定义为:
通过上述向量化方法得到一个高维的向量,从而获得训练所需的特征。在此基础上,使用GRU 神经网络模型解决RNN 面临的梯度消失或梯度爆炸的问题。模型的输出层包含了一个前馈网络,其输入为循环神经网络的输出。本文应用softmax 函数为预测输入序列的下一个值提供概率分布。最后,使用交叉熵误差函数作为优化目标对GRU 模型进行优化,此部分采用ADAM 优化算法[23],其为一种基于梯度的优化算法,与其他算法相比只需要一阶梯度,并且内存占用较少。
3.2 签名生成器
签名生成器的作用是生成匹配恶意攻击的加固签名。该模块接收绕过WAF 的恶意Payload 作为输入。签名被广泛用于防御攻击,签名系统都有相同的基本假设:Payload 存在一个子字符串,该子串在过程中保持不变,并且具有足够的唯一性,可以用作签名而不会导致误报。由于人工生成加固签名通常需要花费大量的时间,因此本文选择使用绕过WAF的Payload 来自动生成WAF 加固签名。
由于可能会有巨大的搜索空间,因此应找到对WAF 判别有最重要影响的字符串。使用4 个能够正确反映字符串对判别重要性且计算效率较高的评分函数,来评估对目标WAF 做出决策最重要的token,如图2 所示,其中,WAF 判别结果可以为0 或1,结果为1 表明实线部分和虚线部分的判别结果不同。
图2 以SQL 为例的评分函数说明Fig.2 Description of scoring function taking SQL as an example
假设输入序列X={x1,x2,…,xN},其中xi表示第i个位置的token。为根据重要性进行排序,需要衡量第i个位置的token 对判别的影响。使用4 个评分函数来评估Payload 中每个token 对WAF 判别的重要性,以f代表WAF 的判别结果。下面将分别对4 个评分函数进行解释说明。
删除函数比较删除token 前后的Payload 语句,以评估xi对WAF 的影响,便于直观地理解其重要性。删除函数表达式如下:
替换函数将xi替换为另一个字符串,通过评估替换的影响来衡量token的重要性。替换函数表达式如下:
由于token 前后的字符串是相关的,可以按顺序衡量token 的重要性,因此定义头部函数比较x1到xi之间的字符串与x1到xi-1之间的字符串,定义尾部函数比较xi到xn之间的字符串与xi+1到xn之间的字符串。这2 种函数的表达式如下:
上述4 个函数的结果以0 和1 表示,表明token 发生变化时是否对判别结果产生影响。综合4 个评分函数的结果,评估所有token,选择若干个频繁出现且对判别影响较大的字符串token,然后使用正则表达式生成签名,每个签名由一个或多个这样的token 组成。正则表达式在灵活性、准确性和效率方面对于攻击检测具有显著的优势。但是,完整的正则表达式过于复杂,而签名不需要其众多的语法规则。因此,本文引入简化正则表达式作为表示签名的方式。简化正则表达式签名是正则表达式的简化形式,其中只包含一个限定符“S*”,表示任意非空白字符。
通过编辑距离对token 进行聚类,将相似的token 划分为一个组,在一组中随机查找2 个字符串的公共子序列。2 个字符串的公共子序列是2 个字符串中相同顺序的字节序列,虽然它不一定是连续的,如在字符串“xxabxxxcx”和“abyyyyycyy”中,最长的公共子序列是“abc”。然后,使用此子序列来不断地匹配和产生新的子序列。当某组的子序列不再匹配时,迭代查找不同组子序列的公共子序列。对于结果,在每2 个字符之间添加“S*”,生成一个简化的正则表达式,即加固签名。
4 实验
通过检测SQL 注入、XSS 攻击和命令注入这3 种典型网络攻击来评估方案的有效性,并将本文方案与现有基于突变的解决方案和主流测试工具进行比较。此外,实验还将评估签名生成器的有效性。
4.1 实验设置
在ModSecurity、Naxsi、Safedog、Xwaf 这4 款WAF 上进行实验。根据以下标准选择WAF:首先,WAF 来自商业公司或者是GitHub 上的高评分项目,并且在安装过程中不会报告错误;其次,WAF 可以禁用对挑战黑洞(Challenge Collapsar,CC)攻击的保护,因为这种保护会阻止系统有效地测试WAF。
在实验中,Web 应用系统部署在带有Intel®Xeon®CPU E5-2680 和32 GB RAM 的Linux 工作站上运行。所选WAF 部署在相同配置的Linux 工作站或Windows 工作站上。分别在Linux 工作站和Windows 工作站上安装Ubuntu 18.04 和Windows 7。深度学习模型是使用Google 的TensorFlow 框架[24]实现的,该框架提供了必要的优化算法和损失函数。
4.2 数据集
本文选择自行生成部分数据集,以及在WAF 服务器上收集到的数据作为实验所用的恶意数据集,主要是基于以下原因:一方面,这类数据集大多都是内部数据集,由于隐私问题而无法公开共享;另一方面,很多数据集高度匿名或无法满足测试需求。此外,“恶意”和“良性”的定义依赖于具体的应用程序,不存在通用的定义。
在生成的这部分数据集中,对于SQL 注入攻击,选择使用随机查询生成器生成数据并运行相应脚本,使其变为恶意Payload。随机查询生成器是SQL Server 的官方测试工具,给定语法,该工具返回一组该语法所表示的Payload,然后从现有的渗透测试工具SQLMap 中提取恶意脚本来生成SQL 注入的Payload。对于命令注入攻击,修改了Commix 来根据实验需要生成恶意Payload。Commix 是一个开源渗透测试工具,能够自动检测和利用命令注入漏洞。对于XSS 攻击,使用XSStrike 来生成恶意Payload.XSStrike 是一个流行的跨站脚本检测套件,在Github上拥有9 000 多个Star。
为获得WAF 自身以及加固后的误报率,本文使用来自公共数据集HTTP CSIC 2010[25]的数据作为良性数据集。数据集HTTP CSIC 2010 包含针对电子商务Web 应用程序生成的流量,其中有36 000 个正常请求。
4.3 漏洞检测
绕过目标WAF 的Payload 数量是衡量WAF 安全防护能力的重要指标。当恶意攻击Payload 绕过WAF 时,表明WAF 中存在安全防护问题。
表1 列出了WAF 安全测试结果。本文并没有针对3 种攻击测试所有4 款WAF,这是因为某些WAF不能保护应用程序免受特定攻击,当同时满足低拦截率和高通过率时,笔者认为WAF 不提供针对此种攻击的保护。由表1 可以看出,在测试的4 款WAF中,只有ModSecurity 和Naxsi 可以防止命令注入,这可能是因为命令注入攻击在Web 应用程序中相对较少,通常需要与其他攻击结合使用。由表1 还可以看出,一些WAF 有过于严格的规则,不仅阻止恶意攻击,而且阻止良性请求,这在现实条件下是不可行的,Naxsi 就是这种WAF,其提供了拦截阈值选项,因此,需要修改参数使其拦截能力达到较为合理的水平来进行测试。
表1 WAF 安全测试结果Table 1 WAF security test results %
表1 中的第3 列描述了使用原始数据集中恶意Payload 测试WAF 时的拦截率,其中被拦截的恶意Payload 将作为Payload 生成器的输入,第3 列这一指标显示了WAF 的拦截能力。可以看出,4 款WAF 应对一般的恶意攻击,均展现出了较高的拦截率。
表1中的第4列描述了使用良性Payload测试WAF的结果。可以看出绕过率很高,这表明WAF 的误报率很低。然而,并非所有良性数据绕过率都达到了高水平,以Naxsi为例,这款WAF 选择牺牲误报率来换取拦截率,因此对于恶意数据和良性数据的拦截率都达到了较高的水平,但对于被WAF 拦截的良性Payload,也选择其作为Payload 生成器的输入。
表1 中的第5 列描述了WAF 对生成的恶意Payload 的拦截率。在实验中,对每类攻击都生成数千个恶意Payload 来进行测试。图3~图5 直观显示了WAF 对生成的恶意攻击Payload 的拦截情况,其中每个直方图对应一种攻击,直方图长度表示拦截率。可以看出,所有3 种攻击的拦截率都大幅降低,这意味着生成了成功的绕过攻击。由图4 可以看出,所有受测试WAF 对原始恶意XSS 攻击的拦截率都高达90%。然而,以Safedog 为例,对于生成的恶意Payload,WAF 仅拦截到其中的26%,而未防护到其中大多数的攻击,说明本文提出的方案成功生成了大量恶意绕过攻击。
图3 SQL 注入攻击Payload 的拦截率变化Fig.3 The change of Payload interception rate during SQL injection attack
图4 XSS 攻击Payload 的拦截率变化Fig.4 The change of Payload interception rate during XSS attack
图5 命令注入攻击Payload 的拦截率变化Fig.5 The change of Payload interception rate during command injection attack
4.4 与现有方案的对比
SQL注入攻击是一种常见的攻击,目前已经有许多成熟的应对方案和工具。因此,以SQL 注入攻击为基准,将本文提出的方案与基于突变的方案[7](下文简称突变方案)以及SQLMap工具在ModSecurity和Safedog这2款WAF上进行实验比较。突变方案通过反复随机应用一些预定义的突变操作来生成恶意攻击Payload。SQLMap是一个面向SQL的开源渗透测试工具,利用其绕过脚本来生成Payload。选择SQLMap是因为此工具目前非常流行,被知名机构和安全专家广泛使用。
1)与突变方案的比较。突变操作是一个函数,其改变Payload 并保留原始语义。表2 中定义了多种突变操作,包括大小写变换、空格替换、注释插入、注释重写等。以大小写交换操作为例,其随机更改Payload 中关键字的大小写,由于SQL 不区分大小写,因此语义不受影响。将这些突变操作应用于原始数据集以生成绕过Payload。为了防止随机应用突变操作造成的随机性,生成10 组数据,并计算最终绕过率的平均值。
表2 突变操作定义Table 2 Definition of mutation operation
2)与SQLMap 的比较。SQLMap 是一种广泛使用的开源渗透测试工具,能够自动检测和利用SQL 注入漏洞。SQLMap 可以生成大量不同的SQL 注入攻击,涵盖了所有常见的SQL 注入攻击技术。本文选用的工具版本1.4.2.38 包含57 个绕过脚本。在实验中,舍弃了其中一些与编码相关的脚本,因为这些脚本是为特定的后端设计的,将对WAF 检测的准确性产生较大影响。本文将其他绕过脚本应用于原始数据集,同时,执行与突变方案相同的操作以减少随机性干扰。
在ModSecurity 和Safedog 上使用本文方案、突变方案和SQLMap 进行实验。在相同的环境中,测试3 种方案并对结果与原始绕过率进行比较,如表3所示。由表3 可以看出:所有方案都可以产生绕过WAF 的Payload,这表明WAF 普遍没有提供足够的保护;对于ModSecurity,突变方案和SQLMap 都能有效提高WAF 的绕过率,但本文方案能够得到最大的提高幅度,且远高于其他2 个方案;对于Safedog情况类似,但可以看到,使用突变方案后绕过率出现了降低,这可能是因为WAF 提供了针对突变的专门保护,因为突变样本与良性SQL 样本的差异很大,最初能够绕过的样本在突变后反而被拦截,导致绕过率降低,这也表明突变方案对于WAF 不是通用的;整体上,本文方案效果优于其他2 种方案,生成的数据具有较高的绕过率,且生成了更多绕过WAF 的恶意攻击。
表3 3 种方案生成Payload 的绕过率比较Table 3 Bypassing rate comparison of Payload generated by three schemes %
4.5 生成签名验证
在本节中,将评估输出加固签名的效率。为了生成加固签名,使WAF 能够有效拦截绕过的恶意攻击,需要实现以下2 个目标:最大化拦截的恶意攻击数量和最小化拦截的良性请求数量。在实验中,将使用拦截率和误报率这2 个指标作为检测结果的评价标准,拦截率表示恶意Payload 被判别为恶意Payload 的比例,误报率表示良性Payload 被判别为恶意Payload 的比例。本文使用原始数据集中的绕过样本以及良性Payload 来评估生成的加固签名。在实验中,需要检验这些签名的效率,即应用加固签名后的误报率和绕过率。
表4 体现了应用加固签名后WAF 拦截率的变化。签名需要在误报率和拦截率之间保持平衡,如果误报率过高,那么无论拦截率有多高都是没有意义的,因为这将导致良性和恶意Payload 的无差别拦截。从表3 的最后2 列可以看出,本文方案得到的加固签名实现了较高的拦截率。在应用加固签名后,拦截率高达90%甚至100%,表明签名阻止了多数恶意绕过攻击。此外,使用良性Payload 对其进行误报率评估,没有一条良性Payload 被拦截,表明加固后的WAF 对正常流量不会产生影响。笔者对误报率都为0 的情况也进行了分析,认为可能原因是恶意Payload 与良性Payload 区别很大,因此加固签名很难匹配到良性Payload。而现实情况也确实如此,与恶意Payload 相似或与良性Payload 不同的流量更有可能来自潜在攻击者,正常网络流量中不会出现与恶意Payload 相似的情况。总体而言,与应用加固签名之前的情况相比,应用加固签名后WAF 的防护能力有了较大的提高,拦截率保持在90%以上。
表4 加固签名评估结果Table 4 Evaluation result of reinforcement signature %
5 结束语
本文提出的WAF 加固方案通过RNN 模型生成恶意Payload,并用于测试WAF,以发现WAF 存在的安全问题,同时还设计了一个签名生成器,利用评分函数找到关键字符串来生成加固签名,保护WAF 免受后续类似攻击,解决了传统方案依赖专业知识的问题。实验针对3 种攻击类型评估4 款WAF,结果表明本文方案发现了大量恶意绕过Payload,生成的加固签名也有效地防止了这些攻击,并且误报率为0。后续将基于强化学习方法优化本文方案,通过从WAF 获得反馈来指导神经网络的学习,进一步改善Payload 的质量并提高绕过率。