【摘要】 SQL Injection 是当前网站安全的主要问题之一。首先阐述了 SQL Injection 网络攻击的基本原理,然后对黑客利用 SQL Injection 技术攻击的一般过程进行了分析。在此基础上针对 SQL Injection 攻击的具体预防措施进行了详细的分析和研究,并且提出了现有防范技术所存在的一些问题及其解决方法。碧森尤信
1 引 言
SQL Injection攻击具有很大的危害,攻击者可以利用它读取、修改或者删除数据库内的数据,获取数据库中的用户名和密码等敏感信息,甚至可以获得数据库管理员的权限。如果能够再利用SQLServer扩展存储过程和自定义扩展存储过程来执行一些系统命令,攻击者还可以获得该系统的控制权。而且,SQL Injection 也很难防范。网站管理员无法通过安装系统补丁或者进行简单的安全配置进行自我保护,一般的防火墙也无法拦截 SQL Injection 攻击。
在目前国内的动态网站中,使用 ASP 和 Access 或 SQLServer的占 70%以上, PHP和MySQL占 20%,其它的不足 10%。
本文将主要分析在 ASP 和 SQL Server 环境下的 SQL Injection攻击及其防范方法,但多数内容同样适合于其它的动态网站环境,希望能对安全工作者和网站开发程序员构建安全的动态网站有一定的借鉴作用。
2 SQL Injection 原理
结构化查询语言(SQL)是一种用来和数据库交互的文本语言。SQL Injection 就是利用某些数据库的外部接口把用户数据插入到实际的数据库操作语言(SQL)当中,从而达到入侵数据库乃至操作系统的目的。它的产生主要是由于程序对用户输入的数据没有进行严格的过滤,导致非法数据库查询语句的执行。
下面将以一个 ASP 登陆页面为例来说明 SQL Injection 的攻击,该页面接收用户输入的用户名和口令,并以此生成一个SQL 查询语句访问数据库。如果该查询成功,将返回一条用户记录,用户登录成功。其中生成查询串的语句如下:
var sql =“select * from users where username=‘”+ username+“‘and password=’”+ password +“‘”;
如果攻击者在登录页面中指定了下面这样的输入数据:
Username: 'or 1=1--
Password:aaa
那么,查询字符串就变为:
select * from users where username=''or 1=1-- and password='aaa'
显然上面查询语句将返回表中所有用户记录,攻击者将以表中第 1 个用户的身份登录。
从上面的例子我们可以知道,SQL Injection就是利用用户提交的数据,把我们想要的SQL语句插入到系统实际的SQL语句当中,从而收集程序及服务器的信息,获取想要得到的资料。
3 SQL Injection 常用方法与技巧
下面简要介绍一下攻击者在运用 SQL Injection 时常用的方法和技巧。
3.1 判断程序运行环境及注入点
传统的注入判断方法是把“’“号添加到提交请求的末尾,然后根据服务器返回的提示信息来判断数据库的类型和是否存在注入漏洞信息。但是部分对 SQL 注入有了解的程序员,会把单引号过滤,在这种情况下使用单引号测试,是测不到注入点的。
经典的注入判断方法是 1=1、1=2 测试法。就是把“ and 1=1”和“and 1=2”插入到提交请求的 URL 的末尾,如果前者正常显示,后者出错,则存在注入漏洞;如果都报错,则不存在漏洞。例如:
A、http://www.xxx.com/show.asp?id=49 and 1=1
B、http://www.xxx.com/show.asp?id=49 and 1=2
如 A 正常显示 B 报错,为可以注入,否则不可以注入。当然,实际应用的时候可能还需要和“’”、“)”等符号进行一些灵活的组合。
3.2 猜测表名和列名
(1)参数类型
在猜测表名和列名之前,首先要确定查询语句中的参数类型。参数类型主要有下面 3 种:①数值参数,形如 Select*from 表名 where 字段=ID;②字符串参数,形如 Select*from 表名 where 字段=’关键字’;③模糊参数,形如 Select*from 表名 where 字段 like’%关键字%’。
(2)注入形式
对于这 3 种不同的参数类型,在注入时应选择不同的注入形式。对于数值参数,使用“IDand 查询条件”进行注入,如:Select*from 表名 where 字段=IDand 查询条件;对于字符串参数,使用“关键字’and 查询条件”进行注入,如:Select*from 表名where字段=’关键字’and查询条件;对于数值参数,使用“关键字%’and 查询条件”进行注入,如:Select*from表名 where 字段 like’%关键字%’and 查询条件。
根据参数的不同,需要选择相应的注入形式进行攻击,比如对数值型参数,我们可以使用下面的语句猜解表名:
select * from 表名 where ID=49 And(Select Count(*)from Admin)>=0
如果返回的页面与原页面相同,说明附加条件成立,即表示 Admin 存在,反之,即不存在。如此循环,直至猜到表名为止。表名猜解出来后,将 Count(*)替换成 Count(字段名),再用同样的原理猜解字段名。
3.3 获得字段值
在得到数据库的表名和列后,可以使用 ASCII 逐字解码法得到字段值。
例如,已知表 Admin 中存在 username 字段,首先,我们取第 1 条记录,测试长度:http://www.xxx.com/show.aspid=49and(select top1len (username)from Admin)>0 如果top1的username长度大于0,则条件成立;接着>1、>2…… >n 继续测试,一直到条件不成立为止。此时的 n 值即第1 条记录的 username 的长度。比如当>7 成立,>8不成立,就是len(username)=8。
然后,用 and(select top1 asc(mid(username, 1,1))from users)>n 来测试 users 表中第 1 个用户的 username 的第 1 个字符。注意:一般是 48-122,48 是数字 0,122 是 z。然后 asc(mid(username,n,1))继续下去,就可以得到用户名。其它字段的解码同理。
3.4 进一步攻击
除了可以对数据库的数据进行上述操作外,SQL 注入还可以结合系统存储过程,来执行一些系统命令进行SQL Injection 攻击,如:利用 xp_cmdshell 扩展存储以 SQL Server 用户的身份在数据库服务器上执行命令;利用xp_regread扩展存储读取注册表的键值,也包括SAM(只要SQLServer是以一个本地账号运行的);用其它的扩展存储改变服务器设置;在联合服务器上执行查询;创建客户扩展存储从而在 SQL Server 进程内运行 exploit;用'bulk insert'语句去读服务器上任何文件;用bcp 在服务器上创建任何文本文件。
4 SQL Injection 的防范
从上述讨论的 SQL Injection 的原理和攻击方法可以看出SQL Injection 攻击的一般特性。由此可以总结出针对 SQL Injection 防范的一般方法,这里主要介绍输入验证和数据库安全策略。
4.1 输入验证
由于 SQL Injection 就是利用某些数据库的外部接口,把攻击者想要执行的 SQL 语句插入到系统实际的 SQL 语句当中,从而达到入侵数据库乃至操作系统的目的。它的产生主要是由于程序对用户输入的数据没有进行细致的过滤,导致非法数据库查询语句的执行,所以首先要对用户提交或者可能由用户提交的数据进行输入验证。
输入验证是一个很复杂的问题。输入验证的途径可以分为以下几种:整理数据使之变得有效;拒绝已知的非法输入;只接受已知的合法的输入。
解决方案 1 有很多概念上的问题。首先,开发者没有必要知道也未必完全了解非法数据由什么组成,因为新形式的非法数据随时都可能产生。第 2,改变数据会改变它的长度,这样会导致前面提到的问题,也就是可能产生新的非法数据。最后,还有需要对系统已有数据的重用的二次注入的问题。
解决方案 2 也会遇到和 1 的一些相似的问题,因为新的攻击技术也在不断发展,所依据的现有非法数据会过时。
解决方案3可能是3种方法中最好的,但是比较难于实现。
从安全角度来考虑,可能最好的解决方法是把解决方案2 和 3 结合起来——只允许合法地输入,然后再寻找过滤非法字符。但是这样也会面临的一个问题,就是会存在一些可能被非法数据利用的合法字符和符号。例如:带有连字符的名字的问题,Question Bassington-Bassington我们必须在合法输入里允许连字符号,但字符串'--'在 SQL-Server 里却有着其它的意义。如果数据整理结合了非法字符验证时就可能产生另外的问题导致 SQL Injection。假设我们应用“非法字符探测器”来探测‘--’、‘select’和‘union’后使用“数据整理过滤器”删除单引号,攻击者就可以指定这样的输入:uni'on sel'ect@@version-'-,经过过滤和整理后,因为单引号被过滤器删除了,最后提交的数据变为:union select@@version--,则可以导致非法SQL 查询语句执行,以致信息泄漏。也就是说攻击者可以把单引号散布于它的已知的非法字符串里来躲避检查。
所以如果想要获得最好的安全状态,目前最好的解决办法就是对用户提交或者可能改变的数据进行简单分类,分别应用正则表达式来对用户提供的输入数据进行严格的检测和验证。
第 1 类:只是简单的字符和数字组合。这也是应用最广泛的提交数据,进行验证也很简单,应用如下的正则表达式就可以进行验证:
[^\w+$]
第 2 类:需要包含一些符号在内的组合,例如 EMAIL、密码等。对这些复杂的情况我们要分别对待。已知输入格式的,就构造该格式的正则表达式进行严格过滤;未知输入格式的,首先匹配其中的分隔符:[空格]、[/*]、[*/]、[[] 、[]] 等,然后再对其中的攻击特征字进行匹配。
总结集合目前已知的 SQL Injection 攻击方法,可以得出目前的攻击中所用到的符号集合作为非法符号集合,通过正则表达式予以过滤并返回错误。
已知字符和合法符号:a-z、A-Z 、@、- _.
已知非法符号:“’”、“;”、“=”、“(”、“)”、“/*”、“*/”、“%”、“+”、“”、“>”、“<”、“--”、“[”、“]”;
其实只需要过滤非法的符号组合就可以阻止已知形式的攻击,并且如果发现更新的攻击符号组合,也可以将这些符号组合增添进来,继续防范新的攻击。特别是空格符号和与其产生相同作用的分隔关键字的符号,例如“/**/”,如果能成功过滤这种符号那么很多注入攻击将不能发生,并且同时也要过滤它们的十六进制表示 “%XX”。
则可以构造如下正则表达式:
(|\'|(\%27)|\;|(\%3b)|\=|(\%3d)|\(|(\%28)|\)|(\%29)|(\/*)|(\%2f%2a)|(\*/)|(\%2a%2f)|\+| (\%2b)|\<|(\%3c)|\>|(\%3e)|\(--))|\[|\%5b|\]|\%5d)
根据上述的正则表达式,最后可以提供两个函数,代替ASP中的Request函数,可以防范大多数的SQL注入,函数如下:
Function SafeRequest(ParaName,ParaType)
'---传入参数---
'ParaName:参数名称-字符型
'ParaType: 参数类型-数字型(1 表示以上参数是数字或字符,0 表示以上参数为其它)
Dim ParaValue
Dim re As RegExp
Set re = New RegExp
If ParaType = 1then
re.Pattern =“[^\w+$]”
Else
re.Pattern =“(|\'|(\%27)|\;|(\%3b)|\=|(\%3d)|\(|(\%28)|\)|(\%29)|(\/*)|(\%2f%2a)|(\ */)|(\%2a%2f)|\+|(\%2b)|\<|(\%3c)|\>|(\%3e)|\(--))|\[|\%5b|\]|\%5d)”
End If
ParaValue=Request(Para)
If re.test(ParaValue)? then
Response.write "参数不符合要求,请重新输入!"
Response.end
SafeRequest=ParaValue
End function
并且,如果有新的 SQL Injection 方法出现,只需要把新方法的特征字符添加进 Pattern 中就可以继续防止新的 SQL Injection 了。但是对一些特定的复杂的输入就要用专门的正则表达式进行过滤。
虽然我们可以通过输入验证来组织绝大多数的 SQL Injection攻击,但是难保WEBc程序员在开发中还是会忽略一些验证,导致 SQL Injection 攻击,所以 SQL Injection 防范最重要的一点是必须防范SQLServer,完全依靠外部的防范并不能保证服务器绝对安全。
4.2 安全策略检测
但有些时候,由于Web程序员的疏忽,或者攻击者躲避了检测,导致 SQL Injection 攻击。所以要降低 SQL Injection 对SQL Server 的威胁,还是要对 SQL Server 进行基本的安全策略检测。
以下是一些构建 SQLServer 服务器时需要的注意事项简明清单。
(1)决定连接到服务器的方法:使用“Network utility”检验你使用的网络库是可用的。
(2)检查存在的账号:为程序创建低权限账号;删除不需要的账号;确保所有的账号都有一个健壮的密码。
(3)检查哪些对象存在:许多扩展存储可以安全地删除,并考虑删除一些包含扩展存储的dll;删除所有的数据库实例——比如'northwind'和'pubs'数据库。
(4)检查哪些账号可以访问对象:应用程序用户所使用的访问数据库的账号应该只拥有对所需要的对象的最小访问权限。
(5)检查服务器的补丁状况:安装一些针对 SQL Server 的缓冲区溢出与格式字符串攻击和一些其它的安全补丁,并及时去查看是否还有更新的补丁。
(6) 检验日志记录,明确日志记录的意义:通过以上的检测,基本上可以了解我们的 SQLServer 的安全状况,并且可以把逃脱输入验证的 SQL Injection 造成的威胁降到最低。
5 结论
随着网络的普及和飞速发展,网络安全问题也越来越引起人们的重视。本文从网站架设的主要脚本语言和数据库系统的安全入手,分析了 SQL Injection 的存在、危害和一些攻击方法,最后给出了防范 SQL Injection 攻击的具体方法。希望能对网站管理人员和开发人员提供一些帮助。
参考文献:
[1] Joel Scanbray,Shema Mike.Web application security secrets and Solutions[M].北京:清华大学出版社, 2003.
[2] Kevin Spett. White paper SQL injection [EB/OL]. 2002. http://www.spidynamics.com/whitepapers/WhitepaperSQL Injection.pdf .
[3] Anley Chris.Advanced SQL injection in SQL server applications[EB/OL]. 2003.http://www. nextgenss. com/papers/advanced_sql_injection.pdf.
[4] Zou Cliff C,Don Towsley,Gong Weibo.E-mail virus propagation modeling and analysis [EB/OL]. 2003.http://tennis.ecs.umass. edu/~czou/research/emailvirus-techreport.pdf.
[5] 潘志强,岑进锋.黑客攻防编程解析[M].北京:机械工业出版社, 2003.
[6] Maximum Security:A hacker's guide to protecting your internet site and network[M].Macmillan Computer Publishing, 1998.
[7] McClure Scambray S,杨洪涛.Windows 2000 黑客大曝光[M].北京:清华大学出版社, 2002.
[8] Adida Ben. Securing the Web [M]. Massachusetts Institute of Technology, IEEE Internet Computing, 1997.
[9] Richards W Tevens, Addison Wesley, 范建华, 等. TCP/IP 详解[M].北京:机械工业出版社, 2000.
[10] 蒋东兴,林鄂华.Windows Sockets网络程序设计大全[M].北京:清华大学出版社, 1999.
[11] Stanek William R.Windows 2000 脚本编程[M].北京:中国水利水电出版社, 2001.
[12] Holzner S,钟鸣,王君,等.XHTML技术内幕[M].北京:机械工业出版社, 2001.
分享到:
相关推荐
SQL Injection分析与防范.pdf
SQL Injection分析与防范研究.pdf
sql注入式 sql注入式(SQL injection)攻击与防范
SQL注入分析与防范策略 SQL注入是一种常见的网络攻击方式,通过在Web应用程序中插入恶意的SQL代码,攻击者可以获取敏感信息、篡改数据、甚至控制整个系统。随着互联网的普及,SQL注入攻击的危害性也越来越大。 一...
### PHP中的代码安全与SQL Injection防范 #### 一、初始化变量的重要性 在PHP开发中,一个常见的安全隐患就是未正确初始化变量。例如,在登录验证时,如果没有初始化`$admin`变量,就可能导致非法用户通过简单的...
SQL注入是一种常见的网络安全威胁,尤其在SQL Server...理解并防范高级SQL注入对于保护SQL Server应用程序的安全至关重要。开发人员和系统管理员需要持续关注最新的安全威胁,采取有效的防御措施,以降低被攻击的风险。
### SQL注入解析与解决方案 #### 一、SQL注入概述 SQL注入是一种常见的Web应用程序安全漏洞,攻击者通过向Web应用程序的输入字段注入恶意SQL代码,从而控制或操纵数据库的行为。这种攻击方式通常发生在应用程序未...
SQL Injection(SQL注入)是一种常见的网络安全威胁,主要针对基于SQL(结构化查询语言)的数据库系统。攻击者通过在Web应用程序的输入字段中插入恶意SQL代码,来操控后台数据库,获取敏感信息,甚至完全控制数据库...
SQL注入(SQL Injection)是Web应用程序安全领域中最常见的漏洞之一,它允许攻击者通过恶意输入在数据库查询中插入或拼接额外的SQL语句,从而操纵数据库执行非预期的操作。本文将基于提供的SQL注入技巧表,深入探讨...
### PHP中的代码安全与SQL Injection防范 #### 一、引言 在当今互联网时代,网站安全变得尤为重要。作为Web开发人员,确保应用的安全性是基本职责之一。其中,防止SQL注入攻击是保护用户数据安全的重要手段。本文...
SQL注入(SQL Injection)是一种常见的网络攻击手段,攻击者通过在Web表单输入或通过修改浏览器URL中的参数,在目标网站的数据库中执行恶意的SQL语句。这类攻击可以用来绕过认证、检索数据库信息、控制数据等,进而...
在这个毕业设计项目中,我们使用了VS2008作为开发环境,结合C#编程语言和SQL Server 2000数据库系统,构建了一个具有防范SQL注入攻击功能的应用。 首先,理解SQL注入攻击的原理至关重要。当用户输入的数据未经适当...
### PHP中的代码安全和SQL Injection防范 #### 一、引言 随着互联网技术的发展与普及,网站和应用程序的安全性越来越受到人们的重视。其中,PHP作为一种广泛使用的服务器端脚本语言,其安全性尤其重要。本文将从PHP...
防范SQL Injection的方法包括: - 参数化查询:使用参数化SQL语句,确保用户输入不会影响查询结构。 - 输入验证:对用户输入进行严格的检查,限制允许的字符和格式。 - 最小权限原则:数据库连接应使用只有执行...
SQL注入(SQL Injection)是一种常见的网络安全漏洞,主要发生在基于结构化查询语言(SQL)的数据库管理系统中。这种攻击方式允许攻击者通过输入恶意的SQL代码,来操纵或获取数据库中的敏感信息,甚至对数据库系统...
### SQL注入攻击与防御知识点详解 #### 一、SQL注入攻击概述 **SQL注入(SQL Injection,简称SQLi)**是一种常见的网络安全攻击方式,通过在应用程序接收的数据中插入恶意SQL语句来操纵后端数据库系统执行非授权...
SQL Injection是一种常见的网络安全威胁,它主要针对使用SQL(结构化查询语言)的数据库系统。攻击者通过在输入字段中插入恶意的SQL代码,利用应用程序的漏洞来操纵数据库,获取、修改、删除敏感数据,甚至完全控制...