基于AOP与SQL结构分析的SQLIAs动态检测及防御

2018-04-19 07:37何成万
计算机工程 2018年4期
关键词:语句静态应用程序

何成万, ,,

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

0 概述

SQL注入漏洞[1]是网站中一种普遍存在的安全隐患。随着Web应用程序的应用越来越广泛,SQL注入攻击(SQL Injection Attacks,SQLIAs)[2]成为Web应用系统当前面临的最大威胁。文献[3]统计出2013年十大Web应用安全隐患,SQLIAs名列第1位。SQLIAs指攻击者通过恶意构造的输入数据拼接到表单页面的文本输入框中,通过欺骗服务器执行恶意构造的SQL命令而得到脏数据信息,从而达到攻击的目的。之前典型的SQL注入[4]更多的是针对服务器端的数据库,然而根据目前HTML5规范,攻击者可以采用完全相同的办法执行 JavaScript 或其他代码访问客户端数据库从而窃取数据。因此,如何更加有效地防御SQLIAs成为十分重要的研究课题。

面向方面编程(Aspect-Oriented Programming,AOP)[5]的核心思想是以方面的形式捕捉横切关注点,即以模块化的方式、程序语言支持及工具支持来捕捉横切关注点。AOP在方面的定义上引入通知、切入点、连接点等机制以实现各个方面间的联系[6]。其优点是可有效地将目前纠缠在功能需求中的非功能需求代码剥离出来,在代码级别上实现关注点分离。

现有的多数SQLIAs检测防御方法只对部分SQLIAs有效,不能检测出所有的SQLIAs。为此,本文提出一种基于AOP与SQL结构分析的SQLIAs动态检测及防御方法,借助AOP技术,结合静态分析与动态捕获的方式比较SQL语句的逻辑结构,从攻击的根源对SQLIAs进行有效检测和防御。

1 相关研究

之前,研究者们在SQLIAs的检测与防御方面做了许多工作,提出了一些新的技术方案。具体情况如下:

文献[7]提出的JDBC-Checker技术,能够阻止的SQLIAs非常有限。文献[8]提出SQLGuard模型,其原理是在运行过程中推导出SQL语句树,并对比用户输入前后的 SQL 树结构是否有变化。该方法直接生成2棵SQL语句树进行匹配,优点是不需要对语句树设置唯一标识,缺点是生成了多个源树。文献[9]针对基于Java的Web应用程序,如jsps、servlets、Frankl 等提出一种自动移除SQLIAs的工具,该技术通过静态分析与程序转换相结合的方式,在代码中自动修复SQL注入漏洞。文献[10]提出一种智能动态查询评估技术,通过学习和预测用户输入的SQL查询目的,将已经确定的SQL结构与用户输入之后生成的查询结构进行比较,以此检测可能的攻击。文献[11]提出一种认证机制,其使用先进的加密标准来阻止SQLIAs,该加密标准使用哈希函数保存密码和用户ID,使每个用户在服务器端都保存有用户名、密码和密钥这3个重要参数。该技术的缺点是重用性低。文献[12]提出一种基于错误和异常检测技术的SQLIAs检测框架,该框架的主要思想是通过分析被提交到数据库的合法查询行为创建一个文件,根据这些合法的行为特征识别可能的SQLIAs。文献[13]提出使用逆向代理和MD5算法检测用户输入的SQLIAs,使用语法表达式的规则检测URL地址中的SQLIAs。文献[14]针对SQLIAs提出一种新策略,即代码指针屏蔽(CPM),该策略先实施正确的语义代码指针,然后依据CPM 监控指针的变化,以此转移应用程序控制流。

2 方法步骤

