理解文件包含
让我们深入探讨「文件包含」的概念及其潜在的漏洞,特别是为初学者量身定制的内容。
文件包含是编程中的常见做法,尤其是在代码可重用性的背景下。开发者通常会将频繁使用的函数或模块封装到单独的文件中。当需要这些函数或模块时,他们只需在代码中包含这些文件,从而避免重复编写相同的代码。
在 PHP 中,有四个主要的文件包含函数:
include()
require()
include_once()
require_once()
以下是每个函数的简要概述:
include()
:此函数在调用时包含一个文件。如果文件未找到,PHP 会发出警告,但脚本会继续运行。
require()
:此函数在脚本开始运行之前包含一个文件。如果文件未找到,PHP 会发出致命错误并停止脚本。
include_once()
和 require_once()
:这些函数与 include()
和 require()
类似,但它们确保文件只被包含一次,即使函数被多次调用。
文件包含方法可以大致分为两种类型:
- 静态包含
- 动态包含
这两种类型的区别将在后续部分通过示例进行说明。
在我们的课程中,我们将探索位于 /home/labex/project/
目录中的三个 .php
文件。这些文件是:
lfi_static.php
lfi_dynamic.php
echo.php
让我们了解每个文件的作用:
-
lfi_static.php
:此文件以静态方式包含 echo.php
文件。换句话说,echo.php
文件的路径是硬编码的,不会改变。这种方法是安全的,不会暴露任何漏洞。
<?php
include("./echo.php");
?>
-
lfi_dynamic.php
:此文件根据 URL 中的 'file' 参数包含其他文件。如果未提供此参数,它只会提示如何使用它。然而,如果参数由攻击者控制,这种方法可能会带来风险。
<?php
if (isset($_GET['file'])) {
include($_GET['file']);
}
else{
echo "You can use the 'file' parameter to include files";
}
?>
-
echo.php
:此文件在被包含时简单地输出一条成功消息。
<?php
echo 'Great, now you have successfully included the content of echo.php!'
?>
使用以下命令在终端中准备用于 lfi
测试的镜像:
cd ~/projects
docker build -t lfi-image .
当镜像构建完成后,你可以使用该镜像启动一个容器来测试 lfi
漏洞:
docker run -d --name lfi -p 80:80 lfi-image
现在你可以在浏览器中测试这些文件。例如,要访问 lfi_static.php
文件,你可以输入以下 URL:
http://127.0.0.1/LFI/lfi_static.php
你会看到 lfi_static.php
文件成功包含了 echo.php
的内容。请记住,这种静态包含文件的方法是安全的。
现在,让我们看看 lfi_dynamic.php
文件。使用以下 URL 访问它:
http://127.0.0.1/LFI/lfi_dynamic.php
你会看到一个提示,告诉你使用 'file' 参数。让我们这样做并包含 echo.php
:
http://127.0.0.1/LFI/lfi_dynamic.php?file=./echo.php
你会看到 echo.php
被成功包含。这展示了文件包含的工作原理。重要的是要记住,虽然这是一个 PHP 示例,但这些原则适用于其他编程语言,尽管使用的具体函数可能不同。