APP下载

基于ECA规则和动态污点分析的SQL注入攻击在线检测

2023-05-24刘吉会何成万

计算机应用 2023年5期
关键词:污点字符串语句

刘吉会,何成万

(武汉工程大学 计算机科学与工程学院,武汉 430205)

0 引言

互联网服务的广泛使用使Web 应用日渐复杂,Web 应用的安全问题也因其易用性和开放性而日益显著,造成的漏洞越来越多[1-3]。在开放式Web 应用程序安全项目(Open Web Application Security Project,OWASP)发布的2013 年和2017年的Web 安全漏洞Top10[4]中,注入漏洞稳居第一,其中以SQL 注入为主体。SQL 注入攻击是一种代码注入攻击[5-6]。Web 应用程序中的SQL 语句通常由程序中受信任的常量字符串和用户输入等不受信任的外部数据动态拼接在一起,这会导致不受信任的数据(例如用户输入)被数据库引擎作为SQL 代码片段执行[7]。攻击者通过精心构造各种未经验证的畸形外部输入数据,欺骗数据库服务器执行恶意构造的SQL 语句以达到攻击的目的,对Web 应用潜在的数据库安全构成严重的威胁。因此,对SQL 注入攻击的检测研究具有非常重要的意义。

现有的SQL 注入攻击检测主要采用基于SQL 语句合法性进行判别的方法来检测攻击[8]。根据检测原理的不同,大致分为基于污点分析的方法、基于规则匹配的方法、基于文本向量化和机器学习的方法。基于文本向量化和机器学习的方法属于新兴的方法,由于数据集不够、分类模型不完善、SQL 语句特征提取困难等问题,存在着诸多挑战;而且在实际应用部署中,实现实时在线检测比较困难。基于规则匹配的方法是传统的SQL 注入攻击检测方法,又分为静态检测、动态检测、动静结合检测。静态检测如JDBCChecker(Java DataBase Connectivity Checker)[9]就是在不运行程序的情况下通过源码分析是否存在SQL 注入的可能。由于需要分析源代码,无法发现运行时发生的部分攻击,漏报率高且浪费人力物力,检测效率低下。动态检测如CANDID(dynamic CANDIDate evaluations)[10]在程序 运行时 动态挖 掘预期 的SQL 查询结构与构造的SQL 语句结构比对,在无法获得源代码情况下通过程序运行时动态生成的模型来判断是否存在SQL 注入攻击。动静结合检测如AMNESIA(Analysis and Monitoring for NEutralizing SQL-Injection Attacks)[11]静态分析应用程序生成正常SQL 语句查询模型,然后在程序运行时进行动态监控,比较构造的SQL 语句是否符合静态分析生成的SQL 语句模型,从而判断是否存在SQL 注入攻击并防御。基于规则匹配的方法在应用部署中要么需要源代码,要么需要在程序运行前进行程序插桩修改原始程序行为,这类方法的可重用性不足,且不能在Web 应用开启后加载检测组件以达到在线检测的目的。基于污点分析的方法大多需要修改应用程序的执行引擎,或需要修改应用的源代码,或通过代码重写技术对Web 应用进行预编译才能加载检测组件。这些技术无法在应用运行时在线加载检测组件,且与原始应用耦合性较高,容易干扰原始应用的业务逻辑,无法做到检测组件的可重用性和在线检测。

ECA(Event Condition Action)规则语言在Java 语义级别可以精确指定将要转换的类及其中的方法以修改原始应用程序的行为或增加额外的功能。Byteman[12]是一个字节码修改工具,采用这种清晰、简单且易于使用的基于Java 的ECA规则语言,使得它在应用程序加载时或运行时更改应用程序的行为变得简单。它工作时原始应用程序无须重写和编译。

