当前位置:首页 >> 网络通讯 >> 网络安全 >> 内容

TEXTCUBE鸡肋读取文件漏洞

时间:2013/4/19 12:09:00 作者:平凡之路 来源:xuhantao.com 浏览:

韩国的一个博客程序TEXTCUBE  读了下发现个奇怪的问题  技术有限 希望大家点拨下!
 
\framework\Dispatcher.php (57行)
 
$part = strtok($uri['input'], '/');   // $uri['input'] == resources/locale/messages.php.
if (in_array($part, array('resources','plugins','cache','skin','attach','thumbnail'))) {  //限制了读取目录 无法直接读根目录
    $part = ltrim(rtrim($part == 'thumbnail' ?
          preg_replace('/thumbnail/', 'cache/thumbnail', $uri['input'], 1) :
          $uri['input']), '/');
    $part = (($qpos = strpos($part, '?')) !== false) ? substr($part, 0, $qpos) : $part;
    if(file_exists($part)) {
        require_once ROOT.'/library/function/file.php';
        dumpWithEtag($part); //读取
        exit;
    } else {
        header("HTTP/1.0 404 Not Found");exit;
    }
}\library\function\file.php(138行)
 
function dumpWithEtag($path) {
    $path = urldecode($path);
    $qIndex = strpos($path,'?');
    if( $qIndex !== false ) {
        $path = substr($path,0,$qIndex);
    }
    /* I think, it is a bad idea to check '..' and skip.
       but this is an annoyance to solve gracefully about whole HTTP request */
    /* Kill them all requests with referencing parent directory */
    if( strpos( $path, "/.." ) !== false ||
        strpos( $path, "\\.." ) !== false || //卡在此处
        strcasecmp( substr( $path, -3 ), "php" ) == 0 ||
        !file_exists( $path ) ) {
        header("HTTP/1.0 404 Not found");
        exit;
    }
    $fs = stat( $path );
    if( !$fs || !$fs['size'] ) { header('HTTP/1.1 404 Not Found');exit; }
    $etag = sprintf( "textcube-%x", (0x1234*$fs['size'])^$fs['mtime'] );
    $lastmodified = gmdate("D, j M Y H:i:s ", $fs['mtime']) . "GMT";
    $length = $fs['size'];
 
    if( !headerEtag($etag,$length,$lastmodified) ) {
        //echo $path;
    //exit;
        header('Content-type: '.getMIMEType(null,$path));
       
        $f =  fopen($path,"r");
        if( !$f ) {
            header("HTTP/1.0 404 Not found");
            exit;
        }
        while( ($content=fread($f,8192)) ){
            echo $content;
        }
        fclose($f);
    }
}

我这里的提交格式是 /tc/index.php?resources/locale/messages.php.
 
后面的resources/locale/messages.php.即是$uri['input']的值
 
测试环境是windows7+apache2.0+php5.2.14  由于是windows下  所以可以绕过strcasecmp(substr( $path, -3 ), "php" ) 这句的限制  直接在php后面加个点即可
 
 


 
下面问题来了, 程序中限制了读取文件的几个目录
 
array('resources','plugins','cache','skin','attach','thumbnail')  所以要读取根目录的config肯定得跳到上层的
 
而dumpWithEtag函数里总共有3个过滤
 
分别是/.. \\.. 以及后缀是否为php
 
 
 
看样子很白痴的一个验证  很轻松就能绕过的  因为/..可以用\..替换  \\..更是不用说了, 所以构造了以下格式
 
?resources/\..\config.php.
 
因为最开头有一句$part = strtok($uri['input'], '/')
 
用来获取目录  所以在白名单目录后必须有一个/号  这格式看似是没问题的吧
 
但是却卡在了strpos( $path, "\\.." ) !== false
 
这里 百思不得其解
 
 
 
随后分别用了以下格式:
 
?resources/.\..\config.php.
 
?resources/1212\..\..\config.php.
 
通通都卡在那一句了  明明没出现\\..字符串的  为何不行呢?
 
 
--------------------------------------------------------------------------------
 
alibaba:在双引号 “” 里,\\ 就是\,www.xuhantao.com,所以这句"\\.." 就是争对\.. 而写
 
from:t00ls.net ,涛涛电脑知识

相关文章
  • 没有相关文章
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
  • 徐汉涛(www.xuhantao.com) © 2024 版权所有 All Rights Reserved.
  • 部分内容来自网络,如有侵权请联系站长尽快处理 站长QQ:965898558(广告及站内业务受理) 网站备案号:蒙ICP备15000590号-1