当前位置:WooYun >> 漏洞信息

漏洞概要 关注数(24) 关注此漏洞

缺陷编号:wooyun-2014-072071

漏洞标题:ThinkSAAS前台Getshell

相关厂商:thinksaas.cn

漏洞作者: phith0n

提交时间:2014-08-12 19:24

修复时间:2014-11-07 19:26

公开时间:2014-11-07 19:26

漏洞类型:命令执行

危害等级:高

自评Rank:20

漏洞状态:漏洞已经通知厂商但是厂商忽略漏洞

漏洞来源: http://www.wooyun.org,如有疑问或需要帮助请联系 [email protected]

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2014-08-12: 细节已通知厂商并且等待厂商处理中
2014-08-17: 厂商主动忽略漏洞,细节向第三方安全合作伙伴开放
2014-10-11: 细节向核心白帽子及相关领域专家公开
2014-10-21: 细节向普通白帽子公开
2014-10-31: 细节向实习白帽子公开
2014-11-07: 细节向公众公开

简要描述:

一个二次操作造成的getshell。
官网又挂加速乐,又审核什么的,懒得测试官网了,就麻烦审核大人本地测试拉~

详细说明:

说一下原理吧。
/app/photo/action/album.php 245行

//批量修改执行
case "info_do":

//用户是否登录
$userid = aac('user')->isLogin();

$albumid = intval($_POST['albumid']);

$albumface = tsClean($_POST['albumface']);

$arrPhotoId = $_POST['photoid'];
$arrPhotoDesc = $_POST['photodesc'];

if($TS_USER['user']['isadmin']==0){

foreach($arrPhotoDesc as $key=>$item){

//过滤内容开始
aac('system')->antiWord($item);
//过滤内容结束

}
}

foreach($arrPhotoDesc as $key=>$item){
if($item){
$photoid = intval($arrPhotoId[$key]);

$new['photo']->update('photo',array(
'photoid'=>$photoid,
),array(

'photodesc'=>tsClean($item),

));

}
}

//更新相册封面
if($albumface){
$new['photo']->update('photo_album',array(
'userid'=>$userid,
'albumid'=>$albumid,
),array(
'albumface'=>$albumface,
));
}

header("Location: ".tsUrl('photo','album',array('id'=>$albumid)));

break;


观察这个动作:$albumface = tsClean($_POST['albumface']);
从POST albumface获得了albumface的值。这个实际上是相册封面的意思。
tsClean是过滤xss的函数,跟本操作无关,暂且不表。
获得了albumface后插入photo_album表:

//更新相册封面
if($albumface){
$new['photo']->update('photo_album',array(
'userid'=>$userid,
'albumid'=>$albumid,
),array(
'albumface'=>$albumface,
));
}


本来是无害的一个操作。不过我们再来看到另一个位置(安装好以后才有的)。
/cache/template/photo.photo.tpl.php:

<div><a href="<?php echo tsurl('photo','album',array('id'=>$item['albumid']))?>" class="album_photo"><img src="<?php if($item['albumface'] == '') { ?><?php echo SITE_URL;?>app/photo/skins/default/photo_album.png<?php } else { ?><?php echo tsXimg($item['albumface'],'photo',170,'170',$item['path'],1)?><?php } ?>" width="170" height="170" alt="<?php echo $item['albumname'];?>" /></a>


这里取到了$item['albumface'],并传入tsXimg函数。于是我们来看看这个函数:
/thinksaas/tsFunction.php 671行