本文提出一种基于ECA 规则和动态污点分析的在线检测SQL 注入攻击的模型。借助ECA 规则语言封装动态污点分析的整个过程,在Web 应用运行时通过安装ECA 规则脚本重新转换构成应用程序和虚拟机程序的原始字节码,从而在用户提交请求时触发相关检测组件的执行,在线检测是否存在SQL 注入攻击。ECA 规则语言构成的检测脚本完全独立于Web 应用的业务逻辑,在Web 应用启动后,整个检测脚本将被转化为内联Java 代码注入到Web 应用及其所属的虚拟机中。实验使用Byteman 实现了本文所提模型,并利用该模型在文献[11]使用的Web 应用bookstore 和WebGoat[13]上做实验,由ECA 规则语言封装的检测脚本经过安装进这些应用的Byteman 代理读取并自动转换构成Web 应用和虚拟机的字节码,从而将检测代码无缝插入到正在运行的应用基层子程序中。经过实验验证,这是一种低侵入性、轻量级的SQL 注入攻击检测方法,能够在不修改应用程序执行引擎和源码的前提下,实现Web 应用的在线检测,且可以检测出6种常见的SQL 注入攻击类型。

1 相关工作

Ray 等[5-6]定义了代码注入攻击。Halfond 等[14]对迄今为止已知的不同类型的SQL 注入攻击进行了广泛的回顾。SQL 注入攻击检测主要采用基于SQL 语句合法性判别的方法来检测攻击。依据检测原理的不同,分为基于规则匹配的方法、基于污点的分析方法、基于文本向量化和机器学习的方法。

基于规则匹配的检测方法通过创建特定的规则并对违反规则的行为进行识别来检测攻击。其中:正则表达式匹配的方法通过构建正则表达式对与所构建的正则表达式相违背的用户输入进行检测过滤[15]。语法树特征匹配的方法,如Bandhakavi 等[10]提出的方法,通过动态挖掘针对用户任何输入的、体现程序开发人员意图的查询结构,并将此结构与实际动态生成的SQL 查询语句结构相比较以检测是否发生SQL 注入攻 击。与之类 似的是Halfond 等[11]提出的AMNESIA,在静态分析阶段,通过获取正常查询语句结构构建合法查询的模型;在动态阶段,监视SQL 语句的构建,并将构建的SQL 语句与静态阶段建立的合法查询模型进行比较以检测攻击。文献[16]的研究继承了AMNESIA 的思想,借助静态代码工具获取SQL 语句模型,利用面向方面编程(Aspect-Oriented Programming,AOP)技术捕获程序执行中产生的SQL 语句,将静态SQL 语句模型与产生的SQL 语句进行比较,判断是否存在SQL 注入攻击。文献[17]中提出一种基于XML(eXtensible Markup Language)且只检测重言式SQL 注入攻击的方法。该方法包含一个XML 文件生成器,拦截用户输入并转换成XML 格式;然后XML 文件将用户凭据传递给Xschema 验证器,将生成的用户查询与Xschema 文件中预定义的合法查询进行比较,两个查询匹配时才允许其访问,否则阻止访问。该方法执行时间尚可,但检测攻击的类型单一。

基于污点分析的方案通过污点的标记和传播,可以准确区分SQL 语句的可信部分和不可信部分。污点检查比较可靠,主要分为静态污点分析和动态污点分析。在静态污点分析中:Jovanovic 等[18]提出的Pixy 使用流敏感、进程间和上下文敏感的静态数据流分析方法来挖掘Web 应用程序漏洞;Livshits 等[19]使用静态数据流分析技术检测标记的用户输入是否到达SQL 语句执行点以挖掘SQL 注入漏洞;Wassermann等[20]将SQL 语句构造过程抽象为上下文无关文法,并使用静态污点分析方法来判断文法中的非终结符是否与用户输入有关。由于静态污点分析不能很好地处理Web 应用语言的动态性,会引入较高的误报率,再加上保守的程序分析,使误报率会更高。

