DiscuzX系列命令执行分析公开(三连弹)

0x00 漏洞概要



360补天发了这样的一条微博:

DiscuzX系列命令执行分析公开(三连弹)

下面是原漏洞报告的概要部分:

“腾讯旗下Discuz! X系列cms存在远程命令执行漏洞,经测试在其2013年6月20日发布的最新版本的Discuz! X3中仍存在此问题。目前这个漏洞尚未在网络中流传,属于0day漏洞。 这个漏洞存在于图片裁剪功能中,需要管理员启用ImageMagick上传图片功能方可触发。此漏洞只需一个可访问论坛内容的账号,即可利用。”

0x01 原理分析


0. 一定条件下前台命令执行



这个漏洞出现在\source\class\class_image.php文件中的Thumb_IM()函数,问题代码如下:

function Thumb_IM() { switch($this->param['thumbtype']) { case 'fixnone': case 1: if($this->imginfo['width'] > $this->param['thumbwidth'] || $this->imginfo['height'] > $this->param['thumbheight']) { $exec_str = $this->param['imageimpath'].'/convert -quality '.intval($this->param['thumbquality']).' -geometry '.$this->param['thumbwidth'].'x'.$this->param['thumbheight'].' '.$this->source.' '.$this->target; $return = exec($exec_str); if(!file_exists($this->target)) { return -3; } } break; //省略部分代码

从第一行红色代码中可以看出,程序通过一些变量的拼接形成一条系统命令,在第二行使用exec方法进行执行。若用户可以控制这些变量中的任何一个,那么就可能导致任意命令的执行。

1. 同点后台命令执行



这个漏洞出现在\source\class\class_image.php文件中的Thumb_IM()函数,问题代码如下:

function Thumb_IM() { switch($this->param['thumbtype']) { case 'fixnone': case 1: if($this->imginfo['width'] > $this->param['thumbwidth'] || $this->imginfo['height'] > $this->param['thumbheight']) { $exec_str = $this->param['imageimpath'].'/convert -quality '.intval($this->param['thumbquality']).' -geometry '.$this->param['thumbwidth'].'x'.$this->param['thumbheight'].' '.$this->source.' '.$this->target; $return = exec($exec_str); if(!file_exists($this->target)) { return -3; } } break; //省略部分代码

从第一行红色代码中可以看出,程序通过一些变量的拼接形成一条系统命令,在第二行使用exec方法进行执行。若用户可以控制这些变量中的任何一个,那么就可能导致任意命令的执行。

由于之前的《[email protected]! X系列远程命令执行漏洞分析(二)》报告中提到过这个问题,也已经提交给腾讯修复了,使用的利用点是param['thumbwidth']和param[' thumbheight']。而这次我使用到param['imageimpath']这个参数,这个参数对应的是后台配置中的“ImageMagick程序安装路径”。

这个利用点应该是最后一个可控点了,因为param['thumbwidth']和param[' thumbheight']在提交给腾讯后添加了整形校验转换,无法传递字符串。而source和target需要在前面进行文件和文件是否存在的验证,无法自由发挥?。

下面来看一下传递param['imageimpath']这个参数的代码,它的位置在\source\admincp\admincp_checktools.php文件中:

$settingnew = $_GET['settingnew']; if(!empty($_GET['previewthumb'])) { $_G['setting']['imagelib'] = $settingnew['imagelib']; $_G['setting']['imageimpath'] = $settingnew['imageimpath']; $_G['setting']['thumbwidth'] = $settingnew['thumbwidth']; $_G['setting']['thumbheight'] = $settingnew['thumbheight']; $_G['setting']['thumbquality'] = $settingnew['thumbquality']; require_once libfile('class/image'); @unlink(DISCUZ_ROOT.$_G['setting']['attachdir'].'./temp/watermark_temp1.jpg'); @unlink(DISCUZ_ROOT.$_G['setting']['attachdir'].'./temp/watermark_temp2.jpg'); $image = new image; //省略部分代码

可以从红色代码出看到imageimpath参数没有进行任何过滤,便传入到全局变量中了。在后面的image类中使用它也是直接从全局变量中提取,没有做任何的过滤和校验,下面是image类的构造函数代码:

function image() { global $_G; $this->param = array( 'imagelib' => $_G['setting']['imagelib'], 'imageimpath' => $_G['setting']['imageimpath'], 'thumbquality' => $_G['setting']['thumbquality'], 'watermarkstatus' => dunserialize($_G['setting']['watermarkstatus']), 'watermarkminwidth' => dunserialize($_G['setting']['watermarkminwidth']), 'watermarkminheight' => dunserialize($_G['setting']['watermarkminheight']), 'watermarktype' => $_G['setting']['watermarktype'], 'watermarktext' => $_G['setting']['watermarktext'], 'watermarktrans' => dunserialize($_G['setting']['watermarktrans']), 'watermarkquality' => dunserialize($_G['setting']['watermarkquality']), ); }

2. 前台命令执行修复绕过


在我之前的《[email protected]! X系列远程命令执行漏洞分析(二)》和《[email protected]! X系列远程命令执行漏洞分析(三)》两篇报告中,将视角盯死在了Thumb_IM这个方法上。在修复后,这个方法的命令执行失败,导致利用后续操作停止。

但是如果让这个方法正常完成它的工作,那么他后面的操作中还是有很多修复中没有考虑到的利用点。下面我们来看下其中的一个利用点,source/class/class_image.php中的Cropper_IM方法:

function Cropper_IM() { $exec_str = $this->param['imageimpath'].'/convert -quality 100 '. '-crop '.$this->param['srcwidth'].'x'.$this->param['srcheight'].'+'.$this->param['srcx'].'+'.$this->param['srcy'].' '. '-geometry '.$this->param['dstwidth'].'x'.$this->param['dstheight'].' '.$this->source.' '.$this->target; exec($exec_str); if(!file_exists($this->target)) { return -3; } }

从上面代码可以看出,这个方法先拼接命令,然后通过exec函数执行。在拼接的过程中很多变量的内容是可控的,而且在到达这个方法之前没有做足够的校验和过滤。从而导致攻击者可以通过传递一些带有命令操作的内容,来达到命令执行的目的。

0x02 利用思路


0. 一定条件下前台命令执行



看到这个漏洞点后,我就开始尝试通过关键字从源码中寻找调用Thumb_IM函数的地方。搜索到使用此函数的文件很多,但是由于这个函数的前两个参数都是和上传文件的文件名相关,而且discuz对于上传文件名做了随机化命名和后缀白名单处理,所以导致前三个参数为不可控点。

所以这之后我将目标点瞄准到图片宽度和高度这几个点,从中筛选参数未被写死的可控调用。这样我找到了\source\module\misc\misc_imgcropper.php文件,之后大量的时间花费在对于这个文件调用的业务逻辑的查找上。

1. 一定条件下前台命令执行



2. 前台命令执行修复绕过



漏洞的触发点在source/module/misc/misc_imgcropper.php中,部分代码如下:

$cropfile = md5($_GET['cutimg']).'.jpg'; $ictype = $_GET['ictype']; if($ictype == 'block') { require_once libfile('function/block'); $block = C::t('common_block')->fetch($_GET['bid']); $cropfile = block_thumbpath($block, array('picflag' => intval($_GET['picflag']), 'pic' => $_GET['cutimg'])); $cutwidth = $block['picwidth']; $cutheight = $block['picheight']; } else { $cutwidth = $_GET['cutwidth']; $cutheight = $_GET['cutheight']; } $top = intval($_GET['cuttop'] < 0 ? 0 : $_GET['cuttop']); $left = intval($_GET['cutleft'] < 0 ? 0 : $_GET['cutleft']); $picwidth = $cutwidth > $_GET['picwidth'] ? $cutwidth : $_GET['picwidth']; $picheight = $cutheight > $_GET['picheight'] ? $cutheight : $_GET['picheight']; require_once libfile('class/image'); $image = new image(); $prefix = $_GET['picflag'] == 2 ? $_G['setting']['ftp']['attachurl'] : $_G['setting']['attachurl']; if(!$image->Thumb($prefix.$_GET['cutimg'], $cropfile, $picwidth, $picheight)) { showmessage('imagepreview_errorcode_'.$image->errorcode, null, null, array('showdialog' => true, 'closetime' => true)); } $image->Cropper($image->target, $cropfile, $cutwidth, $cutheight, $left, $top); showmessage('do_success', dreferer(), array('icurl' => $cropfile), array('showdialog' => true, 'closetime' => true)); }

可以看到在最后调用了$image对象的Cropper方法,而这个过程中$cutwidth和$cutheight都是用户可控的变量,并且在执行到Cropper方法前没有进行过任何校验和过滤。

0x03 技术验证


0. 一定条件下前台命令执行



在管理员开启ImageMagick上传图片功能的前提下,攻击者只需要一个普通用户权限即可,后台设置方法如下图:

DiscuzX系列命令执行分析公开(三连弹)

由于这个功能是对图片进行处理的,所以,要在访问时提供一个本站有效的图片地址。而且最好是存放在data/attachment目录下的,因为默认就是这个目录,否则就要用“../”来修改路径。

所以我的访问路径为:

http://localhost/Discuz_X3.0/upload/misc.php?mod=imgcropper&img=group/19/group_36_banner.jpg

然后使用chrome审查元素功能,修改picwidth的value为“||whoami&”,如下图所示:

DiscuzX系列命令执行分析公开(三连弹)

然后点击网页右下角的裁剪按钮就触发了。为了能直观显示,我添加了一行代码将接受执行结果的$return变量,echo出来并exit来结束掉后面的语句,效果如下图所示:

DiscuzX系列命令执行分析公开(三连弹)

1. 同点后台命令执行



在后台全局->上传设置->ImageMagick 程序安装路径

DiscuzX系列命令执行分析公开(三连弹)

由于这个功能是对图片进行处理的,所以,要在访问时提供一个本站有效的图片地址。而且最好是存放在data/attachment目录下的,因为默认就是这个目录,否则就要用“../”来修改路径。

所以我的访问路径为

http://192.168.188.142/DiscuzX3.1_1122/upload/misc.php?mod=imgcropper&img=forum/201312/05/094746ub04zw03jr4wi44m.jpg

然后直接点击左下角的裁剪,虽然会返回图片访问错误,但是命令却正常执行了,如下图所示:

DiscuzX系列命令执行分析公开(三连弹)

2. ImageMagick



这个漏洞需要在后台开启ImageMagick功能,并确保ImageMagick功能正常运行。下图是我在后台中开启的这个功能,并填写ImageMagick安装目录。

DiscuzX系列命令执行分析公开(三连弹)

如果这个功能开启,我们甚至可以在没有账号的情况下,前台完成命令执行的触发。

首先访问裁切图片的这个功能,因为这个漏洞的触发必须要有一张有效图片,所以我们可以在论坛帖子中随便找到一张图片来引用。例如:我的发帖图片是:

http://192.168.188.143/discuz20140604/data/attachment/forum/201406/13/155944d557e0dtcdpouoad.jpg

那么我要访问的裁切功能的URL为:

http://192.168.188.143/discuz20140604/misc.php?mod=imgcropper&img=forum/201406/13/155944d557e0dtcdpouoad.jpg

然后修改POST数据包中cutheight或者cutwidth中的内容为“%26%26mkdir tsrc||”提交,就可以在discuz根目录下创建一个tsrc的目录。

修改输入包如下图所示:

DiscuzX系列命令执行分析公开(三连弹)

提交后效果如下图所示:

DiscuzX系列命令执行分析公开(三连弹)

分类:默认分类 时间:2012-07-09 人气:0
本文关键词:
分享到:

相关文章

  • DiscuzX没有合法的文件被上传的修复方法 2014-09-25

      打开source/class/discuz/discuz_upload.php   编辑这个文件,将 由于程序限制了大尺寸(指分辨率)附件图片,提示 “没有合法的文件被上传”   更改方法:sourceclassdiscuzclass_upload.php   找到:   复制代码代码如下:   function get_image_info($target, $allowswf = false) {   $ext = discuz_upload::fileext($target);   $

  • Discuz!X升级/转换程序GETSHELL漏洞分析 2012-02-15

    0x01 漏洞分析 漏洞的根源在代码注释中出现换行,导致代码执行,流程如下: 0x0101 首先,从 index.php第30行跟入。 0x0102 do_config_inc.php的第37行,跟入这个save_config_file()函数。 0x0103 gobal.func.php第624行,跟入这个getvars()函数。 0x0104 继续跟入buildarray()这个函数 0x0105 漏洞出现在598行,这个$newline的问题。 这里因为$key可控,所以$newline可

  • Discuz! X1.5 升级至 Discuz! X2.0 正式版的升级流程 2012-05-05

    说明:本文档用于帮助您将原有的 Discuz! X1.5 版本升级到 Discuz! X2 版本。 在您开始升级之前,请务必逐条仔细阅读以下的注意事项: 1、升级之前,为了确保无误,强烈建议您备份原有数据,我们无法对升级前没有备份的用户提供任何技术支持。2、升级程序放置在发行版本的 utility/update.php,此程序需要上传到 install 目录中,并确保 install/data 中的 sql 文件完整。 3、升级到 Discuz! X2 版本中您在 Discuz! X1.5 安装

  • PHPCMS V9调用Discuz X2.5 版块帖子 2012-12-23

    调用论坛指定版块帖子或回复: {pc:get sql="SELECT * FROM discuzx.pre_forum_post where first=1 and fid=62 order by tid desc" num="1" cache="" return="data"} {loop $data $key $val} <dt><a href="http://论坛网址/thread-{$val[tid]}-1-1.html"><strong> {str_

  • Discuz!7.2.UCHome 2.0.SupeSite 7.5到Discuz!X2升级/转换 2013-02-02

    说明:本文档用于帮助您将原有社区产品升级或者转换到 Discuz!X2 正式版本。由于Discuz!6.1、Discuz!7.0升级方法和Discuz!7.2相同,可以参照Discuz!7.2升级方法操作,升级脚本压缩包放二楼。 在您开始升级之前,请务必逐条仔细阅读以下的注意事项: 1、升级之前,为了确保无误,强烈建议您备份原有数据,我们无法对升级前没有备份的用户提供任何技术支持。2、通常情况下,我们的升级程序放置在发行版本的 ./utilities/convert 目录中,此程序可以独立于产品

  • Discuz! 各版本升级至X2.5 RC全攻略 2013-05-13

      1. 如果你的DiscuzX 程序版本为 1.0、1.5、2.0 或者2.5Beta   1)备份数据库   2)建立文件夹 old,旧程序除了 data 和 config目录以外的程序移动进入 old目录中   3)上传Discuz! X2.5 RC程序   4)上传 utility 目录中的 update.php 到 install 目录,删除目录中的index.php   执行 http://你的域名/论坛路径/install/update.php   参照提示进行升级即可。升级时间随

  • Discuz! X3.1正式版发布 可打击垃圾广告帖 2013-05-18

      在经过3个月的研发内测后,新版Discuz! X3.1于9月23日正式发布。作为2013年又一款重要产品,Discuz! 倾力构建的“论坛云卫士”将为社区防御垃圾信息、遏制灌水行为、排除恶意攻击方面发挥关键作用,为守护论坛安全增加防护墙。   论坛云卫士:让论坛远离垃圾帖、盗号和恶意攻击   长期以来,论坛垃圾广告帖铺天盖地,论坛遭受肆无忌惮地恶意攻击,用户账号被盗取屡禁不止,一系列恶劣现象时有发生,不仅给用户的正常体验造成了严重伤害,而且对站长的生存环境造成了巨大威胁。   鉴于此,Dis

  • Discuz!X2 utf8升级为Discuz!X2.5 GBK 完美解决方案 2013-10-03

      因为原论坛安装的是Discuz!X2 UTF8比较占用空间,而且官方正好有发布了Discuz!X2.5正式版,因此就想转成直接升级为Discuz!X2.5 GBK版。   经过多次摸索并参考相关转换教程,终于找到这种转换方式的方法,实现完美转换了,下面给大家分享此经验。   首先说明:   1、该教程不考虑插件问题,插件必须重新卸载再安装相应编码   2、使用前最好先全站备份,这样出了问题也好恢复   一、首先将Discuz!X2 UTF8转换为Discuz!X2 GBK,具体教程如下:  

  • Discuz! X3.0 发布:聚焦移动化 更安全稳定 2014-09-02

      Discuz! X3.0 Beta版已于今日正式发布,Discuz! X3.0 在继承X2.5所拥有的平台性、扩展性的基础上,重点开发了移动端功能,并对Discuz! 现有功能进行了全方位的精雕细琢,改进体验,不堆积功能,让产品更稳定好用。   据Discuz! 官方介绍,此次提供的Discuz! X3.0 Beta版仅供站长测试和体验各项新功能,以收集站长反馈、改进建议,以及协助官方解决bug为主要目的,官方不推荐站长应用于正式场合。   Discuz! X3.0作了近百项细节改进和优化,

Copyright (C) quwantang.com, All Rights Reserved.

趣玩堂 版权所有 京ICP备15002868号

processed in 0.127 (s). 10 q(s)