Created 星期二 24 十月 2017
2017年10月24号 状态:良好 心情:最近转战java web代码了

漏洞说明:
NiuShop开源商城系统v1.16前台使用插件功能处存在任意文件包含漏洞。远程攻击者可以利用该漏洞包含一句话木马,获取网站服务器管理权限。

  1. 前台使用插件功能处存在任意文件包含导致getshell:
    0x01 代码位置:
    \application\shop\controller\Addons.php 第30-53行
    代码分析:该处代码提供了调用使用插件的功能,并且访问这个功能点是不需要权限认证,构造好链接后
    可以直接访问。

      public function execute($addons = null, $controller = null, $action = null, $addons_type = null)
    {
    
    if (!empty($addons) && !empty($controller) && !empty($action)) {
        // 获取类的命名空间
        if($addons_type == null){
            //addon
            $class = get_addon_class($addons, 'addon_controller', $controller);
        }else{
            //addons
            $class = get_addon_class($addons_type, $addons, $controller);
        }
        if(class_exists($class)) {
            if ($model === false) {
                $this->error(lang('addon init fail'));
            }
            // 调用操作
            return  \think\App::invokeMethod([$class, $action]);
        }else{
    //                 $this->error(lang('控制器不存在'.$class));
        }
    }
    $this->error(lang('没有指定插件名称,控制器或操作!'));
    }
    

    0x02 接下来我们跟进到具体的控件功能的代码中,代码位置:\addons\Addons.php 第171-181行
    代码分析:这里我们主要分析fetch这个action,这个方法中把传入的template模板文件直接拿到TP框架代码中的fetch方法进行模板渲染。

     public function fetch($template = '', $vars = [], $replace = [], $config = [])
    {
    
    if (!is_file($template)) {
        $template = '/' . $template;
    }
    // 关闭模板布局
    $this->view->engine->layout(false);
    echo $this->view->fetch($template, $vars, $replace, $config);//调用TP框架fetch方法进行渲染
    }
    

    0x03 接下来我们跟进到框架中的fetch方法,看看它具体的实现方法:
    代码位置:\thinkphp\library\think\View.php 第148-171行
    代码分析:这里的代码根据类型设置去决定用来实现渲染模板的引擎以及判断是采用display还是fetch方法去处理

    public function fetch($template = '', $vars = [], $replace = [], $config = [], $renderContent = false)
    {
    // 模板变量
    $vars = array_merge(self::$var, $this->data, $vars);
    
    // 页面缓存
    ob_start();
    ob_implicit_flush(0);
    
    // 渲染输出
    $method = $renderContent ? 'display' : 'fetch';
    $this->engine->$method($template, $vars, $config);
    
    // 获取并清空缓存
    $content = ob_get_clean();
    // 内容过滤标签
    Hook::listen('view_filter', $content);
    // 允许用户自定义模板的字符串替换
    $replace = array_merge($this->replace, $replace);
    if (!empty($replace)) {
        $content = strtr($content, $replace);
    }
    return $content;
    }
    

    再跟进到具体fetch的实现方法:\thinkphp\library\think\view\driver\Php.php 第61-81行
    代码分析:此处代码会判断传入的template文件是否存在,同时检测默认模板文件有没有设置,不管有没有,
    反正都会被include直接包含,导致最终getshell

    public function fetch($template, $data = [])
     {
     if ('' == pathinfo($template, PATHINFO_EXTENSION)) {
         // 获取模板文件名
         $template = $this->parseTemplate($template);
     }
     // 模板不存在 抛出异常
     if (!is_file($template)) {
         throw new TemplateNotFoundException('template not exists:' . $template, $template);
     }
     // 记录视图信息
     App::$debug && Log::record('[ VIEW ] ' . $template . ' [ ' . var_export(array_keys($data), true) . ' ]', 'info');
     if (isset($data['template'])) {
         $template = $template;
         extract($data, EXTR_OVERWRITE);
         include $template;  
     } else {
         extract($data, EXTR_OVERWRITE);
         include $template;   ///////此处传入文件直接被include包含
     }
    

0x03 构造利用:
根据调用代码代码: \application\shop\controller\Addons.php 第30-53行。我们直接调用到系统安装时默认的模板wxtemplatemsg,
让系统判断这个类存在,然后就可以调用到addons/addons.php下的各种action。这里我们需要用到fetch这个方法,所以我们构造链接如下
,另外template这个参数表示系统需要包含的恶意攻击文件(当然这里的文件可以是任意的文件,我们在具体的攻击中,可通过前台的修改个人头像功能
上传一张带有恶意代码的图片,然后template参数指向它就能够被include包含,导致最终的getshell):
http://192.168.99.163/index.php?s=/shop/addons/execute/addons/wxtemplatemsg/controller/wxtemplatemsg/action/fetch/&template=./addons/test.txt
.\pasted_image.png

参考链接:http://www.cnvd.org.cn/flaw/show/1158591
该漏洞博主已提交至CNVD.