动态污点分析方法可以更好地处理程序的动态特性。Haldar 等[21]提出了一种动态解决方案,在运行时标记和跟踪用户输入,并防止用户不正当使用以恶意影响程序的执行;Perl 的污点模式[22]明确地将来自程序外部的数据标记为受污染,防止受污染的数据被用作某些敏感函数的参数;Nguyen-Tuong 等[23]修改PHP 执行引擎中String 类的数据结构和内置函数,在字符级对不可信数据进行污点标记与传播,并在汇聚点处分析SQL 语句语法结构;Rafailidis 等[24]设计了污点传播算法来实现实施安全策略的内联监视器;Chin等[25]针对Java 实现了高效率的字符级别的污点传播算法;董敏[26]基于C++语言的特性以影子内存原理封装基本数据类型,扩展污点标记位,重载运算符以实现数据在程序运行时的实时传播过程,并在污点汇聚点处解析SQL 语句的污点状态以触发报警装置;Halfond 等[27]则提出了积极污点标记方法的新概念,污点标记可信数据,如程序中的硬编码字符串,并动态跟踪污点传播轨迹,可有效解决不可信输入来源广泛、难以完整标记的问题。

从以上工作可以看出,对于SQL 注入攻击检测,动态污点追踪机制提供额外的污点信息来判断SQL 注入攻击行为,提高了检测准确性,且没有复杂的静态分析开销。文献[28-29]将此机制与AOP 的思想结合,使SQL 注入攻击的安全关注点从应用逻辑中分离出来由方面封装,赋予检测模型更高的可重用性。从代码级别捕获Web 应用基础设施的污点数据的流动,通过方面编织器将污点检测代码织入原始Web 应用相关的安全关注点中,在关注点中模拟动态污点分析的各个流程,避免了对Web 应用源码及执行引擎的直接修改。他们的方法既实现了对多数SQL 注入攻击类型的检测,又对攻击检测代码的可重用实现作出努力;但他们的方法部署需要预编译加载检测组件,在线加载检测组件难以实现。

基于文本向量和机器学习的方法针对SQL 语句的合法性进行判断。它们针对正常和恶意SQL 语句进行特征向量的提取和向量化,选取合适的分类模型进行数据集的训练。由此研究人员提出了许多方法和改进的措施。如李红灵等[30]提出的基于支持向量机(Support Vector Machine,SVM)和文本特征向量提取的SQL 注入攻击检测技术、苏林萍等[31]提出的基于N-gram 和词频逆向文件频率(Term Frequency Inverse Document Frequency,TF-IDF)的SQL 注入攻击检测方法等。相关数据集的数据量不够、分类模型的不完善以及SQL 语句特征提取困难等问题,使这个方面的研究存在诸多困难;而模型检测的准确度和效率完全取决于数据集的质量。

2 本文模型

ECA 规则精确指定在运行时应如何改变应用程序行为。规则的三个组成部分事件(Event)、条件(Condition)、动作(Action)分别定义如下:1)在应用程序执行期间应该发生副作用的地方;2)副作用是否应该发生;3)副作用应该是什么。因此,ECA 规则可以识别应用程序中外部数据流动经过的函数,并在该函数执行过程中在规则指定的位置插入相应的副作用。如果条件判断为真,副作用就会发生,就会改变原始应用的行为;反之,副作用不会发生。

污点分析技术[32]包括污点源、污点汇聚点和无害化处理等部分。其中,污点源表示将污点数据引入系统中;污点汇聚点表示系统将污点数据输出到敏感数据区或外界,造成敏感数据区被改写或机密数据被泄漏;无害化处理表示通过数据加密或重新赋值等操作使数据传播不再对系统的完整性和机密性产生危害。污点分析就是分析程序中由污点源引入的数据能否不经无害化处理而直接传播到污点汇聚点[33]。由于ECA 规则的特性,它可以精确识别污点源函数、污点传播经过的函数和污点汇聚点函数,在这些函数对应位置中插入的副作用就是污点标记、污点传播、污点检查动作,而副作用发生的条件就是判断函数参数及函数调用者对象是否携带污点,若携带污点,则执行相应的污点分析动作。

本文提出的基于ECA 规则和动态污点分析的SQL 注入攻击检测模型如图1 所示。

图1 基于ECA规则和动态污点分析的SQL注入攻击检测模型Fig.1 SQL injection attack detection model based on ECA rules and dynamic taint analysis

它的处理流程主要分为三个步骤:第一,针对污点源的ECA 规则自动识别污点源,在污点源处对被引入系统的外部数据进行污点标记;第二,针对污点传播的ECA 规则自动识别污点传播经过的函数,判断函数参数以及函数调用者对象的污点状态,以此决定是否标记函数返回值,从而在程序运行时实时跟踪污点数据的流向;第三,针对污点汇聚点的ECA 规则自动识别污点汇聚点,在污点汇聚点处对将要执行的SQL 语句进行词法语法分析评估其污点状态,从而判断是否存在SQL 注入攻击。在Web 应用运行时,安装ECA 规则,实现检测模块的自动在线加载。此时,检测模块就会在用户提交请求后发挥作用。ECA 规则比较系统完整地模拟了动态污点分析过程,实现了针对待测Web 应用中外部数据进入系统后从污点源到污点汇聚点经过的所有可能的基本函数的自动识别以及在相应函数中插入相应的污点分析逻辑。这些基本函数包括服务器请求接口的方法(污点源,如ServeltRequest.getParameter())、字符串类中具有污点传播能力的字符串操作方法(污点传播经过的函数,如String.append())、Java 数据库连接(Java Database Connectivity,JDBC)接口中的方法(污点汇聚点,如Statement.executeQuery())。在用户发起请求后,Web 应用中与该请求相关的基本函数的执行就会触发与之相关的ECA 规则的执行,相关规则就会随着污点数据在系统中的流动而自动触发执行污点标记、污点传播、污点检查动作,从而判断当前用户的请求是否存在SQL注入攻击。当Web 应用处理用户请求时,外部数据实际会经过哪些基本函数的处理对用户而言是模糊的,对ECA 规则而言是透明的。检测模块独立于原始Web 应用的业务逻辑,作为一个整体被ECA 规则定义,在线安装ECA 规则可以将检测模块动态插入到正在运行的Web 应用中;同时,也可以在线卸载ECA 规则,被规则影响的基本函数就会恢复原状。安装卸载规则的过程中,无须重新编译、打包、部署Web应用。

2.1 污点标记算法

本文基于Java EE(Java platform,Enterprise Edition)框架作具体论述。不可信数据进入程序中,参与SQL 语句的动态构建,并最终被数据库服务器当作SQL 代码执行。由于SQL注入攻击涉及的都是字符串的构建,因此本文为JDK(Java Development Kit)中的String、StringBuffer、StringBuilder 三个字符串类的实例建立一个映射。每一个字符串实例与一个StringData 类实例相对应,相对应的StringData 类实例存储了该字符串实例的污点状态信息。StringData 类包含一个布尔变量字段和一个布尔数组字段:布尔变量表征该实例是否被污染,布尔数组则表征该字符串实例的每个字符的污染状况。若布尔变量为false,则相应的布尔数组为空,这样可以节省内存。

动态污点标记如图2 所示,在Web 应用运行时,污点源ECA 规则一经安装,就会自动识别污点引入函数,在该函数业务逻辑中增加对规则的触发调用。当用户提交的数据经过污点引入函数时,污点标记规则自动触发,评估条件为真执行污点标记动作,标记用户提交的数据。

图2 污点标记示意图Fig.2 Schematic diagram of taint marking

污点标记的算法如算法1 所示,创建一个StringData 类,初始化该类字段,布尔变量字段赋为true,布尔数组字段的每一个数组元素赋值为true,然后以方法参数param为键将新创建的StringData 实例存储到taintMaps 映射表中。这种标记的好处在于既不用扩展字符串类String 等的污点属性,使污点标记的逻辑与原来字符串处理逻辑弱耦合,也不用在某些字符串处理函数再进行额外的污点标记和污点去除的操作,还可以保证污点标记的精度。

算法1 污点标记算法。

2.2 污点传播算法

污点传播算法的设计参考文献[21,27-28]的思想。污点传播分析要解决的就是外来数据在程序内部的实时传播跟踪与存储的问题。ECA 规则负责识别污点传播经过的函数,然后在规则动作执行条件中判断经过函数的调用者和参数是否被污染:若被污染,在该字符串函数返回之前,规则将根据函数的调用者和参数的污点状态将它们的污点状态合并组合传播给函数返回值;反之不执行相关的污点传播动作。污点传播逻辑由ECA 规则定义,而字符串处理函数的逻辑则在字符串操作类中,从而设计出既不会破坏程序执行逻辑,又能保持污点方法跟踪污点数据的传播轨迹的方法。

