如何做网站专题,四面山网站建设,石家庄网站建设教程,最佳磁力引擎吧dedecms介绍
DedeCMS是国内专业的PHP网站内容管理系统-织梦内容管理系统#xff0c;采用XML名字空间风格核心模板#xff1a;模板全部使用文件形式保存#xff0c;对用户设计模板、网站升级转移均提供很大的便利#xff0c;健壮的模板标签为站长DIY自己的网站提供了强有力…dedecms介绍
DedeCMS是国内专业的PHP网站内容管理系统-织梦内容管理系统采用XML名字空间风格核心模板模板全部使用文件形式保存对用户设计模板、网站升级转移均提供很大的便利健壮的模板标签为站长DIY自己的网站提供了强有力的支持。高效率标签缓存机制允许对同类的标签进行缓存在生成 HTML的时候有利于提高系统反应速度降低系统消耗的资源。模型与模块概念并存在模型不能满足用户所有需求的情况下DedeCMS推出一些互动的模块对系统进行补充尽量满足用户的需求。众多的应用支持为用户提供了各类网站建设的一体化解决方案。
环境搭建
DedeCMS V5.8.1 beta 内测版下载 https://www.dedemao.com/dedeplug/dedecmsv58.html
ip地址池推荐
一般在红队检测、爬虫等工作会频繁被banip可
漏洞描述
这洞蛮简单的有点类似于以前那个dz的前台代码执行在写入临时tpl缓存文件的时候缓存内容中存在可控的函数且使用了include进行包含导致我们可以写入任意代码造成代码执行,漏洞主要是由于include\common.func.php中定义的ShowMsg参数导致的任何文件存在调用ShowMsg的情况下都可以造成模板注入。
漏洞分析
找个调用ShowMsg的文件下面以plus/recommend.php为例分析。
当$aid为空则会调用ShowMsg进到ShowMsg函数- \include\common.function.php
function ShowMsg($msg, $gourl, $onlymsg 0, $limittime 0)
{if (empty($GLOBALS[cfg_plus_dir])) {$GLOBALS[cfg_plus_dir] ..;}if ($gourl -1) {$gourl isset($_SERVER[HTTP_REFERER]) ? $_SERVER[HTTP_REFERER] : ;//可控if ($gourl ) {$gourl -1;}}定义的模板内容 $htmlhead html\r\nhead\r\ntitleDedeCMS提示信息/title\r\nmeta http-equiv\Content-Type\ content\text/html; charset{dede:global.cfg_soft_lang/}\ /meta name\viewport\ content\widthdevice-width, initial-scale1, maximum-scale1, user-scalableno\meta name\renderer\ content\webkit\meta http-equiv\Cache-Control\ content\no-siteapp\ /link rel\stylesheet\ type\text/css\ href\{dede:global.cfg_assets_dir/}/pkg/uikit/css/uikit.min.css\ /link rel\stylesheet\ type\text/css\ href\{dede:global.cfg_assets_dir/}/css/manage.dede.css\base target_self//headbody . (isset($GLOBALS[ucsynlogin]) ? $GLOBALS[ucsynlogin] : ) . center style\width:450px\ class\uk-container\div class\uk-card uk-card-small uk-card-default\ style\margin-top: 50px;\div class\uk-card-header\ style\height:20px\DedeCMS 提示信息/divscript\r\n;$htmlfoot /script/centerscript src\{dede:global.cfg_assets_dir/}/pkg/uikit/js/uikit.min.js\/scriptscript src\{dede:global.cfg_assets_dir/}/pkg/uikit/js/uikit-icons.min.js\/script/body\r\n/html\r\n;$litime ($limittime 0 ? 1000 : $limittime);$func ;if ($gourl -1) {if ($limittime 0) {$litime 3000;}$gourl javascript:history.go(-1);;}if ($gourl || $onlymsg 1) {$msg scriptalert(\ . str_replace(\, “, $msg) . \);/script;} else {//当网址为:close::objname 时, 关闭父框架的idobjname元素if (preg_match(/close::/, $gourl)) {$tgobj trim(preg_replace(/close::/, , $gourl));$gourl javascript:;;$func . window.parent.document.getElementById({$tgobj}).style.displaynone;\r\n;}$func . var pgo0;function JumpUrl(){if(pgo0){ location$gourl; pgo1; }}\r\n;$rmsg $func;$rmsg . document.write(\div styleheight:130px;font-size:10pt;background:#ffffffbr /\);\r\n;$rmsg . document.write(\ . str_replace(\, “, $msg) . \);\r\n;$rmsg . document.write(\;if ($onlymsg 0) {if ($gourl ! javascript:; $gourl ! ) {$rmsg . br /a href{$gourl}如果你的浏览器没反应请点击这里.../a;$rmsg . br//div\);\r\n;$rmsg . setTimeout(JumpUrl(),$litime);;} else {$rmsg . br//div\);\r\n;}} else {$rmsg . br/br//div\);\r\n;}$msg $htmlhead . $rmsg . $htmlfoot;//$msg存储缓存信息}$tpl new DedeTemplate();//调用DedeTemplate类$tpl-LoadString($msg); //处理模板传输$msg$tpl-Display();
}在这里gourl是可控的定义默认为-1
if (empty($aid)) {ShowMsg(文档ID不能为空!, -1);exit();
}所以gourl的值可控。
接着看处理模板的位置,跟进LoadString($msg)方法DedeTemplate类定义追溯到include/dedetemplate.class.php
public function LoadString($str ){$this-sourceString $str;//将缓存信息存储到sourceString$hashcode md5($this-sourceString);$this-cacheFile $this-cacheDir . /string_ . $hashcode . .inc;$this-configFile $this-cacheDir . /string_ . $hashcode . _config.inc;$this-ParseTemplate();}该函数首先设置缓存文件和缓存配置文件缓存文件位于data\tplcache目录随后调用ParserTemplate对文件进行初步检查。
接着返回到\include\common.function.php看到最后调用了Display()方法,include/dedetemplate.class.php
public function Display(){global $gtmpfile;extract($GLOBALS, EXTR_SKIP);$this-WriteCache();include $this-cacheFile;}可以发现它调用了WriteCache方法和包含了cacheFile文件
先追溯WriteCache方法:include/dedetemplate.class.php
public function WriteCache($ctype all){if (!file_exists($this-cacheFile) || $this-isCache false|| (file_exists($this-templateFile) (filemtime($this-templateFile) filemtime($this-cacheFile)))) {if (!$this-isParse) {$this-ParseTemplate();}$fp fopen($this-cacheFile, w) or dir(Write Cache File Error! );flock($fp, 3);$result trim($this-GetResult());$errmsg ;if (!$this-CheckDisabledFunctions($result, $errmsg)) {fclose($fp);unlink($this-cacheFile);die($errmsg);}fwrite($fp, $result);fclose($fp);if (count($this-tpCfgs) 0) {$fp fopen($this-configFile, w) or dir(Write Config File Error! );flock($fp, 3);fwrite($fp, . ?php . \r\n);foreach ($this-tpCfgs as $k $v) {$v str_replace(\, \\\, $v);$v str_replace(\$, \\\$, $v);fwrite($fp, \$this-tpCfgs[$k]\$v\;\r\n);}fwrite($fp, ? . );fclose($fp);}}在WriteCache写入了缓存文件那么就可以通过referer构造payload再通过上面的include文件包含缓存文件进行RCE
我们可以先测试赋值Referer为Keepb1ue然后写入的模板内容。
那我们现在就可以将Referer替换为注入代码当然我们如果直接写一些常见的危险函数是不行的因为在dedetemplate.class.php中存在CheckDisabledFunctions函数CheckDisabledFunctions函数在WriteCache中被调用会对内容进行一个检测。
public function CheckDisabledFunctions($str, $errmsg ){global $cfg_disable_funs;$cfg_disable_funs isset($cfg_disable_funs) ? $cfg_disable_funs : phpinfo,eval,exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source,file_put_contents,fsockopen,fopen,fwrite;// 模板引擎增加disable_functionsif (!defined(DEDEDISFUN)) {$tokens token_get_all_nl($str);$disabled_functions explode(,, $cfg_disable_funs);foreach ($tokens as $token) {if (is_array($token)) {if ($token[0] 306 in_array($token[1], $disabled_functions)) {$errmsg DedeCMS Error:function disabled . $token[1] . a hrefhttp://help.dedecms.com/install-use/apply/2013/0711/2324.html target_blankmore.../a;return false;}}}}return true;}函数首先通过token_get_all_nl函数获取输入时处理时并没有过滤双引号导致在disable_functions列表匹配时失败。
这边由于某种原因就不把payload给出来了。。
修复建议
当前官方已发布最新版本建议受影响的用户及时更新升级到最新版本。链接如下
https://github.com/dedecms/DedeCMS