基于AOP与SQL语句结构分析的SQLIAs动态检测及防御方法,核心是对源码中的SQL语句在参与到查询前后的逻辑结构进行比较,通过校验被构造出的SQL语句逻辑结构是否一致来判断SQL注入的发生。本方法分为2个步骤,即代码静态分析和SQL语句动态捕获,其中,代码静态分析借助代码分析工具获取程序中包含的所有SQL语句结构;SQL语句动态捕获借助AOP技术在程序执行过程中自动获取包含用户输入数据的SQL语句。对上述2个SQL语句的逻辑结构进行分析比较,如果结果一致,即静态SQL模型值与动态捕获的SQL串完全匹配,则为一次正常请求;如果结果不一致,则表示此次请求已被恶意构造改变了原有SQL语句的逻辑结构,可以将其视为一次SQLIAs。

在详细介绍本文方法之前,先以一个简单的示例来说明方法的基本思想。在接收用户输入后参与构造SQL语句的程序代码如下:

public static User findUser(String userName,

String password){

User user=null;

String sq1=“select * from user_qw where”;

Connection conn=DBUtil.getConnection();

Statement stmt=conn.createStatement();

sq1+=“username=′”+userName+“′ and pwd=′”+password+“′”;

ResultSet rs=stmt.executeQuery(sq1);

}

对上述代码进行静态分析后得到SQL语句结构:select * from user_qw where username=′′and pwd=′′。

如果用户输入合法的用户名(如“guest”)和密码(如“123”),则程序构造的SQL语句为select * from user_qw where username=′guest′ and pwd=′123′。由于该SQL语句结构和上述通过代码分析得到的SQL语句结构一致,因此判断该查询不包含SQLIAs。

如果用户试图发动攻击,输入含特殊字符的用户名(如“′or 1=1--”),则构造后的SQL语句为select * from user_qw where username=′′or 1=1--′ and pwd=′′。由于该SQL语句结构和上述通过静态分析得到的SQL语句结构不一致,因此判断该查询是一次SQLIAs。

本文方法的整体结构框架如图1所示。

图1 SQLIAs检测及防御方法框架

2.1 静态分析

静态分析的主要功能是通过分析得到源程序中要执行的每个SQL语句所对应的静态语句串,保存该静态语句串,其中SQL语句中出现的变量参数以空字符串表示,同时记录下每个SQL语句执行点对应的执行周围环境,包括执行点位置信息、Signature签名信息。静态分析部分要在Web应用程序第一次部署的时候完成,其流程如图2所示。

图2 静态分析流程

静态分析具体步骤如下:

1)分析Web应用程序中JDBC函数库与数据库之间实现交互的函数接口特征,并定位应用程序中出现的交互点,即含有变量且将被送往数据库被执行的SQL语句点。

2)通过静态分析获取每个交互点的位置信息、Signature信息及静态SQL语句模型。

3)将以上获取到的信息保存至本地文件中,保存的顺序为交互点位置信息、Signature信息、静态SQL语句模型。

2.2 动态捕获

针对已经执行过静态分析的Web应用程序,借助AOP技术,首先声明方面,然后在JDBC函数库与数据库交互的接口位置定义切入点,请求到达后执行通知函数中的校验流程,此即动态捕获,其具体流程如图3所示。

图3 动态捕获流程

动态捕获具体步骤如下:

1)根据静态分析得到的接口处方法名,在JDBC函数库与数据库交互的接口方法处自动生成切入点函数,使得SQL语句在被送往数据库服务器执行之前,先执行切入点的通知函数。

2)分别捕获方法调用的Signature信息和方法调用上传递的参数值信息。

3)根据动态SQL语句的Signature信息唯一确定其对应的静态SQL语句模型,将动态SQL语句串与静态SQL模型的逻辑结构进行比较。如果结果一致,则提交数据库,继续后续操作;否则,视为一次SQLIAs行为。

3 方法实现

3.1 静态分析实现

静态分析部分具体实现过程如下:

1)先分析源应用程序的后台代码与数据库的交互接口,查找当前所有的交互点,一般的Web应用程序利用JDBC函数库与数据库进行交互,通过分析库函数的接口,如java.sql.Statement.execute Query(String sql),了解这些函数的Signature信息,进而得到需要执行的SQL字符串在这些函数中的参数位置,即交互点[15]。其中如果所有SQL语句字符串执行前后都不存在可变量,或者SQL字符串不会被提交到后台数据库,就不能将其算作交互点。

