在6月份的黑防上看到《动网7.1漏洞惊现江湖》一文,说是admin_postings.asp文件
存在注入漏洞,但利用的前提是拥有超级斑竹或前台管理员权限。我想起以前发现的动网7.x版本存在一个前台权限提升漏洞,正好可以结合起来利用。这个前台权限提升漏洞对7.x的Access和Sql版都有效。下面我们就以7.0sp2sql版,讲解这个漏洞的利用。
漏洞分析
我们知道动网是通过GroupID来判断当前用户所在的组的,然后再通过组的信息判断用户的权限。它是如何取得这个GroupID的呢?让我们看看登录验证的那一段:
login.asp的525行左右
Rem==========论坛登录函数=========
Rem判断用户登录
FunctionChkUserLogin(username,password,mobile,usercookies,ctype)
…………前面的代码省略
Sql="SelectUserID,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&""
setrsUser=Dvbbs.Execute(sql)
IfrsUser.eofandrsUser.bofThen
ChkUserLogin=false
ExitFunction
Else
iMyUserInfo=rsUser.GetString(,1,"|||","","")
rsUser.Close:SetrsUser=Nothing
EndIf
iMyUserInfo="Dvbbs|||"&Now&"|||"&Now&"|||"&Dvbbs.BoardID&"|||"&
iMyUserInfo&"||||||Dvbbs"
iMyUserInfo=Split(iMyUserInfo,"|||")
Iftrim(password)<>trim(iMyUserInfo(6))Then
ChkUserLogin=false
ElseIfiMyUserInfo(17)=1Then
ChkUserLogin=false
ElseIfiMyUserInfo(19)=5Then
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)
IfArticle<0ThenArticle=0
EndIf
…………后面的代码省略
可以看到,动网将用户的信息先用”|||”三个竖线连起来,做为一个字符串传给iMyUserInfo,然后iMyUserInfo由”|||”分隔成一个字符串数组。用户密码验证正确后就把数组的第20个元素的值:iMyUserInfo(19)赋给GroupID。看到没,GroupID只是数组对应的第20个元素的值,如果iMyUserInfo(19)的值为1的话,动网就以为现在登录的用户是前台管理员了。
在inc目录下的Dv_ClsMain.asp文件中也有这么验证用户身份的一段代码,用来在用户更新信息后检测用户的权限。
Dv_ClsMain.asp的650行左右
PublicSubTrueCheckUserLogin()
……前面的省略
DimRs,SQL
Sql="SelectUserID,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]WhereUserID="&UserID
SetRs=Execute(Sql)
IfRs.EofAndRs.BofThen
Rs.Close:SetRs=Nothing
UserID=0
EmptyCookies
LetGuestSession()
Else
MyUserInfo=Rs.GetString(,1,"|||","","")
Rs.Close:SetRs=Nothing
IfIsArray(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"
EndIF
Response.WriteMyUserInfo
MyUserInfo=Split(MyUserInfo,"|||")
……
EndIf
EndSub
用户登录成功后,采用本函数读取用户数组并判断一些常用信息
PublicSubGetCacheUserInfo()
MyUserInfo=Session(CacheName&"UserID")
UserID=Clng(MyUserInfo(4))
MemberName=MyUserInfo(5)
Lastlogin=MyUserInfo(15)
IfNotIsDate(LastLogin)ThenLastLogin=Now()
UserGroupID=Cint(MyUserInfo(19))
……后面代码省略
两处检验的方式一模一样,所以我们可以利用这两个中的任意一个来达到我们的目的。看它的sql语句部分:
Sql="SelectUserID,UserName,UserPassword,UserEmail,UserPost,UserTopic,UserSex,
UserFace,UserWidth,UserHeight,JoinDate,LastLogin,UserLogins,Lockuser,Userclas
s,UserGroupID,UserGroup,userWealth,userEP,userCP,UserPower,UserBirthday,UserLa
stIP,UserDel,UserIsBest,UserHidden,UserMsg,IsChallenge,UserMobile,TitlePic,UserTit
le,TruePassWord,UserToday"
Sql=Sql+"From[Dv_User]WhereUserID="&UserID
javascript:window.open(this.src);src="/article/UploadPic/2006/8/27/200682723275512.GIF"onload="javascript:if(this.width>screen.width-500)this.style.width=screen.width-500;"align=baselineborder=0>