手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>网站运营>建站经验>列表

SQL盲注攻击技术综述

来源:互联网 作者:west263.com 时间:2008-04-16
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!

/mysite/proddetails.asp?ProdName=Book
要测试该ProdName参数是否有注入漏洞,能够先其替换成一个无效的字符串比如Book’,然后再替换成一
个可能生成正确字符串的表达式,比如B’ ’ook(对于Oracle,是B’||’ook)。这就会形成以下两个SQL请求
语句:
(1) SELECT * FROM Products WHERE ProdName = 'Book''
(2) SELECT * FROM Products WHERE ProdID = 'B' 'ook'
则第一个仍然可能产生一个SQL错误,而第二个则可能返回和最初的请求相同的值为Book的产品。
我们注意到,即使应用程式已过滤了’和 等META字符,我们仍然能够在输入时过把字符转换成URL
编码(即字符ASCII码的16进制)来绕过检查,例如:
/mysite/proddetails.asp?ProdID=3 1就等于/mysite/proddetails.asp?ProdID=3+1
/mysite/proddetails.asp?ProdID=B’ ’ook就等于/mysite/proddetails.asp?ProdID=B'+'ook
类似的,任何表达式都能够用来替换最初的参数。而特别的系统函数也能够被用来提交以返回一个数字,
一个字符串或一个日期,比如Oracle中sysdate返回一个日期表达式,而在SQL Server中,getdate()会返回日
期表达式。其他的技术同样能够被用来判断是否存在SQL注入漏洞。
通过以上介绍能够发现,即使没有周详的错误信息,对于攻击者来说,判断是否存在SQL注入漏洞仍然
是个很简单的任务。

3 实施注入攻击
攻击者在确定注入点后,就要尝试进行注入利用,这需要其能确定符合SQL语法的注入请求表达式,判
断出后台数据库的类型,然后构造出所需的利用代码。

3.1 确定正确的注入句法
这是SQL盲注攻击中最难也最有技巧的步骤,假如最初的SQL请求语句很简单,那么确定正确的注入
语法也相对容易,而假如最初的SQL请求语句较复杂,那么要想突破其限制就需要多次的尝试,但进行这些
尝试所需要的基本技术却是很简单。
确定基本的句法的过程即通过标准的SELECT … WHERE语句,被注入的参数(即注入点)就是WHERE
语句的一部分。为了确定正确的注入句法,攻击者必须能够在最初的WHERE语句后添加其他数据,使其能
返回非预期的结果。对一些简单的应用程式,仅仅加上OR 1=1就能够完成,但在大多数情况下假如想构造
出成功的利用代码,这样做当然是不够的。经常需要解决的问题是如何配对插入语符号(parenthesis,比如
成对的括号),使之能和前面的已使用的符号,比如左括号匹配。另外常见的问题是个被篡改的请求语句可
能会导致应用程式产生其他错误,这个错误往往难于和一个SQL错误相区分,比如应用程式一次假如只能处
理一个记录,在请求语句后添加OR 1=1可能使数据库返回1000条记录,这时就会产生错误。由于WHERE
语句本质上是一串通过OR、AND或插入语符号连接起来的值为TRUE或FALSE的表达式,因此要想确定
正确的注入句法,关键就在于能否成功地突破插入语符号限制并能顺利地结束请求语句,这就需要进行多次
组合测试。例如,添加AND 1=2能将整个表达式的值变为FALSE,而添加OR 1=2则不会对整个表达式的值
产生影响(除非操作符有优先级)。
对于一些注入利用,仅仅改变WHERE语句就足够了,但对于其他情况,比如UNION SELECT注入或
存储过程(stored procedures)注入,还需要能先顺利地结束整个SQL请求语句,然后才能添加其他攻击者所
需要的SQL语句。在这种情况下,攻击者能够选择使用SQL注释符号来结束语句,该符号是两个连续的破
折号(--),他需要SQL Server忽略其后同一行的任何输入。例如,一个登录页面需要访问者输入用户名和密
码,并将其提交给SQL请求语句:
SELECT Username, UserID, Password FROM Users WHERE Username = ‘user’ AND Password = ‘pass’
通过输入john’--作为用户名,将会构造出以下WHERE语句:
WHERE Username = ‘john’ --'AND Password = ‘pass’
这时,该语句不但符合SQL语法,而且还使用户跳过了密码认证。但是假如是另外一种WHERE语句:
WHERE (Username = ‘user’ AND Password = ‘pass’)
注意到这里出现了插入语符号,这时再使用john’--作为用户名,请求语句就会错误:
WHERE (Username = ‘john' --' AND Password = ‘pass’)
这是因为有未配对的插入语符号,请求语句就不会被执行。
这个例子显示出使用注释符号能够用来判断请求语句是否被顺利地结束了,假如添加了注释符号且没有
产生错误,这就意味着注释符号前的语句已顺利地被结束。假如出现了错误,这就需要攻击者进行更多的
请求尝试。

3.2 判断数据库类型
攻击者一旦确定了正确的注入句法后,就会开始利用注入去判断后台数据库的类型,这个步骤比确定注
入句法要简单得多。攻击者一般会使用以下几种技巧,这些技巧是基于不同类型数据库引擎在具体实现上的
差异。下面只介绍如何区分Oracle和MS SQL Server:
最简单的办法,就是前面提到的利用字符串的连结符号,在注入句法已确定的情况下,攻击者能够对
WHERE语句自由地添加额外的表达式,那么就能够利用字符串的比较来区分数据库,例如:
AND 'xxx' = 'x' 'xx' (或 AND 'xxx' = 'x' + 'xx')
通过将 替换成||,就能够判断出是数据库是Oracle还是MS SQL Server,或是其他类型。
其他的办法是利用分号字符(即;),在SQL中,分号是用来将几个SQL语句连接在同一行中。在注入
时,也能够在注入代码中使用分号,但Oracle驱动程式却不允许这样使用分号。假设在前面使用注释符号时
没有出现错误,那么在注释符号前加上分号对MS SQL Server是没有影响的,但假如是Oracle就会产生错误。
另外,还能够使用COMMIT语句来确认是否允许在分号后再执行其他语句(例如,注入语句xxx' ; COMMIT
--),假如没有出现错误就能够认为允许多句执行。
最后,表达式还能够被替换成能返回正确值的系统函数,由于不同类型的数据库使用的系统函数也是不
同的,因此也能够通过使用系统函数来确定数据库类型,比如2.3节提到的MS SQL Server的日期函数getdate()
和Oracle的sysdate.
3.3 构造注入利用代码
当任何相关的信息都已获得后,攻击者就能够开始进行注入利用,而且在构造注入利用代码过程中也不
再需要周详的错误信息,构造利用代码本身能够参考其他描述标准SQL注入攻击的文档。

文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!