-1-基于SQL的Web系统安全防范——SQL注入漏洞攻击研究及防范措施SQL-BasedWebSystemSecurity——StructuredQueryLanguageInjectionLeakAttackStudyAndDefenseMeasure作者:辽宁省经济和信息化委员会姜志坤摘要:在当今的数字世界中,人们发现在维持公开的Internet连接的同时,保护网络和计算机系统的安全变得越来越困难。病毒、木马、后门、蠕虫等攻击层出不穷,虚假网站的钓鱼行为也让警惕性不高的公众深受其害。据有关部门统计,2008年一季度,我国有15万台主机被植入木马,网站篡改数量迅速增加,预计已达5835个,其中政府网站达484个,每月564次的安全事件报告。为了减轻信息泄露及系统攻击带来的风险,企业和机构开始对自己的系统进行渗透性测试,找出其中存在的漏洞和安全隐患。本文通过对目前最流行的SQL注入漏洞攻击的过程做了逐一的分析,并提出了检测方法和防范措施。关键字:SQL注入漏洞攻击脚本攻击SQL注入点检测防范模型有害代码SQL注入(SQLInjection)漏洞攻击是目前网上最流行最热门的黑客脚本攻击方法之一,那什么是SQL注入漏洞攻击呢?它是指黑客利用一些Web应用程序(如:网站、论坛、留言本、文章发布系统等)中某些存在不安全代码或SQL语句不缜密的页面,精心构造SQL语句,把非法的SQL语句指令转译到系统实际SQL语句中并执行它,以获取用户名、口令等敏感信息,从而达到控制主机服务器的攻击方法。1.SQL注入漏洞攻击原理1.1SQL注入漏洞攻击实现原理SQL(StructuredQueryLanguage)是一种用来和数据库交互的语言文本。SQL注入的攻击原理就是攻击者通过Web应用程序利用SQL语句或字符串将非法的数据插入到服务器端数据库中,获取数据库的管理用户权限,然后将数据库管理用户权限提升至操作系统管理用户权限,控制服务器操作系统,获取重要信息及机密文件。SQL注入漏洞攻击主要是通过借助于HDSI、NBSI和Domain等SQL注入漏洞扫描工具扫-2-描出Web页面中存在的SQL注入漏洞,从而定位SQL注入点,通过执行非法的SQL语句或字符串达到入侵者想要的操作。下面以一段身份验证的.NET代码为例,说明一下SQL注入攻击的实现方法。SqlConnectionnwConn=newSqlConnection((string)ConfigurationSettings.AppSettings[DBconnStrings]);stringqueryStr=SELECTuserid,userpwd,username,typeFROMuserswhereuserid='+Txtusername.Text+';DataSetuserSet=newDataSet();SqlDataAdapteruserAdapter=newSqlDataAdapter(queryStr,nwConn);userAdapter.Fill(userSet,Users);Session[UserID]=Txtusername.Text.ToString();Session[type]=type.Text.ToString();Response.Redirect(/Myweb/admin/login.aspx);从上面的代码中可以看出,程序在与数据库建立连接得到用户数据之后,直接将username的值通过session传给login.aspx,没有进行任何的过滤和处理措施,直接用来构造SQL语句,其危险系数是非常高的,攻击者只要根据SQL语句的编写规则就可以绕过身份验证,从而达到入侵的目的。1.2SQL注入漏洞攻击分析SQL注入可以说是一种漏洞,也可以说是一种攻击。当程序中的变量处理不当,没有对用户提交的数据类型进行校验,编写不安全的代码,构造非法的SQL语句或字符串,都可能产生这个漏洞。例如Web系统有一个login页面,这个login页面控制着用户是否有权访问,要求用户输入一个用户名和口令,连接数据库的语句为:“select*fromuserswhereusername='username'andpassword='password'”攻击者输入用户名为aaor1=1口令为1234or1=1之类的内容。我们可以看出实际上攻击者并不知道真正的用户名、口令,该内容提交给服务器之后,服务器执行攻击者构造出的SQL命令,但由于攻击者输入的内容非常特殊,所以最后得到的SQL命令变成:“select*fromuserswhereusername='aa'or1=1andpassword='1234'or1=1”;服务器执行查询或存储过程,将用户输入的身份信息和数据库users表中真实的身份信-3-息进行核对,由于SQL命令实际上已被修改,存在永远成立的1=1条件,因此已经不能真正验证用户身份,所以系统会错误地授权攻击者访问。SQL注入是通过目标服务器的80端口进行的,是正常的Web访问,防火墙不会对这种攻击发出警告或拦截。当Web服务器以普通用户的身份访问数据库时,利用SQL注入漏洞就可能进行创建、删除、修改数据库中所有数据的非法操作。而当数据库以管理用户权限的身份进行登录时,就可能控制整个数据库服务器。SQL注入的方法很多,在以手动方式进行攻击时需要构造各种各样的SQL语句,所以一般攻击者需要丰富的经验和耐心,才能绕过检测和处理,提交语句,从而获得想要的有用信息。这个过程需要花费很多的时间,如果以这种手动方式进行SQL注入漏洞攻击,许多存在SQL注入漏洞的ASP、JSP、PHP、JAVA等网站就会安全很多了,不是漏洞不存在了,而是手动入侵者需要编程基础,但现在攻击者可以利用一些现成的黑客工具来辅助SQL注入漏洞攻击,加快入侵的速度,使SQL注入变得轻而易举。由于SQL注入漏洞攻击利用的是通用的SQL语法,使得这种攻击具有广泛性。理论上说,对于所有基于SQL语言的数据库管理系统都是有效的,包括MSSQLServer、Oracle、DB2、Sybase和MySQL等。当然,各种系统自身的SQL扩展功能会有所不同,因此最终的攻击代码可能不尽相同。1.3SQL注入漏洞攻击过程(1)绕过身份验证如一个login界面,需要输入用户名和口令,然后Post到另一个页面,进行身份验证,因此攻击者只需在用户名和口令的输入框中都输入aaor’1’=’1’的内容,那么攻击者就可以通过欺骗的验证方式而直接进入下一个页面,并拥有和正常登录用户一样的全部特权。原因是什么呢?我们比较一下正常用户登录和攻击者登录时的两种SQL语句:1)正常用户(如用户名为admin,口令为1234567):SQL=selectfromuserswhereusername=’admin’andpassword=’1234567’;2)攻击者(用户名和口令都为aaor’1’=’1’):SQL=select*fromuserswhereusername='aaor’1’=’1’'andpassword='aaor’1’=’1’';可以看到由and连接的两个条件都被一个永远成立的1=1所代替,执行的结果为true,数据库会认为条件恒成立,会返回一个true,让攻击者以合法身份登录进入下一个页面。-4-(2)执行非法操作如一个查询页面select1.asp?id=1,编程人员原本设计意图是显示id为1的查询信息,而攻击者利用程序中没有对id内容进行检查的机制,插入自己的代码。从select1.asp中摘录一段关键代码:SQL=select*fromphotowherephotoid='id';可以看到,id没有进行任何的处理,直接构成SQL语句并执行,而攻击者在知道该系统数据库中表名及字段名的情况下,利用SQL语句特性(分号是将两句SQL语句分开的符号),直接向数据库Tuser表中添加记录:select1.asp?id=1;InsertintoTuser(username,password,type)values('hack','1234567','管理员'),然后攻击者就可以直接用hack进行登录了。通过这样的方法,攻击者还可以对系统做任何的事情,包括添加、删除、修改系统资源的操作。(3)执行系统命令如果Web主机使用MSSQL数据库管理系统,那么攻击者就可以用到xp_cmdshell这个扩展存储过程,xp_cmdshell是一个非常有用的扩展存储过程,用于执行系统命令,比如dir、net等,攻击者可以根据程序的不同,提交不同的语句:execmaster.dbo.xp_cmdshelldir;execmaster.dbo.xp_cmdshellnetuserhack1234567/add;execmaster.dbo.xp_cmdshellnetlocalgroupadministratorshack/add;这样就可以向Web主机系统中成功添加了一个管理员帐户。2.SQL注入漏洞攻击的检测方式及方法2.1检测方式SQL注入漏洞攻击检测分为入侵前的检测和入侵后的检测。入侵前的检测,可以通过手工方式,也可以使用SQL注入漏洞扫描工具软件。检测的目的是为预防SQL注入漏洞攻击,而对于SQL注入漏洞攻击后的检测,主要是针对审计日志的查看,SQL注入漏洞攻击成功后,会在WebService和数据库的审计日志中留下“痕迹”。2.2检测方法(1)动态SQL检查动态的SQL语句是一个进行数据库查询的强大的工具,但把它和用户输入混合在一起就使SQL注入成为了可能。将动态的SQL语句替换成预编译的SQL或者存储过程对大多数应用程序是可行的。预编译的SQL或者存储过程可以将用户的输入作为参数而不是命令来执行,-5-这样就限制了入侵者的行动。当然,它不适用于存储过程中利用用户输入来生成SQL命令的情况。在这种情况下,用户输入的SQL命令仍可能得到执行,数据库仍然存在SQL注入漏洞攻击的危险。(2)有效性校验如果一个输入框只可能包括数字,那么要通过验证确保用户输入的都是数字。如果可以接受字母,检查是不是存在不可接受的字符,那就需要设置字符串检查功能。确保应用程序要检查以下字符:分号、等号、破折号、括号以及SQL关键字。(3)数据表检查使用SQL注入漏洞攻击工具软件进行SQL注入漏洞攻击后,都会在数据库中生成一些临时表。通过查看数据库中最近新建的表的结构和内容,可以判断是否曾经发生过SQL注入漏洞攻击。(4)审计日志检查在Web服务器中如果启用了审计日志功能,则WebService审计日志会记录访问者的IP地址、访问时间、访问文件等信息,SQL注入漏洞攻击往往会大量访问某一个页面文件(存在SQL注入点的动态网页),审计日志文件会急剧增加,通过查看审计日志文件的大小以及审计日志文件中的内容,可以判断是否发生过SQL注入漏洞攻击事件;另外还可以通过查看数据库审计日志,查询某个时间段是否有非法的插入、修改、删除操作。(5)其他SQL注入漏洞攻击成功后,入侵者往往会添加特权用户(如:administrator、root、sa等)、开放非法的远程服务以及安装木马后门程序等,可以通过查看用户帐户列表、远程服务开启情况、系统最近日期产生的一些文件等信息来判断是否发生过入侵。3.SQL注入漏洞攻击检测防范模型及措施3.1防范模型本人通过深入的学习研究,吸取前人的经验成果,提出了一种通用的SQL注入漏洞攻击检测防范模型如图1所示,本模型中所有检测均在服务器端进行。首先是校验客户端提交数据的有效性,自动识别该数据类型是否符合程序中设定的值,如果校验未通过将禁止访问,返回重新输入数据并记录该过程;其次将输入的字符串类型与SQL注入规则库字符串类型进行比对,检测字符串类型是否合法(验证是否存在SQL注入漏洞),若不合法也将禁止访问,返回重新输入数据并记录该操作;最后检测是否超过访问权限,如果未超过访问权限,就可以正常访问页面,若超过访问权限,除禁止访问,返回重新输