http://www.blogjava.net/ebecket 返还网
随笔-140  评论-11  文章-131  trackbacks-0
来自 千一网络

看了小竹的《SQL注入天书之ASP注入漏洞全接触》,感觉这篇文章写得非常好,由浅入深,实例详尽,对新手起到教学作用,对老手起到交流探讨作用,目前近40%的ASP网页均存在此漏洞,可以说《SQL注入天书之ASP注入漏洞全接触》也来得非常实用。

我是从其它网站上拷贝到“千一网络”的,我对其中的个别部分进行了修改,我想可能是别人在拷贝这篇文章时把其中的某些部分弄错了,在此向作者说明,其中修改的部分是去掉部分sql语句中的";"号,如:
  http://www.mytest.com/showdetail.asp?id=49 ;and (select count(*) from sysobjects)>0
  修改为:
http://www.mytest.com/showdetail.asp?id=49 and (select count(*) from sysobjects)>0

SQL Server注入漏洞可能造成什么损失呢?
  
轻:查看数据库名、SQL Server连接名、得到表的字段与记录等。
  重:备份数据库、下载数据库、在计算机内添加管理员等。

“查看数据库名、SQL Server连接名、得到表的字段与记录”之类的攻击,对于存在注入漏洞的网页一般都可实现。但若是使用Web管理网站,Web的密码又没加密,这样事态就变严重了。另外对于SELECT语句,如果没有控制好LockType(应设置为adLockReadOnly),也是很严重的。

对于ASP+SQL Server如何彻底防范注入漏洞:
  一、对进入sql语句的数字先进行类型转换
  二、对进入sql语句的字符,将单引号("'")替换为两个单引号("''")或其它

仅此两点即可,也许有人会问,那么文中第8页所说:

在入门篇提到,有很多人喜欢用’号测试注入漏洞,所以也有很多人用过滤’号的方法来“防止”注入漏洞,这也许能挡住一些入门者的攻击,但对SQL注入比较熟悉的人,还是可以利用相关的函数,达到绕过程序限制的目的。
  是什么意思呢?既然说进行类型转换,过滤掉"'"就可以了,这里怎么又说可以绕过"'"的限制呢?其实,这里所说的是指对数字类型或我们注入添加的sql。也就是说:

对sql = "……where id=" & request.QueryString("id")
  用**.asp?id=char(50),char会起到函数的作用

或者where xtype=char(85)(见文中第8页),char也会起到函数的作用。

但对于sql = "……where key='" & request.QueryString("key") & "'"
  用**.asp?key=char(50),这里的char(50)是不起作用的,为什么呢?
  套入sql一看,语句是这样的:
  sql = "……where key='char(50)'"
  char(50)位于"'"内,变成了字符(串),所以就起不到函数的作用了。

养成好的习惯,制定统一的规范
  
上面的方法确实解决了注入漏洞问题,但并不表示其它地方可以马虎了,为什么要马虎了,为什么要让自己的网页千疮百孔,让几句代码去独挡一面呢?如果不养成好的习惯,团体之间如果不制定统一的规范,今天这个问题解决了,明天那个问题还会出现。

1、使用RecordSet记录集之前必须判断RecordSet的BOF或EOF属性。
  2、对于SELECT语句,除了不得已的情况,LockType必须设置为adLockReadOnly。
  3、放入数据库中的密码应该使用良好的加密算法进行加密,同时也禁止密码以明文的形式存在于页面文件中。
  4、在Web条件下,在非本机调试的情况下,不得使用sa连接数据库。
  5、对于需要用户权限的平台,必须将用户名和密码载入session,然后在需要的页面进行判断,不得使用if session("loginOK")<>"" then之类的语句来判断用户是否是合法用户。
  ……
  必要时,可以禁止IIS返回详细的出错信息,可以禁止public对sysobjects表的SELECT权限。
  ……

安全不是一方面的,仅靠几个规范几个好的习惯并不能保证能造就出安全的空间,1个False与99个True进行“与”运算,结果还是False,从中可以看出,哪怕只有一点错误,都可能导致结果全盘被否定。Web安全,除了注入漏洞,还有FTP设置错误、Web服务设置错误、后台程序漏洞这些最最基本的都可能导致服务器整个被人控制,所以处处都要三思啊。


再次说明防注入不是替换关键字!

最近又看到很多关于 SQL 注入的帖子,都是使用替换 select、delete、update 等字符串的方法来防注入的。

再说明一下,这种是错误的防注入方法,原因如下:

  1. 可能替换不全,不是所有的关键字都列入其中了的。
  2. 本身这种替换就有漏洞,比如 aandnd 本身没有问题,把其中的 and 替换掉后,反而冒出一个 and 出来。
  3. 这种替换方式还破坏了文字的原义,我曾经在某个网站上注册了 candy 这个用户名,后来该系统却告诉我没有这个用户,后来才知道 candy 中的 and 被去掉了。

正确的防注入方法是:

  • 对数字类型进入 sql 前强制转换为数字。
  • 对文本类型进入 sql 前替换单引号为双引号。
  • 对日期类型进入 sql 前强制转换成日期,并替换单引号为双引号。

这是从注入的原理来防的。

posted on 2010-03-22 09:01 becket_zheng 阅读(221) 评论(0)  编辑  收藏 所属分类: C#网络/服务器

只有注册用户登录后才能发表评论。


网站导航: