转载

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

ModNar@0keeTeam

起因&漏洞点

在看ImageMagick影响DZ这条线,排查上传点时发现的有问题逻辑

简单说就是:

1.正则并没对content参数包含的url部分内容做限制,

2.DZ图片后缀检查函数可用aaa.php#b.jpg绕过

3.DZ图片内容检查函数限制了非图片文件请求的SSRF利用后的回显

Discuz X系列门户文章功能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这个函数的算法是否可预测

function check_articleperm(          if($_G['group']['allowmanagearticle'] || (empty($aid) && $_G['group']['allowpostarticle']) || $_GET['modarticlekey'] == modauthkey($aid)) {                    return true;          }

source/function/function_core.php

//生成算法里有个authkey,值是Discuz安装时随机生成的

//于是换个思路去看,是否有调用此函数且泄露到页面里的逻辑

function modauthkey($id) {          return md5(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.1 301 Moved Permanently"); 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

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

第一步

登陆后,请求获取modauthkey算出的一个key,用于操作对应文章:

http://a.cn/discuz_x3.2_sc_gbk/upload/forum.php?mod=redirect&goto=findpost&modthreadkey=1&ptid=1&pid=1

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

从跳转的链接取出modthreadkey的参数值:

http://a.cn/discuz_x3.2_sc_gbk/upload/forum.php?mod=viewthread&tid=1&page=1&modthreadkey=fce8163c9f310147f91a244a9eb9dc33#pid1

第二步

带上当前formhash,modarticlekey拼上第一步的modthreadkey的值,即可发请求:

aa=a

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

图片被下载并上传到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

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

线上站点示例

Baidu:

site:qq.com inurl:"portal.php?mod=view&aid="

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

远程nc监听:

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

修复方案

临时修复方案

source/include/portalcp/portalcp_upload.php:

对应修改或新增代码:

function filter_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_ipList as $startIp=>$endIp){                             $startLong = ip2long($startIp);                             $endLong = ip2long($endIp);                             if ($iplong >= $startLong && $iplong <= $endLong){                                      echo "filtered";                                      return false;                             }                    }                    return true;          }          else return false; } $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:

Discuz X系列门户文章功能SSRF漏洞挖掘与分析

总结

1.此漏洞的利用需要一定的前提,即论坛管理者在论坛门户发表过文章,具体可用以下方法探测:

http://home.qihoo.net/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

原文  http://bobao.360.cn/learning/detail/2889.html
正文到此结束
Loading...