文章作者: 落叶纷飞 & 华夏鸡头4 [S.S.T]
信息来源:邪恶八进制信息安全团队(
www.eviloctal.com)
注意:文章首发脚本安全小组论坛(www.Cnsst.Org),后由原创作者友情提交到邪恶八进制信息安全团队,转载请注明首发站点。
PS:有些JJ老是说我发现的动网XSS就是 樱花浪子 发现的那个,晕,现在发出来算了,本来还想投稿的~~!
前一段时间,樱花浪子发现了DVBBS8.0的自定义头像跨站点,看了他的文章后令我对DVBBS8有了一些兴趣,所以就下了套来看,谁知,真的被我看出了点问题了。好了,现在我们来分析下漏洞的成因。
我们看看IndivGroup_List.asp文件的部分漏洞代码:
....省略部分代码....
Sub saveappgroup()
Dim UserID,UserName,GroupName,GroupInfo,GroupSetting,viewflag
....省略部分代码....
GroupName = Dvbbs.CheckStr(Request("GroupName"))
GroupInfo = Dvbbs.CheckStr(Request("GroupInfo"))
....省略部分代码....
If GroupName="" Then
errflag = errflag & "$圈子名称没有填写"
End if
....省略部分代码....
If errflag<>"" Then
errflag = split(errflag,"$")
Response.write "parent.information('错误:\n"
For i=1 To UBound(errflag)
Response.write "1、"&errflag(i)&"\n"
Next
Response.write "');"
Else
Set Rs=Dv_IndivGroup_MainClass.Execute("Select GroupName,AppUserName From Dv_GroupName Where AppUserName='"&UserName&"' Or GroupName='"&GroupName&"'")
If Not Rs.Eof Then
If UserName=Rs(1) Then
Response.write "parent.information('你已经申请过圈子了,一个用户只能申请一个圈子。');"
Else
Response.write "parent.information('圈子名称已经有人申请,请重新填写。');"
End If
Else
Rs.Close
If Dvbbs.forum_setting(102)=0 Then
Dv_IndivGroup_MainClass.Execute("Insert Into Dv_GroupName(GroupName,GroupInfo,AppUserID,AppUserName,UserNum,Stats,LimitUser,AppDate,PassDate,Locked,viewflag) Values('"&GroupName&"','"&GroupInfo&"','"&UserID&"','"&UserName&"',1,1,"&Dvbbs.GroupSetting(74)&","&SqlNowString&","&SqlNowString&","&GroupSetting&","&viewflag&")")
Response.write "parent.information('申请信息已经保存,请等待管理员通过');"
....省略部分代码....
看倒了么?在saveappgroup过程中Groupname和GroupInfo两个变量经过Dvbbs.CheckStr过滤之后再赋值,那么,现在我们来看看Dvbbs.CheckStr这个函数是怎么写的,代码如下:
....省略部分代码....
If Isnull(Str) Then
CheckStr = ""
Exit Function
End If
Str = Replace(Str,Chr(0),"")
CheckStr = Replace(Str,"'","''")
....省略部分代码....
大家看到了吧!这个函数只过滤了“null”、“chr(0)”和“'”,那么,我们只要绕过这几个字符来进行跨站就可以了,我们可以构造这样的测试代码“<script>alert("cnsst")</script>”。
我们再来看看admin/indivgroup.asp文件的漏洞代码:
<td width="20%" class=td1><b>圈子名称</b></td>
<td width="80%" class=td1>
<input type="text" name="Groupname" size="35" value="<%=Groupname%>">
</td>
</tr>
....省略部分代码....
<tr>
<td width="20%" class=td1><b>圈子说明</b></td>
<td width="80%" class=td1>
<textarea rows="4" cols="35" name="GroupInfo"><%=GroupInfo%></textarea>
....省略部分代码....
呵呵,Groupname和GroupInfo在出库时没有做过滤哦!再来看看indivgroup_index.asp的漏洞代码:
....省略部分代码....
Sub ShowBoardList()
Dim i,ShowMod,BoardID,LastPost,LastPostDate
Set XMLDom=Server.CreateObject("msxml2.FreeThreadedDOMDocument"& MsxmlVersion)
XMLDom.appendChild(XMLDom.createElement("IndivGroup"))
XMLDom.documentElement.appendChild(Dv_IndivGroup_MainClass.BoardXMLDom.documentElement.cloneNode(True))
XMLDom.documentElement.attributes.setNamedItem(XMLDom.createNode(2,"groupid","")).text=Dv_IndivGroup_MainClass.ID
XMLDom.documentElement.attributes.setNamedItem(XMLDom.createNode(2,"groupname","")).text=Dv_IndivGroup_MainClass.Name
XMLDom.documentElement.attributes.setNamedItem(XMLDom.createNode(2,"powerflag","")).text=Dv_IndivGroup_MainClass.PowerFlag
....省略部分代码....
呵呵,groupname没有做过滤就出库了。
好了,我们来测试下,在本地搭建一个环境,注册一个用户,然后在“个性圈子”里打开“申请圈子”,在“圈子名称”和“圈子说明”里同时输入“"><script>alert("cnsst")</script>”,然后我们进入动网后台的圈子管理里面看看,呵呵,弹出了两个框,如图1。
我们再打开这个圈子,又弹出了两个框。我在官方也成功测试了,如图2。
再来看看IndivGroup_Manage.asp的漏洞代码:
....省略部分代码....
boardinfo = Dvbbs.CheckStr(NewlineEncode(Request("boardinfo")))
....省略部分代码....
boardrules = Dvbbs.CheckStr(NewlineEncode(Request("boardrules")))
....省略部分代码....
Dv_IndivGroup_MainClass.Execute("insert into Dv_Group_Board(boardname,boardinfo,indeximg,rootid,founddate,rules,boardstats) values('"&boardname&"','"&boardinfo&"','"&indeximg&"',"&Dv_IndivGroup_MainClass.ID&",'"&now()&"','"&boardrules&"',"&boardstats&")")
Response.write "parent.document.getElementById('boardForm').innerHTML='<li>栏目增加成功。[<a href=\""javascript:history.go(-1)\"">返回</a>]'"
....省略部分代码....
大家看到了吧,boardinfo和boardrules这两个变量都分别用Dvbbs.CheckStr和NewlineEncode函数过滤了再进库,我们来看看NewlineEncode函数的代码:
....省略部分代码....
Function NewlineEnCode(Str)
If Not IsNull(Str) Then
Str = Replace(Str, CHR(13), "")
Str = Replace(Str, CHR(10), "<BR/>")
NewlineEnCode = Str
End If
....省略部分代码....
过滤了CHR(13)和CHR(10),呵呵,这很容易绕过嘛~!IndivGroup_index.asp文件在输出这两个值的时候也没有做过滤。现在我们来测试下。打开圈子管理里面的“添加栏目”,然后在“栏目说明”和“栏目规则”里分别输入跨站代码“<script>alert(1112)</script>”、“<script>alert(111)</script>”,其他的随便输入,然后点“保存”,OK我们打开圈子看看,呵呵,跨站代码执行了,如图3。

我们再打开圈子中的那个栏目,怎么样,跨站代码也成功执行了,如图4。
好了,dvbbs8.0的跨站漏洞就介绍到这里,大家如果有什么问题可以来脚本安全小组(
www.cnsst.org)或X档案的论坛来找我。