2)借助静态分析工具JSA(Java String Analyzer[16],该工具是一个用于分析已编译的类文件中字符流和字符串操作的开源工具),对所需应用程序编译后的class文件进行静态分析,即得到每个交互点的静态SQL语句模型、Signature信息及交互点位置信息。调用JSA库函数的一些核心代码如下:

ObjectInputStream in = newObjectInputStream(new FileInput Stream(“sql.reg”));

Iterator hi = hotspots.iterator();

while (hi.hasNext()) {

String sf = sa.getSourceFile(e);

}

3)扩展JSA库函数,在其库函数AnalyzeSQL类文件中添加写入本地指定文件中的写方法,即将静态分析得到的交互点位置信息、Signature信息以及静态SQL语句模型按照先后顺序保存在本地文件中。由于除了保存静态SQL语句模型,还有交互点位置和对应的Signature信息,因此可以唯一标识该静态SQL语句模型。JSA库函数扩展代码如下:

String staticSQLModel=

quoteString(diff.getShortestExample(true));

String sqlStaticInfor=

line+“,”+sf+“,”+staticSQLModel.substring(1,staticSQLModel.length()-1);

File f = new File(“文件路径名”);

BufferedWriter output = new BufferedWriter(new FileWriter(f,true));

output.write(sqlStaticInfor+“ ”);

output.close();

3.2 动态捕获实现

动态捕获部分具体实现过程如下:

1)借助AOP技术首先定义方面和切入点,使得SQL语句在被送往数据库服务器执行之前,先执行切入点的通知函数,在通知函数中获取需要的信息。根据由静态分析得到的SQL语句信息,判断出对应该处执行的数据库交互函数的方法名,根据该方法名自动生成AOP程序的切点函数。

2)编写call(Signature)和args([TypePatterns]|[Identifiers])切入点,在通知函数中使用this Joint Point类来捕获方法调用上的Signature信息和传递的参数值信息,从而得到动态SQL语句串。核心实现代码如下:

public aspect CaptureCallParametersPecipe {

pointcut captureCallParameters(String dSqlStr) :

call(java.sql.ResultSet

java.sql.Statement.executeQuery(String))

&& args(dSqlStr);

before(String dSqlStr):captureCallParameters(dSqlStr) {

String signature=thisJoinPoint.getStaticPart().getSignature();

String sourceLine=thisJoinPoint.getStaticPart().

getSourceLocation();

String dSql=dSqlStr;

String[] sourceLocationInfor=sourceLine.toString().split(“:”);

}

3)如上述代码所示,动态捕获到的信息有SQL执行点的位置、源文件的类名、实时SQL语句串。此处SQL语句串中包含从外部输入拼接进去的参数,因此,在与静态SQL语句模型进行比较之前需要先对动态SQL进行去参处理。由于静态分析情况下得到的信息也按照上述顺序依次保存,通过执行点的位置信息和源文件的类名信息可以唯一确定执行的SQL语句,因此只有三部分完全匹配才能证明该动态SQL语句串与静态SQL模型值匹配成功。具体比较过程如下:

(1)对由动态捕获到的SQL语句串进行去参处理。

(2)读取经过静态分析生成的SQL语句模型文件,并依次遍历其内容。

(3)按照信息保存的顺序,依次比较动态SQL语句串与静态SQL模型值的SQL执行点位置、源类文件名称、SQL语句串值,只有三部分完全相同,才能说明该动态SQL语句值与静态SQL值完全匹配,即SQL结构没有被改变,然后继续后续操作;否则,视为一次SQLIAs。

动态捕获与SQL逻辑结构比较的伪代码如下:

{

//存储含有SQL攻击行为对应的静态SQL语句模型

String staticStr=“”;

if (常规校验) {

//动态调用SQL查询语句的环境信息

String[] sourceLocationInfor=thisJoinPoint. getStaticPart().getSourceLocation().toString().split(“:”);

//动态SQL串的完整信息

String dSqlInfor=sourceLocationInfor[1]+

“,”+sourceLocationInfor[0]+“,”+newDsqlStr;

//读取静态分析文件,查找对应的SQL并比对 BufferedReader reader= new BufferedReader(new FileReader(file);

//遍历静态模型值,与动态获取的SQL串进行比较

for (int i = 0; i < staticSqlModelList.size(); i++) {

if (不完全匹配) {

//得到对应的静态SQL串staticStr

return proceed(staticStr);

}

}

return proceed(dSqlStr);

}

4 实验结果与分析

4.1 实验准备

根据本文方法的介绍,静态分析部分是在系统应用程序部署之前要提前执行的。首先需要对测试对象的应用程序中与数据库交互的Java类文件做静态分析,用JSA分析工具分析其对应编译后的class文件,并得到对应的执行点以及该位置的Signature信息,为每一个执行点生成对应的静态SQL模型,并将这些语句串按照执行点位置、源类文件及静态SQL串的顺序保存在本地文件中。在本次实验中设计一个简单的Web项目,包含用户登录页面,其中与数据库交互的UserDAO.java类文件中包含提交数据库执行的非安全编码SQL查询语句。针对本实验的测试项目对所需类文件进行静态分析的结果如图4所示。

图4 静态分析结果

分析完UserDAO文件后,在其保存的文件中会执行的SQL语句完整信息为:

26,UserDAO.java,select * from user_qw where username=′′and pwd=′′

解析完后会得到该文件中所有将执行的SQL语句以及执行点的位置和源类名。

在登录界面动态构造重言式攻击,即用户名输入“′or 1=1--”,密码输入“123”,点击登录,执行后台查询用户的方法,借助AOP技术在切入点的通知函数中动态捕获到的SQL语句完整信息为:

26,UserDAO.java,select * from user_qw where username=′′or 1=1--′ and pwd=′′

由此可知,对由静态分析与动态捕获到的SQL串值按照执行点位置、源类名、SQL语句值的顺序依次进行比较,在构造重言式攻击后得到的动态SQL语句值与静态分析下得到的SQL语句不一致,因此,将其视为一次SQLIAs。

为了增强说服性,本次实验共列举了如表1所示的6种攻击形式来构造测试用例,通过将静态SQL模型值与动态获取的SQL串进行匹配,根据匹配的结果判断是否存在SQLIAs。

表1 不同攻击类型的测试用例对应的防御结果

4.2 方法性能分析

4.2.1 测试用例设计

下面分别对本文方法在插入AOP程序前后2种情况下的执行时间进行比较分析。首先,该方法的正常访问执行流程为:部署项目→浏览器输入URL地址请求→根据请求访问后台action→调用DAO层的数据库交互代码→执行SQL查询命令。插入AOP程序后程序的执行流程为:部署项目→浏览器输入URL地址请求→根据请求访问后台action→调用DAO层的数据库交互代码→在executeQuery方法执行之前执行方面代码→执行SQL查询命令。

针对以上执行流程的介绍,考虑到测试一次的结果不稳定且不具有代表性,因此,在前台页面处模拟多次提交URL地址请求,测试脚本代码如下:

function test(){

var begin = new Date();

for(var i= 0; i < 500; i++){

document.getElementById("formId").submit();

}

var end = new Date();

console.log(end-begin);

}

在后台DAO层与数据库交互的代码段前后添加时间标记代码用于记录执行的时间差,测试代码如下:

PerformanceMonitor.beginMethod();

rs=stmt.executeQuery(sql);

PerformanceMonitor.endMethod();

PerformanceMonitor.printPerformace();

PerformanceMonitor类主要用于监控目标代码在执行前后所需要的时间差,其中包含3个方法,beginMethod用于标记开始时间,endMethod用于标记介绍时间,printPerformance用于输出两者的时间差。

4.2.2 数据分析与比较

本文采用4组实验进行测试,前2组分别为插入AOP程序前正常请求与发生攻击行为情况下的数据测试与记录;后2组分别为插入AOP程序后正常请求与发生攻击行为情况下的数据测试与记录。每组实验需要记录的数据为测试单数执行时间、测试多数执行总时间。因为无论是正常请求还是发生注入攻击时,SQL在数据库中的查询时间是固定的,仅受实验平台的影响,所以在记录数据时考虑记录下插入AOP程序前后的单次执行时间。实验详细记录情况如表2所示。

表2 执行时间实验结果 ms

根据表2所记录的实验结果,分别将1组、3组(正常请求下的响应时间)和2组、4组(发生攻击下的响应时间)进行比较。首先由1组、3组时间值可看出,单次执行情况下,插入AOP程序前后响应时间分别为1 ms和8 ms;执行500次的情况下,插入AOP程序前后执行总时间分别为2 656 ms和6 972 ms,此种情况下求得单次平均所需时间值分别为5.312 ms和13.944 ms。其次由2组、4组数据可看出,在发生攻击行为的情况下,插入AOP程序前后单次响应时间分别为1 ms和7 ms;执行500次的情况下,平均单次所需时间分别为5.462 ms和11.662 ms。不同组间数据相比较的柱状图如图5和图6所示。

图5 1组、3组实验时间比较

图6 2组、4组实验时间比较

通过图5、图6数据可以看出,不论是正常请求下还是发生攻击行为时,插入AOP对程序的执行响应时间影响并不大,单次增加值在6 ms~9 ms之间,这完全在用户可以接受的范围之内。

通过对以上实验数据的分析与比较,可知本文提出的基于AOP的SQLIAs检测与防御方法在时间性能方面表现良好,没有造成太大的性能开销,所以,其不会影响到用户的体验。

4.3 与现有SQLIAs防御方案的比较

由于每种防御方案的实验环境不一样,有些源码并不开放,在查阅了相关研究论文后分别从功能和性能两方面对本文方法以及部分现有方法进行分析比较,每种防御方法防范能力的比较结果见表3,每种防御方法在实施时所需的部署要求以及自动化程度见表4。其中表3用3种不同类型标记符号表示不同的防御情况:“√”表示该防御方法可以成功阻止此种类型的所有攻击行为;“×”表示该方法不能防御此种类型的攻击;“*”表示该方法仅对此类基本的攻击起到防御作用。

表3 不同防御方法攻击种类比较

表4 不同防御方法部署要求比较

由表4可以看出,结合静态、动态分析的SQLGuard和SQLChecker技术需要修改源代码、管理密钥,而且自动化程度不高;实现基于动态分析的CSSE系统需要事先修改PHP解释器;AMNESIA在动态监控部分需要插入监控代码,使得原应用程序性能大为降低,另外还需额外为每个SQL语句模型生成一个唯一的ID进行标识。

相比较而言,本文方法首先通过静态分析得到每个SQL执行点对应的SQL静态模型值,该模型值包括执行点位置以及Signature信息,两者可以唯一确定一个SQL字符串,不需要额外的指定ID进行唯一标识;然后借助AOP技术对用户输入数据进行动态捕获,将结果与之前静态SQL模型值进行一一匹配,不存在生成多余SQL语句树的情况。因此,本文给出的防御方法与现行的防御系统相比,具有易于部署、配置灵活、适用性强等优点。

5 结束语

本文提出一种基于AOP与SQL结构分析的SQLIAs动态检测及防御方法。根据代码静态分析的结果自动生成AOP连接点定义,在程序运行过程中动态获取包含用户输入数据的SQL语句,将其与不包含用户输入数据的SQL语句逻辑结构进行分析比较,从而达到检测和防御SQLIAs的目的。实验结果表明,本文方法能有效检测和防御不同类型的SQLIAs,同时具有容易部署、不需要修改源码等优点。同时实验数据还表明,本文方法在时间性能方面表现良好,即插入AOP程序后不会产生太大的时间开销。但是本文的研究工作还有不足,基于此,下一步将扩展本文方法,使其能够适用于更多种类的攻击类型,同时多比较不同静态源码分析工具的优缺点,分析其得到的静态信息并研究如何将其无差别地运用到本文方法中。

[1] LIM J,KIM S,KIM D,et al.A designated query protocol for serverless mobile RFID systems with reader and tag privacy[J].Tsinghua Science and Technology,2012,17(5):521-536.

[2] 张 卓.SQL注入攻击技术与防范措施研究[D].上海:上海交通大学,2007.

[3] GOSWAMI S,KRISHNAN N R,VERMA M,et al.Reducing attack surface of a Web application by open Web application security project compliance[J].Defence Science Journal,2012,62(5):324-330.

[4] SHARMA P,JOHARI R,SARMA S S.Integrated approach to prevent SQL injection attack and reflected cross site scripting attack[J].International Journal of System Assurance Engineering and Management,2012,3(4):343-351.

[5] MENASCE D,GOMAA H,MALEK S,et al.SASSY:a framework for self-architecting service-oriented sys-tems[J].IEEE Software,2011,28(6):78-85.

[6] 洪 贵.面向方面软件开发冲突问题的研究[D].长沙:国防科学技术大学,2007.

[7] GOULD C,SU Z,DEVANBU P.JDBC checker:a static analysis tool for SQL/JDBC applications [C]//Proceedings of International Conference on Software Engineering.Washington D.C.,USA:IEEE Press,2004:697-698.

[8] GREGORY B,BUEHRER,BRUCE W,et al.Using parse tree validation to prevent SQL injection attacks[C]//Proceedings of the 5th International Workshop on Software Engineering and Middleware.New York,USA:ACM Press,2005:106-133.

[9] MUI R,FRANKL P.Preventing SQL injection through automatic query sanitization with ASSIST[J].Electronic Proceedings in Theoretical Computer Science,2010,35:27-38.

[10] SELVAMANI K,KANNAN A.ISQL-IDPS:intelligent SQL-injection detection and prevention system[J].European Journal of Scientific Research,2011,51(2):222-231.

[11] KINDY D A,PATHAN A S K.A detailed survey on various aspects of SQL injection in web applications:vulnerabilities,innovative attacks and remedies[J].International Journal of Communication Networks and Information Security,2013,5(2):80-92.

[12] SHAIMAA E S,MOHAMED I M,LAILA M E,et al.Web anomaly misuse intrusion detection framework for SQL injection detection[J].International Journal of Advanced Computer Science and Applications,2012,3(3):123-129.

[13] HIDHAYA S F,GEETHA A.Intrusion protection against SQL injection attacks using a reverse proxy[C]//Proceedings of International Conference on Advanced Computer Science and Information Technology.Washington D.C.,USA:IEEE Press,2012:129-144.

[14] PHILIPPAERTS P,YOUNAN Y,MUYLLE S,et al.CPM:masking code pointers to prevent code injection attacks[J].ACM Transactions on Information and System Security,2013,16(1):1-27.

[15] 竺霞芳.双层防御SQL注入攻击的方法[D].武汉:华中科技大学,2011.

[16] LI D,LYU Y,WAN M,et al.String analysis for Java and Android applications[C]//Proceedings of Joint Meeting on Foundations of Software Engineering.New York,USA:ACM Press,2015:661-672.

猜你喜欢
语句静态应用程序
最新进展!中老铁路开始静态验收
静态随机存储器在轨自检算法
重点:语句衔接
删除Win10中自带的应用程序
谷歌禁止加密货币应用程序
油罐车静态侧倾稳定角的多体仿真计算
我喜欢
三星电子将开设应用程序下载商店
作文语句实录
微软软件商店开始接受应用程序