首页 | 源码下载 | 网站模板 | 网页特效 | 广告代码 | 网页素材 | 字体下载 | 书库 | 站长工具
会员投稿 投稿指南 RSS订阅
当前位置:主页>网络编程>SQL server>资讯:SQLServer应用程序中的高级SQL注入

SQLServer应用程序中的高级SQL注入

www.jz123.cn  2008-09-09   来源:   中国建站    袁袁整理    我要投递新闻


本质上,如果一个有参数的查询被执行,并且用户提供的参数通过安全检查才放入到查询中,那么SQL注入明显是不可能发生的。但是如果攻击者努力影响所执行查询语句的非数据部分,这样他们就可能能够控制数据库。
比较好的常规的标准是:
?如果一个ASP脚本能够产生一个被提交的SQL查询字符串,即使它使用了存储过程也是能够引起SQL注入的弱点。
?如果一个ASP脚本使用一个过程对象限制参数的往存储过程中分配(例如ADO的用于参数收集的command对象),那么通过这个对象的执行,它一般是安全的。
明显地,既然新的攻击技术始终地被发现,好的惯例仍然是验证用户所有的输入。

为了阐明存储过程的查询注入,执行以下语句:
sp_who''1''select*fromsysobjects
or
sp_who''1'';select*fromsysobjects
任何一种方法,在存储过程后,追加的查询依然会执行。

[高级SQL注入]
通常情况下,一个web应用程序将会过滤单引号(或其他符号),或者限定用户提交的数据的长度。
在这部分,我们讨论一些能帮助攻击者饶过那些明显防范SQL注入,躲避被记录的技术。

[没有单引号的字符串]
有时候开发人员会通过过滤所有的单引号来保护应用程序,他们可能使用VBScript中的replace函数或类似:
functionescape(input)
input=replace(input,"''","''''")
escape=input
endfunction
无可否认地这防止了我们所有例子的攻击,再除去'';''符号也可以帮很多忙。但是在一个大型的应用程序中,好象个别值期望用户输入的是数字。这些值没有被限定,因此为攻击者提供了一个SQL注入的弱点。
如果攻击者想不使用单引号产生一个字符串值,他可以使用char函数,例如:
insertintousersvalues(666,
char(0x63)+char(0x68)+char(0x72)+char90x69)+char(0x73),char(0x63)+char(0x68)+char(0x72)+char90x69)+char(0x73),
0xffff)
这就是一个能够往表中插入字符串的不包含单引号的查询。
淡然,如果攻击者不介意使用一个数字用户名和密码,下面的语句也同样会起作用:
insertintousersvalues(667,
123,
123,
oxffff)
SQLSERVER自动地将整型转化为varchar型的值。

[Second-OrderSQLInjection]
即使应用程序总是过滤单引号,攻击者依然能够注入SQL同样通过应用程序使数据库中的数据重复使用。
例如,攻击者可能利用下面的信息在应用程序中注册:
Username:admin''—
Password:password
应用程序正确过滤了单引号,返回了一个类似这样的insert语句:
insertintousersvalues(123,''admin''''—'',''password'',0xffff)
我们假设应用程序允许用户修改自己的密码。这个ASP脚本程序首先保证用户设置新密码前拥有正确的旧密码。代码如下:
username=escape(Request.form("username"));
oldpassword=escape(Request.form("oldpassword"));
newpassword=escape(Request.form("newpassword"));
varrso=Server.CreateObject("ADODB.Recordset");
varsql="select*fromuserswhereusername=''"+username+"''andpassword=''"+oldpassword+"''";
rso.open(sql,cn);
if(rso.EOF)
{

设置新密码的代码如下:
sql="updateuserssetpassword=''"+newpassword+"''whereusername=''"+rso("username")+"''"
rso("username")为登陆查询中返回的用户名
当username为admin''—时,查询语句为:
updateuserssetpassword=''password''whereusername=''admin''—''
这样攻击者可以通过注册一个admin''—的用户来根据自己的想法来设置admin的密码。
这是一个非常严重的问题,目前在大型的应用程序中试图去过滤数据。最好的解决方法是拒绝非法输入,这胜于简单地努力去修改它。这有时会导致一个问题,非法的字符在那里是必要的,例如在用户名中包含''符号,例如
O''Brien
从一个安全的观点来看,最好的解答是但引号不允许存在是一个简单的事实。如果这是无法接受的话,他们仍然要被过滤;在这种情况下,保证所有进入SQL查询的数据都是正确的是最好的方法。
如果攻击者不使用任何应用程序莫名其妙地往系统中插入数据,这种方式的攻击也是可能的。应用程序可能有email接口,或者可能在数据库中可以存储错误日志,这样攻击者可以努力控制它。验证所有数据,包括数据库中已经存在的数据始终是个好的方法。确认函数将被简单地调用,例如:
if(notisValid("email",request.querystring("email")))then
response.end
或者类似的方法。

[长度限制]
为了给攻击者更多的困难,有时输入数据的长度是被限制的。当这个阻碍了攻击时,一个小的SQL可以造成很严重的危害。例如:
Username:'';shutdown—
这样只用12个输入字符就将停止SQLSERVER实例。另一个例子是:
droptable<tablename>
如果限定长度是在过滤字符串后应用将会引发另一个问题。假设用户名被限定16个字符,密码也被限定16个字符,那么下面的用户名和密码结合将会执行上面提到的shutdown命令:
Username:aaaaaaaaaaaaaaa''
Password:'';shutdown—
原因是应用程序尝试去过滤用户名最后的单引号,但是字符串被切断成16个字符,删除了过滤后的一个单引号。这样的结果就是如果密码字段以单引号开始,它可以包含一些SQL语句。既然这样查询看上去是:
select*fromuserswhereusername=''aaaaaaaaaaaaaaa''''andpassword='''''';shutdown—
实际上,查询中的用户名已经变为:
aaaaaaaaaaaaaaa''andpassword=''
因此最后的SQL语句会被执行。

[审计]
SQLSERVER包含了丰富的允许记录数据库中的各种事件的审计接口,它包含在sp_traceXXX类的函数中。特别有意思的是能够记录所有SQL语句,然后在服务器上执行的T-SQL的事件。如果这种审计是被激活的,我们讨论的所有注入的SQL查询都将被记录在数据库中,一个熟练的数据库管理员将能够知道发生了什么事。不幸地,如果攻击者追加以下字符串:

上一篇:sql标签嵌套调用实现循环显示栏目文章标签 下一篇:MYSQL使用简述

评论总数:2 [ 查看全部 ] 网友评论