/**
* ThinkSAAS专用图片截图函数
* @param unknown $file 数据库里的图片url
* @param unknown $app app名称
* @param unknown $w 缩略图片宽度
* @param unknown $h 缩略图片高度
* @param string $path
* @param string $c 1裁切,0不裁切
* @return void|string
*/
function tsXimg($file, $app, $w, $h, $path = '', $c = '0') {

if (! $file) {
return false;
}else{

//$info = explode ( '.', $file );
//$name = md10 ( $file ) . '_' . $w . '_' . $h . '.' . $info [1];

$info = explode ( '/', $file );
$name = $info [2];

if ($path == '') {
$cpath = 'cache/' . $app . '/' . $w . '/' . $name;
} else {
$cpath = 'cache/' . $app . '/' . $path . '/' . $w . '/' . $name;
}

if (! is_file ( $cpath )) {
createFolders ( 'cache/' . $app . '/' . $path . '/' . $w );
$dest = 'uploadfile/' . $app . '/' . $file;
$arrImg = getimagesize ( $dest );
if ($arrImg [0] <= $w) {
copy ( $dest, $cpath );

} else {
require_once 'thinksaas/tsImage.php';
$resizeimage = new tsImage ( "$dest", $w, $h, $c, "$cpath" );
}
}

return SITE_URL . $cpath;

}
}


这个函数过程是这样:
1.$info = explode ( '/', $file ); 将传入的路径用/来分成数组
2.$name = $info [2]; name是数组的第三项。
3.$cpath = 'cache/' . $app . '/' . $path . '/' . $w . '/' . $name; 将cpath设置一下,可以看到,直接将name放进cpath里了。
4.如果cpath不是文件,就创建目录:createFolders ( 'cache/' . $app . '/' . $path . '/' . $w );
5.getimagesize ( $dest ); 获得dest的大小,dest是'uploadfile/' . $app . '/' . $file,传入文件的路径,$file可控。
6.if ($arrImg [0] <= $w) {copy ( $dest, $cpath );} 如果获得的宽度($arrImg [0])小于预设值$w,则直接将dest复制到cpath。
发现什么了吗,copy这个操作的两个参数都是我们可以控制的。于是,我们就可以轻松地getshell。
具体操作步骤见漏洞证明。

漏洞证明:

首先注册用户,创建一个专辑:

01.jpg


记下这个时候的专辑id,我的是1:

002.jpg


把shell改后缀为.gif然后上传。注意,不需要用图片木马,直接webshell上传即可。因为后面要验证图片的宽度小于170,如果你的图片木马太大反而不能生成。
查看,并记下路径:

003.jpg


然后向localhost/think/index.php?app=photo&ac=album&ts=info_do POST如下数据:

004.jpg


如上图,我们之前说的$name取得是$info[2],也就是用/分割后的第三个,所以我前面加了个1/2/shell.php这个时候取的$name既是shell.php。
然后后面我需要用../跳转到根目录下,再把刚才记下的路径放在后面(上图第二个红框),发包后数据库里就改好了。
再访问一下localhost/think/index.php?app=photo,生成shell.php:

005.jpg


查看http://localhost/think/cache/photo/170/shell.php即可:

006.jpg


所以说这是一个“二次getshell”,先让危险的数据进入数据库,再通过程序取出,getshell。

修复方案:

你们懂。

版权声明:转载请注明来源 phith0n@乌云


漏洞回应

厂商回应:

危害等级:无影响厂商忽略

忽略时间:2014-11-07 19:26

厂商回复:

最新状态:

暂无


漏洞评价:

评论

  1. 2014-08-12 19:25 | roker ( 普通白帽子 | Rank:357 漏洞数:108 )

    前排顶师傅。

  2. 2014-08-12 21:57 | phith0n 认证白帽子 ( 核心白帽子 | Rank:656 漏洞数:107 | 一个想当文人的黑客~)

    @xsser @疯狗怎么这个也走小厂商呀。。。这么经典的二次getshell。。。

  3. 2014-08-12 22:02 | BadCat ( 实习白帽子 | Rank:81 漏洞数:21 | 悲剧的我什么都不会)

    这牛了,真的牛了...我看那么久的代码都没找到 T_T (我还是太浅了

  4. 2014-08-24 11:23 | 廷廷 ( 路人 | Rank:0 漏洞数:1 | 有很强的好奇心,爱好广泛,求女女带走。。...)

    前排顶师傅。 师傅好厉害