来源:自学PHP网 时间:2015-04-17 13:03 作者: 阅读:次
[导读] 韩国的一个博客程序TEXTCUBE 读了下发现个奇怪的问题 技术有限 希望大家点拨下!\framework\Dispatcher.php (57行)$part = strtok($uri[#39;input#39;], #39;/#39;); // $uri[#39;input#39;] == ......
韩国的一个博客程序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); //读取 www.2cto.com 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); } } 我这里的提交格式是http://www.2cto.com /tc/index.php?resources/locale/messages.php. 后面的resources/locale/messages.php.即是$uri['input']的值 www.2cto.com 测试环境是windows7+apache2.0+php5.2.14 由于是windows下 所以可以绕过strcasecmp(substr( $path, -3 ), "php" ) 这句的限制 直接在php后面加个点即可 下面问题来了, 程序中限制了读取文件的几个目录 array('resources','plugins','cache','skin','attach','thumbnail') 所以要读取根目录的config肯定得跳到上层的 而dumpWithEtag函数里总共有3个过滤 分别是/.. \\.. 以及后缀是否为php 看样子很白痴的一个验证 很轻松就能绕过的 因为/..可以用\..替换 \\..更是不用说了, 所以构造了以下格式 http://127.0.0.1/tc/index.php?resources/\..\config.php. 因为最开头有一句$part = strtok($uri['input'], '/') 用来获取目录 所以在白名单目录后必须有一个/号 这格式看似是没问题的吧 但是却卡在了strpos( $path, "\\.." ) !== false 这里 百思不得其解 随后分别用了以下格式: http://127.0.0.1/tc/index.php?resources/.\..\config.php. http://127.0.0.1/tc/index.php?resources/1212\..\..\config.php. 通通都卡在那一句了 明明没出现\\..字符串的 为何不行呢? -------------------------------------------------------------------------------- alibaba:在双引号 “” 里,\\ 就是\,所以这句"\\.." 就是争对\.. 而写 from:t00ls.net |
自学PHP网专注网站建设学习,PHP程序学习,平面设计学习,以及操作系统学习
京ICP备14009008号-1@版权所有www.zixuephp.com
网站声明:本站所有视频,教程都由网友上传,站长收集和分享给大家学习使用,如由牵扯版权问题请联系站长邮箱904561283@qq.com