针对JDK 字符串类中的基础字符串函数,本文逐一实现污点传播逻辑。污点传播算法如算法2所示,分三种情况进行讨论:1)如果JDK 字符串类中函数(如toString()、subString()等)只有携带污点的字符串调用者对象,则将字符串调用者对象的污点状态传播给函数返回值;2)如果JDK 字符串类中函数(如构造函数)参数为携带污点的字符串对象,则将该字符串对象的污点状态传播给函数返回值;3)如果JDK 字符串类中函数是这一类函数(如append()、replace()等),则函数调用者对象和参数对象均可能携带污点,将这二者可能携带的污点状态合并传播给函数返回值。通过该算法实现JDK字符串类中基础字符串函数级别的污点传播分析,避免了传统的基于指令级别的污点传播分析。

算法2 污点传播算法

由于字符串类为引用对象类型,字符串类之间赋值的本质是向某个内存的指针赋值。本文污点的存储方式是基于映射的方式,即一个字符串对象对应一个污点存储的位置,当带污点的字符串对象赋值给另一个变量,则另一个变量与被赋值的变量指向同一个存储污点的内存,赋值操作不用更新taintMaps 映射,即自动将污点从等号右边传向左边。

2.3 污点检查算法

标准Servlet 程序中所有和数据库交互的相关操作都封装在JDBC 库中。SQL 注入污点汇聚点是消耗用户输入的敏感函数,如executeQuery()、executeUpdate()等。使用污点检查规则就可以在函数开始执行前捕获这些敏感函数的参数并对它们进行语法解析,从而判断是否发生SQL 注入攻击。若判断发生SQL 注入攻击,则污点检查规则执行通知开发人员的动作。

对程序中动态构建的SQL 语句进行词法语法分析以构建语法分析树,遍历语法分析树的所有终端结点,检查它们的污点状态。若污点仅仅分布在字符串文本和数字文本中,则没有发生SQL 注入攻击;若污点部分或全部分布在SQL 关键字、操作符、特殊字符等,则可以认为发生SQL 注入攻击[27]。为了降低污点传播性能的损失,每次执行语法解析之前都会清空taintMaps 中存储的键值对。污点检查算法如算法3 所示。

算法3 污点检查算法

3 模型实现

本文基于Byteman 工具实现了所提出的模型。Byteman规则引擎负责解析ECA 规则,将它表示的内联Java 代码转化为字节码,由Byteman 代理插入到Web 应用的字节码中。由此,在Web 应用请求数据流动的过程中,就会执行ECA 规则集指定的污点分析动作。ECA 规则语言涉及到的内置操作集由Byteman 的帮助类加以扩展或替换。由Byteman 帮助类实现有关动态污点分析动作的内置操作集,就可以使ECA规则语言具有污点分析的功能。基于Byteman 工具实现模型共分为四个部分:Byteman 帮助类的定义、污点标记实现、污点传播实现以及污点检查实现。

3.1 Byteman帮助类的定义

Byteman 单个ECA 规则的基本架构如图3 所示。ECA 规则语言中,E(event)为规则事件,用来规范标识与目标类关联的目标方法中的特定位置。目标方法可以是静态或实例方法或构造函数。RULE、CLASS、METHOD、AT 子句定义规则事件。C为condition,由IF子句定义。A为actions,由DO 子句定义,当与规则匹配的类及方法执行时,就会触发该规则的执行。由该规则转化地注入应用程序中的字节码执行过程是:首先判断IF子句的condition表示的条件是否为真,若为真,则执行DO 子句后面的actions 表示的单个或多个动作;否则,不执行由DO 子句定义的动作,即规则虽然触发但没有执行实际的动作。Byteman 工具存在的意义在于为用户提供ECA 规则语言,使用户可以在Java 语义级别直观地修改运行中的应用程序和JVM 的字节码。Byteman 的底层规则引擎通过Java代理机制实现了ECA规则到字节码的自动转换。

图3 单个ECA规则的基本架构Fig.3 Basic structure for single ECA rule

在图3 中,HELPER 子句定义的是与该规则相关联的、由用户自行定义的帮助类。对于ECA 规则而言,可以使用的内置操作集并不固定。规则引擎将规则中调用的内置操作集与该规则相关联的帮助类的公共实例方法相对应,任何被指定为帮助类的类必须是非抽象和可继承的,它的公共实例方法自动变为规则事件、条件、动作中可调用的内置操作集。在图4(a)~(c)的3 个规则中,setTaintedInSource、isTainted、setTaintedByMethod、parse 等内置操作对应下面自定义帮助类HelperSub2 的公共成员方法。所以规则condition 或actions 子句对某些方法的调用实质就是对该规则关联的帮助类的公共实例方法的调用。在图4 中,污点标记、污点传播、污点检查规则脚本都与帮助类HelperSub2 相关联,由此有关污点标记、污点传播、污点检查和污点存储的具体实现也是在该帮助类中完成的。该类编写完成打包为jar 包,在Web 应用启动后,使用Byteman 写好的脚本bmsubmit 命令于命令行上在线提交该jar 包到引导类路径中,以扩展在线提交规则集的内置操作集。根据图4 所示的内容,下面将详细阐述污点分析规则脚本的编写以及相应的污点标记、传播、检查算法的实现。

图4 Byteman帮助类的定义Fig.4 Definition of Byteman Helper class

3.2 污点标记实现

以图5 所示的污点规则示例1 进行描述,RULE 子句中RULE 关键字后面为规则名,INTERFACE、METHOD、AT 子句则表明该规则触发执行的位置,即在所有实现javax.servlet.ServletRequest 接口的实现类中的getParameter 方法返回之前才触发该规则的执行。IF 子句为规则动作是否执行的条件,DO 子句为该规则触发后具体执行的操作,setTriggering(false)方法总是返回true,对getParameter 方法返回的字符串$!执行污点标记的动作,具体地设置污点标记的实现在Byteman 自定义帮助类HelperSub2 中完成。在该规则中,$!为Byteman 的特殊变量,自动与getParameter 方法的返回值绑定。

图5 污点规则示例1Fig.5 Taint rule example 1

与图5 类似的ECA 规则脚本共同监视应用可能引入外部数据的函数,一旦这些函数执行,就会执行相应的污点标记动作。这些脚本都与帮助类HelperSub2 相关联,脚本调用的污点标记动作之一setTaintedInSource()在该帮助类中作一个公共成员方法来实现。核心代码如下:

3.3 污点传播实现

监控污点经过的字符串操作函数的规则集都与HelperSub2 类相关联,从而将针对字符串操作函数的污点设置方法整合在一个类中。一系列监控污点传播经过的函数的规则集和它们调用的在帮助类中实现的各污点传播动作构成了本文所提模型中污点传播算法的具体实现。

针对JDK 字符串类中每个字符串操作函数均有相应的规则需要编写。以图6 所示的规则示例2 举例阐述,该规则匹配StringBuilder 类中的append(String)方法,判断$!,$1的污点状态以决定是否在该方法返回之前给该方法返回值设置污点标记。该规则中$1 与append 方法的第一个参数自动绑定。设置污点方法是setTaintedByAppend(),该方法针对append()方法进行处理,具体污点处理操作在自定义帮助类HelperSub2 中实现。由于利用Byteman 比较完整地实现了针对污点传播经过的字符串函数的规则,但实际应用到哪些字符串函数对于用户而言是模糊的,对于规则而言却是透明的。由此,用户不需要知道数据流经过哪些具体的字符串操作函数,由规则自动识别而触发执行污点传播动作。

图6 污点规则示例2Fig.6 Taint rule example 2

针对图 6 规则调 用的污 点传播动作setTaintedByAppend ($!,$1),在帮助类HelperSub2 中实现的核心代码如下:

判断函数参数是否携带污点的内置操作isTainted()在帮助类HelperSub2 中实现的核心代码如下:

3.4 污点检查实现

