蝶梦林许愿本漏洞浅析
日期:2008年5月9日 评论次数:No Comments » 浏览次数:
蝶梦林许愿本是目前网络上使用比较多的一个许愿版,经历了几次升级,目前最新版本为2.7。我们可以用关键字“intitle:Nothing is impossible to a willing heart! 心之所愿,无事不成!-蝶梦林许愿V2.7”来查找使用这个系统的网站。比起其他许愿系统来说,其安全性还是比较好的,但这并不代表它就没漏洞,下面就开始我们的漏洞分析之行吧。
search.asp是许愿本的搜索模块,要实现搜索功能,自然少不了数据库的查询操作,所以这里会有参数的传递及操作。按照安全的编程习惯,只要存在参数的传递就应该对其过滤,但是在这里程序员显然没有认识到它的危害,漏洞也自然暴露出来了。其代码如下:
CODE:
startTime=timer()
searchType=request.Form("searchType")
word=request.Form("word")
'取得参数word的值
startTime=timer()
function htmlEncode(str) '过滤函数
str=replace(str,chr(32)," ")
str=replace(str,chr(10),"<br />")
str=replace(str,chr(13),"<br />")
htmlEncode=str
end function
%>
<!–#include file="conn.asp"–>
<%
openDB
dim rs_wish,strsql,rs_wish_total,totalPage,splitPage,filepath
Set rs_wish=Server.CreateObject("adodb.recordset")
if(searchType="wisher") then
strsql="select * from wish where name like '%"&word&"%'ORDER BY date DESC"
'参数word没有经过任何过滤就查询了数据库
else
strsql="select * from wish where msg like '%"&word&"%'ORDER BY date DESC"
end if
rs_wish.open strsql,connWish,1,1
rs_wish_total=rs_wish.recordcount
totalPage=rs_wish.pagecount
rs_wish.PageSize = 10 '每页显示记录数
splitPage=rs_wish.PageSize
filepath="index.asp"'request.ServerVariables("PATH_INFO")
很显然,参数word没有经过过滤就进行了数据库操作。虽然有过滤函数,但可能是程序员糊涂了,并没有对word进行过滤。利用这个漏洞,我们就可以查询到管理员的密码了。在这里,程序员对搜索的长度进行了20位限制:<input name="word" type="text" id="word" maxlength="20" style="border:1px solid #7db1b5; background-color:#F6F6F6; " />,以为这样就无法攻击了,其实不然。我们可以把网页下载到本地,把maxlength长度修改到最大,比如修改为1000,然后在提交的时候,把提交地址由原来的相对地址改成绝对地址即可。根据这个查询语句的特殊性,在判断漏洞肯定存在时,我们应该将语句改成:"word+'","word+%' and 1=1 and'%","word+%' and 1=2 and'%",当搜索的条件不符合时,就会出现如图1所示的结果。
要查询管理员的密码也很简单,比如要查询表admin的第一条记录,字段username第一个字的ASCII值是否为b,那么我们就应该输入如下的查询代码:"word+%' and (select top 1 asc(mid(username,1,1)) from admin)=98 and'%",在SQL语句中就变成了select * from wish where name like '%word+%' and (select top 1 asc(mid(username,1,1)) from admin)=98 and'%%'ORDER BY date DESC。其实这里的注入也很简单,我们只要修改两个and之间的代码就可以了,和在URL中的手工注入是一模一样的。细心的朋友应该可以看到,对于这个漏洞的攻击是少不了单引号这个字符来进行数据的闭合的,所以防止这个漏洞非常的简单,只要把搜索关键字中的单引号过滤,就没有机会注入了。
在检查系统是否存在跨站漏洞时,我发现其过滤跨站攻击的函数是这样编写的。
CODE:
function HTMLEncode(str)
str=replace(str,"&","&")
str = Replace(str, ">", ">")
str = Replace(str, "<", "<")
str = Replace(str, "", " ")
str = Replace(str, """", """)
str=replace(str,"%0D",chr(10))
str=replace(str,"<br />",chr(10))
if isArray(badWord) then
dim i
for i =0 to ubound(badWord)
str = Replace(str,badWord(i), "*")
next
else
str = Replace(str,badWord, "*")
end if
HTMLEncode=str
end function
虽然这个函数可以过滤大部分跨站的攻击,但是在特定的环境下还是可以被绕过的。比如很多系统提供了自定义头像功能,此时就可以输入<img src=javascrip:alert("cmd")></img>来达到跨站效果。如果不可以用函数和字符串,还可以用<img src=javascript:alert('cmd')></img>来突破。
而上面的函数只是转换掉“<>”字符,让用户不能建立自己的HTML标记,这是远远不够的,因为攻击者可以借助系统提供的“<>”来间接达到攻击效果,所以系统自己的HTML标记也要防范。过滤JavaScript和特殊字符“&”可以阻止用户修改标记的属性为Script,最后通过“"”和空格的过滤使用户不能引发时间机制和重建其他的属性,将用户的输入限制在一个字符串内,只有这样才能从本质上把跨站漏洞杜绝。
我在上面只是简单地分析了一下蝶梦林许愿本,其搜索模块的注入漏洞还是比较严重的。程序员应该都要明白,一切漏洞的产生都是因为变量和逻辑没有考虑好而导致的,所以在写程序时要特别注意,变量一定要过滤好,而逻辑上的考虑主要是离散数学方面。只要这两方面过关了,那么系统的安全性将会大大提高。
0 Comments.