2. 福建师范大学 福建省网络安全与密码技术重点实验室, 福州 350117;
3. 福州职业技术学院 信息技术工程系, 福州 350108
2. Fujian Provincial Key Laboratory of Network Security and Cryptology, Fujian Normal University, Fuzhou 350117, China;
3. Department of Information Technology Engineering, Fuzhou Polytechnic, Fuzhou 350108, China
随着Web 3.0时代的到来以及B/S模式的迅速发展, Web技术在许多领域都得到了广泛的应用, 且已成为世界经济发展中的关键技术之一[1]. 与此同时, Web的安全问题也日趋严峻, Web安全威胁已经成为网络安全威胁最主要的来源之一. 因此, 对Web安全的研究也成为了目前网络安全领域的重点和热点[2]. 其中, SQL注入作为Web应用程序面临的最普遍、最高危的攻击之一, 连续多年位列OWASP(开放式Web应用程序安全项目, Open Web Application Security Project)年度十大攻击行为, 并且多次排名第一.
基于上述分析, 本文结合URL长度、访问频率及SQL语法树, 提出了一种新的SQL注入过滤方法——LFS (length-frequency-SQL syntax tree)过滤方法. 该方法包括学习和过滤两个阶段. 学习阶段在安全的环境下进行, 通过爬虫和数据库代理, 根据用户提供的爬虫启始数据进行爬取, 生成URL和SQL语句的映射表. 过滤阶段工作在现实环境下, 通过检测长度、连接频率、SQL语法树特征, 以此来检测SQL注入攻击. 仿真实验及结果分析表明LFS方法相较于传统的关键字过滤和正则表达式过滤能够更有效的防止SQL注入攻击.
1 相关工作针对SQL注入攻击检测, 国内外研究人员已经做了大量的研究工作, 并且取得了一定的研究成果. 张燕等[3]提出了一种基于数据挖掘技术的SQL注入攻击检测方法. 该方法首先收集了数据库日志中内部查询树; 然后, 根据查询树的语义、语法特征和查询树类型提取查询树的特征向量; 最后, 根据多项式核函数SVM对这些特征向量进行分类, 从而实现SQL攻击检测.
黄保华等人[4]提出了一种SQL语句块摘要树模型, 用于检测SQL注入攻击. 基于该模型的SQL注入检测对SQL语句序列进行了检测, 有效地提高了拦截率, 但是在数据库连接共享的环境中, 该模型由于需要对顺序执行的SQL序列进行检测导致实施起来存在一定的困难. 赵宇飞等人[5]根据SQL注入攻击的网络流量与正常用户请求的网络流量有较大的区别, 以网络流量分析的角度, 提出了LFF(length-frequency-feature)检测方法. 张志超等人[6]结合人工神经元网络, 提出了一种基于人工神经元网络的SQL注入漏洞的分析模型. 该模型利用人工神经网络算法对用户输入的SQL语句进行检测, 从而判断用户是否在进行SQL注入攻击.
王伟平等人[7]利用正则表达式对SQL注入攻击的特征进行描述, 并提出了基于正则表达式的SQL注入攻击过滤方案. 该方案与关键字过滤相比, 具有更高的识别率和较低的误报率. Ivan Ristc开发的开源项目ModSecurity[8]和Roesch M开发的入侵检测软件Snort[9]同样根据SQL注入攻击的特征定制SQL注入攻击的特征规则集, 并以此过滤用户的输入来抵挡SQL注入攻击. 田玉杰等人[10]提出了一种基于分类的SQL注入攻击双层防御模型. 该模型采用了基于Http请求分类的用户输入过滤, 以此降低用户输入过对正常数据的误报率. 应用SQL语法结构比较和于参数化分类的动态查询匹配, 从而提高了用户输入过滤的拦截率和语法结构比较的检测效率.
Ain Zubaidah Mohd Saleh等人[11]将提出了一种Web应用程序漏洞检测方法. 该方法结合了Boyer-Moore字符串查找算法, 能够有效地检测多种Web安全漏洞, 例如SQL注入, XSS等Web安全漏洞. Nency Patel等人[12]改进了Aho-Corasick模式匹配算法, 并将该算法应用于SQL注入攻击防御. 传统的防止SQL注入的模式匹配往往采用静态的模式匹配算法. 但是改进的Aho-Corasick模式匹配算法能够捕捉SQL注入引起的新异常模式, 并将反复出现的新异常模式自动加入模式匹配库中. Jemal Abawajy等人[13]针对SQL注入攻击在RFID系统中的危害, 提出了一种基于策略的SQL注入攻击检测方法. 该方法通过制定合法的SQL查询语句规则形成规则库, 之后对RFID系统传输的数据进行拦截验证, 并根据合法的SQL查询语句规则库进行检测, 以此来防御SQL注入.
同时, 还可以通过采用参数化查询, 在代码层对SQL注入攻击进行防御[14]. 使用参数化查询访问数据库, 能够防止SQL注入, 使Web应用程序更加安全. 此外, 通过对存储过程的访问权限的正确配置也能够防止SQL注入, 提高系统安全性. 存储过程将一组SQL语句集编译后存储在数据库中, 以此来提高安全性、防止SQL注入. 例如, 黄龙军[15]在网上考试系统中利用SQL Server存储过程有效地防御SQL注入攻击, 提高了系统的安全性.
2 SQL注入过滤方法概述 2.1 SQL注入攻击概述SQL注入攻击是一种由攻击者通过影响应用程序向后台数据库传递的SQL查询而引发的攻击. SQL注入攻击是一种通过操纵Web输入来修改后台SQL语句以利用代码进行攻击的技术[16]. 虽然不同种类的SQL注入的攻击方式有所区别, 但它们的原理和过程基本相同. SQL注入攻击过程和原理如图1所示.
攻击者在登录界面使用账号admin’和密码admin进行登录. 客户端浏览器向Web服务器发送URL为: http://www.test.com/login.asp?username=ad min’&password=admin的请求. 之后Web服务器向数据库服务器发送SQL语句, 该SQL语句为: select * from accounts where username=’admin’ and password=’admin’. 数据库执行该SQL语句后向Web服务器返回敏感信息, 并最终由Web服务器将该敏感信息转发给了客户端浏览器, 从而被攻击者获取.
2.2 SQL注入过滤方法
对于特定的Web应用程序, 其发送的HTTP请求报文的URL和参数与Web应用程序收到请求报文执行的SQL语句存在一定的映射关系. 并且任何拥有SQL攻击特征的输入都将改变原有的SQL语句的语法结构. 因此若用户输入构成的SQL语句的语法结构和期望中的语法结构不一致, 则该输入为SQL注入. 本文方法基于上述前提, 提出了一种新的SQL注入过滤方法, 该方法将SQL注入防护分为两个阶段: 学习阶段和过滤阶段.
2.2.1 学习阶段学习阶段工作在安全环境下, 利用爬虫和数据库代理, 根据用户提供的启始文件(XML文件), 该文件包含爬虫的启始数据, 对该Web应用程序进行爬取, 生成该Web应用程序的HTTP请求报文中的URL和Web应用程序执行的SQL语句的映射表(XML文件). 其运行环境如图2所示.
以图1为例, 假设用户发送的URL为http://www.test.com/login.asp?username=admin&password=123456&type=admin, 则之后Web应用程式执行的SQL语句为: select * from accounts where username=‘admin’ and password=‘123456’ and type=‘admin’. 过滤系统先对该SQL语句进行解析生成对应的语法树, 之后将语法树的结点与爬虫发出的HTTP报文中的数据进行对比, 其数据发出时必须不重复, 并且不包含有SQL关键字如select, and, or等. 若数据一致并且该数据在原SQL语句中被‘’(一对单引号)所引用, 则该数据类型为字符型, 将SQL语句中对应的数据改为该数据对应的Http数据报文中的参数名. 若数据一致, 该数据为数字并且在原SQL语句中没有被‘’所引用, 则该数据类型为数字型, 将SQL语句中对应的数据改为该数据对应的Http数据报文中的参数名并在该参数名两侧加上*符号. 据此将Web生成的SQL语句改为: select * from accounts where username=‘username’ and password=‘passwor d’ and type=‘type’. 若该url会根据用户输入的执行不同的SQL语句, 则需在相应的启始文件写入各种情况的启始数据并将该对应的<param>的change属性设置为true. 生成的映射表(XML文件)利用选择标签<if>和<elseif>分情况存储SQL语句. 假设上面的例子根据type属性执行不同的SQL语句, 则图3和图4分别给出了相对应的启始文件和URL与SQL语句映射表的XML文件. 表1和表2分别给出了启始文件的标签和映射表标签. 其中图3的sql标签的元素where username =‘username’ and password = ‘password’中, 其中对SQL的抽取的原理如下.
SQL注入攻击往往会改变原有的SQL语句语法树的结构. 以SQL语句“select a from b where c=?”(其中? 为占位符)为例, 对于正常的用户输入, 假设用户输入为admin, 则其SQL语法树结构如图5所示. 对于SQL注入攻击, 假设用户输入为admin ‘or’ 1 ‘=’ 1 , 则其SQL语法树结构如图6所示. 由图5和图6中的语法树结构可见, 由于SQL语句“select a from b where c=?”(其中? 为占位符)中用户输入的数据位于where子树, 所以其它SQL语法树中并没有改变结构. 因此对SQL的抽取没有必要抽取整个SQL语句, 只需根据用户输入数据所对应的位置, 对该子树进行解析并记录下该子树的根节点和特征(该子树的结点总数), 抽取对应的SQL语句. 以SQL语句“select a from b where c=?”(其中? 为占位符)为例, 则对应抽取的SQL语句为: where c=?(其中? 为占位符, 根据与爬虫发出的数据的对比结果确定的Http数据报文中的参数名), 并记录该子树根结点为where, 特征为4.
2.2.2 过滤阶段
过滤阶段工作在现实环境下, 通过检测长度、连接频率, 并根据映射表和用户的输入构建SQL语句, 再对该SQL语句进行解析获取特征值, 之后将该特征值与映射表的SQL语句特征进行匹配, 以此来检测SQL注入攻击. 其工作环境如图7所示.
在HTTP的get请求方式中, SQL注入攻击过程往往需要向URL中拼接SQL语句, 所以SQL注入的URL长度相较于正常的URL长度会有所区别. 因此当HTTP的URL长度超过某个阈值时, 则该用户输入可能为SQL注入攻击, 需要进行进一步判断. 文献[7]中研究表明, 大部分的HTTP的get请求方式中URL的长度普遍在5–70 byte之间, 所以本文设置URL长度阈值为70 byte, 当URL长度大于70时, 则记录该请求由人工进行进一步判断.
SQL注入攻击的HTTP连接频率往往高于正常用户的HTTP连接频率. 所以, 单位时间内HTTP请求的三元组<源IP, 目的IP, 目的端口>的频率能够作为检测SQL注入的一个标准. 文献[7]中研究表明, 正常网络的HTTP连接频率为4.87次/s, 但其中大部分连接频率远低于该值. 因此, 本文将连接频率的阈值定为3次/s. 检测中, 如果某个三元组的连接频率大于3次/秒, 则记录该请求由人工进行进一步判断.
SQL注入攻击往往会改变原有的SQL语法树结构. 因此, 可以根据用户的输入提取映射表中对应的SQL语句信息, 之后根据相应的信息进行SQL解析. 再与映射表的SQL语句特征进行匹配, 若匹配成功则为正常输入. 若匹配失败则为SQL注入攻击. 以上文中的图4为例, 假设用户的正常输入为admin和123456, 则对应的解析后的SQL语法树子树如图8所示. 假设SQL注入攻击的输入为admin和123456’or’1’=’1, 则对应的解析后的SQL语法树子树如图9所示. 由此可见用户正常输入的SQL语法树子树的特征与SQL注入攻击的SQL语法树子树的特征有所区别. 因此, 可以根据SQL语法树子树的特征来检测SQL注入攻击.
3 SQL注入过滤方法详细流程及模块介绍 3.1 学习阶段流程本文提出的SQL注入过滤方法的学习阶段的具体流程描述如下:
步骤1. 读取用户提供的爬虫启始数据放入待抓取URL队列并生成URL与SQL语句的映射表. 之后读取待抓取URL队列的队头数据.
步骤2. 判断步骤1中提取的URL是在已抓取URL队列中, 若存在则直接结束, 准备读取下一个待抓取URL. 若不存在则进行步骤3.
步骤3. 发送HTTP请求, 并根据其中的URL和请求方式在映射表中相应的位置生成<url>和<type>标签. 之后获取SQL语句并解析成SQL语法树.
步骤4. 将步骤3生成的SQL语法树的叶子结点逐个与HTTP报文中参数的数据进行比较. 若数据不一致, 则比较下一个结点; 若所有结点都不一致, 则直接结束, 准备读取下一个待抓取URL; 若数据一致, 则进行步骤5.
步骤5. 判断步骤4的数据是否被’’所引用, 若被’’所引用, 则该数据类型为字符型, 将SQL语句中对应的数据改为该数据对应的Http数据报文中的参数名. 若该数据为数字并且在原SQL语句中没有被’’所引用, 则该数据类型为数字型, 将SQL语句中对应的数据改为该数据对应的Http数据报文中的参数名并在该参数名两侧加上*符号.
步骤6. 抽取SQL语法树, 记录下抽取子树的根结点和特征. 之后在映射表中对应的<url>标签中生成对应的<sql>标签.
步骤7. 准备读取下一个待抓取URL, 重复步骤1到步骤6.
3.2 过滤阶段流程本文提出的SQL注入过滤方法的过滤阶段的具体流程描述如下:
步骤1. 首先, 将对HTTP请求方式进行判断. 如果是GET方式, 提取URL进入步骤2, 如果是POST方式, 提取实体进入步骤3.
步骤2. 对URL的长度进行检测, 若长度大于70 byte, 则记录该请求由人工进行进一步判断, 之后进入步骤3. 否则直接进入步骤3.
步骤3. 提取当前HTTP请求中的三元组<源IP, 目的IP, 目的端口>, 若其不存在于三元组表中, 则创建该三元组. 若存在于三元组表中, 则相应的三元组连接数加1, 并对该三元组进行连接频率检测, 若连接频率大于3次/秒, 则记录该请求由人工进行进一步判断, 之后进入步骤4. 否则直接进入步骤4.
步骤4. 根据URL查找学习阶段生成的URL和SQL语句映射表, 获取相应的SQL语句, 子树根结点, 语法树特征等信息. 从HTTP请求中提取相应的参数值, 构建SQL子句. 根据映射表中的子树根结点, 对该SQL子句进行进行对应的SQL解析得到SQL语法子树. 若解析析失败则进行二次解析; 若解析成功继续步骤5. 二次解析时过滤模块自动生成完整的SQL语句进行解析. 以上文中的where username=’admin’ and password=’123456’ and type=’admin’为例, 生成select a from b where username=’admin’ and password=’123456’ and type=’admin’进行解析. 若仍解析失败则判断该输入为SQL注入攻击, 解析成功则继续步骤5.
步骤5. 将步骤4生成的SQL语法子树的特征(SQL语法子树的结点总数)与映射表中的特征进行匹配. 若一样则将该输入判定为正常输入; 若不一样该则将输入判定为SQL注入攻击.
步骤6. 获取下一条HTTP请求, 重复步骤1到步骤5.
3.3 模块介绍本文提出的方法的设计模块图如图10所示.
1) 数据提取模块: 负责提取HTTP报文中的数据. 在学习阶段时, 并将相关的数据存入配置文件中. 在过滤阶段, 并结合映射表生成相应的SQL语句.
2) 爬虫模块: 该模块包括待抓取URL队列和已抓取URL队列. 爬虫从待抓取URL队列中依次读取URL, 之后根据URL访问对应网页. 同时将已经访问的URL发送给已抓取URL队列, 以避免重复抓取. 对于刚抓取的网页, 则从中抽出所包含的所有链接信息, 并在已抓起队列中检测, 若发现链接还没被抓取, 则将该URL放入待抓取URL队列末尾. 直至待抓取URL队列为空时才停止抓取网页.
3) 判断模块: 负责对HTTP连接的URL长度、连接频率进行检测. 若URL长度大于70 byte或连接频率大于3次/s, 则记录该请求由人工进行进一步判断. 并比较SQL解析模块生成的SQL语法树的特征值与映射表中的特征值, 根据结果判断该用户输入是否为SQL注入攻击.
4) SQL解析模块: 负责对SQL语句进行解析, 生成相应的SQL语法树. 该模块包括词法分析和语法分析. 词法分析负责将输入的SQL语句进行分词. 语法分析在词法分析的基础上, 判断输入的SQL语句是否符合语法逻辑. 当语法分析正常结束后, 则输出相应的抽象语法树.
5) 日志: 负责接收其他模块的记录请求, 并将疑似SQL注入攻击的HTTP请求记录在日志中.
6) 配置文件: 配置文件包括用户提供的启始文件(XML文件)和URL和SQL语句映射表(XML文件). 其中启始文件包含用户提供的爬虫启始数据. URL和SQL语句映射表中包含了URL和SQL语句的映射信息.
4 仿真实验与性能分析本文通过搭建实际的测试平台来检测和分析LFS方法的性能. 测试平台使用tomcat服务器, 后台数据库采用MySQL数据库, Web应用程序为小型J2EE招聘系统, 涵盖登录, 查看简历等功能并代码中存在SQL注入漏洞. 测试数据为SQL注入攻击输入, 包含SQL关键字的用户输入和用户正常输入各100条, 其中SQL注入攻击输入由SQLMAP生成. 为了测试LFS过滤方法对于SQL注入攻击的拦截率和误报率, 本文对LFS过滤, 关键字过滤和正则表达式过滤(含30条过滤规则)进行了比较. 测试结果如图11、图12和表3所示.
测试结果表3、图11和图12表明了本文提出的LFS过滤方法相较于关键字过滤和正则表达式过滤有更高的拦截率和更低的误报率, 能够较好的对SQL注入进行防御.
为了测试LFS过滤方法对于Web应用程序性能的影响, 本文分别对Web应用程序未加载过滤模块和Web应用程序加载了过滤模块这两种情况分别进行测试, 测试结果如图13、图14、图15和表4所示.
图13表明, 对于不含关键字的正常访问, 加载过滤模块与否对Web应用程序响应时间有略微的影响, 加载了过滤模块将导致Web应用程序响应时间有略微的延迟, 但对用户体验影响不大. 图14表明, 对于含有关键字的正常访问, 过滤模块需要对该用户请求进行URL长度和连接频率的检测. 之后需要根据映射表和用户输入的数据进行SQL解析, 但是用户输入中含有SQL关键字(如select、order by等)可能会改变了原有的SQL语句的语法, 造成SQL解析失败, 进行二次解析, 致使系统响应时间较长. 图15表明, 对于SQL注入攻击, 当没有加载过滤模块时, SQL注入攻击能够改变Web应用程序的SQL语句, 使得后台数据库执行该SQL语句, 从而导致Web应用程序响应时间有明显; 当加载了过滤模块时, 由于要对url长度和连接频率进行检测, 并且过滤模块对复杂的SQL语句的解析时间较长, 导致系统响应时间增加. 表4则给出了加载过滤模块与否, 在三种输入中的平均系统响应时间. 因此对于SQL注入攻击, 不论加载了过滤模块与否和系统响应时间都会有所延迟, 导致了两者的系统响应时间较为接近. 因此, 该过滤模块对于系统的响应延迟在可接受的范围内, 对用户体验的影响不大.
5 结束语
论文针对SQL注入攻击问题展开研究, 并结合爬虫、数据库代理等技术, 提出了一种新的SQL注入过滤方法——LFS过滤方法. 首先, 通过采用爬虫和数据库代理技术构建URL和SQL语句映射表, 完成学习过程; 其次, 通过对URL长度、访问频率及SQL语法树这三个方面进行检测, 实现对用户输入进行过滤, 防止SQL注入, 完成过滤过程; 最终, 将学习过程和过滤过程有机结合, 实现了新的LFS过滤方法. 仿真实验和性能分析结果表明, 论文提出的LFS过滤方法能够有效的防止SQL注入攻击, 在拦截率和误报率方面优于关键字过滤方法和正则表达式过滤方法.
然而随着系统业务的不断提高, 应用程序可能会随着用户输入的不同而产生不同的SQL语句, 这给本方法带来很大的挑战. 一方面导致本方法在学习阶段可能无法获取所有的SQL语句, 另一方面由于SQL语句的数量不可控, 可能导致学习阶段产生的URL和SQL语句映射表数据量巨大, 从而导致在过滤阶段耗时有显著增加. 我们同时注意到可变语句(随着用户输入的不同而产生不同的SQL语句)的产生有和大相似度, 例如相关的SQL语法树结构有很大的相似性, 变化的只有SQL语句的局部. 因此, 在未来的研究工作中, 我们考虑采用基于SQL语法树的相似度的方法来对学习阶段产生的URL和SQL语句映射表进行压缩, 以此减少过滤时间.
[1] |
郑成兴. 网络入侵防范的理论与实践. 北京: 机械工业出版社, 2006.
|
[2] |
高鹏, 严望佳. 构建安全的Web站点. 北京: 清华大学出版社, 1999.
|
[3] |
张燕. 数据挖掘提取查询树特征的SQL注入攻击检测. 电子技术应用, 2016, 42(3): 90-94. |
[4] |
黄保华, 马岩, 谢统义. 用于SQL注入检测的语句块摘要树模型. 信息安全与技术, 2012(3): 34-37. |
[5] |
赵宇飞, 熊刚, 贺龙涛, 等. 面向网络环境的SQL注入行为检测方法. 通信学报, 2016, 37(2): 88-97. DOI:10.11959/j.issn.1000-436x.2016034 |
[6] |
张志超, 王丹, 赵文兵, 等. 一种基于神经网络的SQL注入漏洞的检测模型. 计算机与现代化, 2016(10): 67-71. DOI:10.3969/j.issn.1006-2475.2016.10.014 |
[7] |
王伟平, 李昌, 段桂华. 基于正则表示的SQL注入过滤模块设计. 计算机工程, 2011, 37(5): 158-160. |
[8] |
Becher M. Web application firewalls. Akademikerverlag: Universiti Teknologi MARA, 2012.
|
[9] |
Roesch M. Snort-lightweight intrusion detection for networks. Proceedings of the 13th USENIX Conference on System Administration. Berkeley, CA, USA. 1999. 229–238.
|
[10] |
田玉杰, 赵泽茂, 王丽君, 等. 基于分类的SQL注入攻击双层防御模型研究. 信息网络安全, 2015(6): 1-6. |
[11] |
Saleh AZM, Rozali NA, Buja AG, et al. A method for web application vulnerabilities detection by using boyer-moore string matching algorithm. Procedia Computer Science, 2015(72): 112-121. DOI:10.1016/j.procs.2015.12.111 |
[12] |
Patel N, Shekokar N. Implementation of pattern matching algorithm to defend SQLIA. Procedia Computer Science, 2015(45): 453-459. DOI:10.1016/j.procs.2015.03.078 |
[13] |
Abawajy J, Fernando H. Policy-based SQLIA detection and prevention approach for RFID systems. Computer Standards & Interfaces, 2015(38): 64-71. |
[14] |
Wei K, Muthuprasanna M, Kothari S. Preventing SQL injection attacks in stored procedures. Proceedings of 2006 Software Engineering Conference. Sydney, Australia. 2006. 191–198.
|
[15] |
黄龙军. 存储过程技术在网络考试系统SQL注入攻击防御上的应用. 计算机系统应用, 2013, 22(1): 103-106. |
[16] |
Clarke J. SQL Injection Attacks and Defense. Amsterdam: Elsevier, 2009.
|