图7 规则示例3 显示的规则识别所有实现Statement 接口的实现类的executeQuery()方法的执行,在该方法执行第一条语句前判断规则条件以执行通知开发人员动作。在规则条件中,首先检查该方法参数是否携带污点,若携带污点,则规则调用parse()方法对方法参数即动态构建的SQL 语句进行词法语法分析,从而判断是否存在SQL 注入攻击。对于所有敏感函数接口(如executeUpdate 等),均有相应的规则与之对应,这些规则调用HelperSub2 类中的parse 方法,污点检查算法在parse 方法中实现。

图7 污点规则示例3Fig.7 Taint rule example 3

parse 方法实现的核心代码如下:

4 实验与结果分析

为验证本文所提模型的有效性,在文献[11]中使用的bookstore 和WebGoat[13]上进行测试。为了在这些Web应用上进行测试,还需要针对每一个应用的SQL 注入攻击测试集(负样本)和正常访问请求集(正样本),负样本中含有多种类型的SQL 注入攻击,正样本包含富文本字面量及无SQL 语义字符。在笔记本电脑上搭建实验环境,利用正负样本测试集测试目标应用以验证SQL 注入攻击在线检测模型的有效性。

4.1 实验设置与测试结果分析

首先启动Web 应用,此时在命令行输入jps 查询应用执行的进程号,并输入Byteman 写好的命令bminstall,将Byteman 代理安装到对应进程(正在运行的Web 应用)的Java虚拟机中,使用bmsubmit 命令提交自定义帮助类jar 包,然后在线提交ECA 规则集。此时的Web 应用已经加载了在线检测模块,模块随时监测Web 应用接收的请求。在虚拟机Linux 系统中使用wget 命令批量提交请求以及手动注入,模拟攻击者频繁发送包含SQL 注入行为的请求和正常的请求,检测模型会对每一个请求在应用中产生的SQL 语句进行评估以判断是否存在SQL 注入攻击行为。对检测结果进行统计之后,结果如表1~3 所示。

表1 SQL注入测试用例及检测结果Tab.1 SQL injection test cases and detection results

表1 列出了各种SQL 注入攻击类型的测试用例代表的攻击字符信息和检测结果,所提模型能根据污染的敏感攻击字符在SQL 语法分析树中的位置判断动态生成的SQL 语句的合法性,从而判断出表1 中的测试用例存在SQL 注入攻击行为。

表2 列出了针对每个Web 应用攻击的SQL 注入攻击请求样本数和成功检测到攻击的样本数。针对两个Web 应用发送大约1 200 个SQL 注入攻击请求样本,发现本文模型可以检测到绝大多数的攻击样本,说明该模型具有一定的检测能力。

表2 恶意请求样本检测结果Tab.2 Detection results of malicious request samples

表3 给出了针对每个Web 应用发送的正常请求样本数和检测到SQL 注入攻击行为的样本数。从表中数据可以看出,发送了大约800 个正常请求样本,本文检测模型没有检测到SQL 注入攻击行为,说明该模型并没有将正常的请求误认为存在SQL 注入攻击行为的恶意请求,即不存在误报的情况。

表3 正常请求样本检测结果Tab.3 Detection results of normal request samples

综上所述,可以发现本文模型能够检测出常见SQL 注入攻击类型,如重言式、非法或逻辑错误查询、联合查询等,针对发送的SQL 注入攻击请求样本能识别出绝大多数具有SQL 注入攻击行为的请求样本,针对正常请求没有出现误报。上述实验结果可以说明本文模型是有效的。

4.2 与其他检测方法的比较分析

由于有些检测方法源码并不开放,难以复现,只能通过阅读大量的文献分别从检测能力和部署要求等方面进行粗略的分析评估。每种检测方法的检测能力见表4,每种检测方法的实施部署要求见表5。其中:表4 使用“√”表示可以检测到此种类型的攻击;“*”表示部分可以检测的情况;“×”表示不能检测该类型的攻击。

表4 不同方法的检测能力比较Tab.4 Comparison of detection capability of different methods

表5 不同方法的部署要求比较Tab.5 Comparison of deployment requirements for different methods

从表4 以看出,文献[9]的方法侧重于类型安全,文献[17]的方法侧重于重言式,它们只能检测SQL 注入攻击的一小部分,而当前其他一些主流方法基本都可以检测到所有类型的SQL 注入攻击,文献[30-31]中通过机器学习与特征向量提取的方法构建检测模型,模型训练准确率分别可以达到91.05%、98.67%。本文方法检测准确率达到99.42%,在检测能力上可以与这些方法相当。

从表5 可以看出,文献[10-11,27]的方法采用某种插桩工具离线插桩来加载检测模块,文献[23]的方法修改了PHP解释器,文献[26]的方法则重新定义字符串类及其相关的赋值连接操作,用这种语言编写有漏洞的Web 应用来加载检测模块。本文方法既不修改运行时系统,也不需要修改原始字符串类,在未作任何修改的Web 应用启动后运行时就可以在线提交规则集以加载检测模块,部署方式更加灵活方便。

另外,本文和文献[28]都采用代码注入的方式将检测代码注入Web 应用程序实现SQL 注入攻击检测。文献[28]的方法采用AOP 实现静态注入,而本文使用ECA 规则实现了在线注入,可以实现Web 应用的在线检测,并且ECA 规则可以在线卸载,使Web 应用恢复原状。因此,本文模型是一个低侵入性的无须重新编译、打包、部署应用的SQL 注入攻击检测模型。另外,文献[28]的方法对不可信数据进行首尾标记,并把拼接后的字符串的属性taint 设为true,而本文方法对不可信数据采用映射的方式进行污点标记与存储,即每一个不可信数据对象与一个存储污点信息的对象相对应,这样标记的好处是不影响应用的字符串处理逻辑,与应用逻辑弱耦合,而且可以保证精度。

4.3 模型实时性分析

本文模型在加载后,除了可以检测SQL 注入攻击行为,还要考虑它对原始Web 应用造成的性能损失,即当用户发起请求后,检测模型能否及时给出检测结果。在Web 应用的3个注入点,测试加载检测模块前、后提交正常和恶意请求后得到响应的时间,每个请求提交200 次,计算出平均响应时间。通过比较两者时间的差异,初步评估模型施加给应用的性能开销。测试结果如表6 所示。从表6 可以看出,3 个注入点测试中,当发送正常请求时,加载检测组件后,平均响应时间最多增加11 ms;当发送恶意请求时,加载检测组件后的平均响应时间最多增加13 ms。由此可以初步评估,本文模型加载后对Web 应用的施加的影响比较小,对正常和恶意的请求,模型能及时判断出是否存在SQL 注入攻击行为。

表6 注入点加载前后的平均响应时间比较 单位:msTab.6 Comparison of average response time before and after loading injection points unit:ms

5 结语

针对当前SQL 注入攻击检测方法不能在线注入检测代码的不足,本文提出了一种基于ECA 规则和动态污点分析的SQL 注入攻击检测模型。该模型在Web 应用运行时安装ECA 规则,自动加载SQL 注入攻击检测代码。在攻击者发送请求时自动触发检测组件的执行,从而在线检测Web 应用是否受到SQL 注入攻击。整个检测模块由ECA 规则脚本封装在一起,与Web 应用原来的逻辑相互独立,脚本可在线安装和卸载,具有轻量级和低侵入性的部署优点,在脚本安装卸载过程无须修改应用程序执行引擎和源码,无须重新编译、打包、部署Web 应用。本文基于Byteman 实现了所提模型,并通过实验验证了模型的有效性。但本文方法也具有局限性,只能解决污点传播中数据依赖传播,没有考虑控制依赖传播。因此未来的研究计划中,将本文方法适用于其他种类的Web 安全威胁防御中。

猜你喜欢

污点字符串语句
基于代码重写的动态污点分析
基于文本挖掘的语词典研究
重点:语句衔接
使用Lightroom污点去除工具清理照片中的瑕疵
我国“污点证人”刑事责任豁免制度的构建
一种新的基于对称性的字符串相似性处理算法
如何搞定语句衔接题
依据字符串匹配的中文分词模型研究
一种针对Java中字符串的内存管理方案
作文语句实录