文件包含漏洞是一种常见的Web应用程序安全漏洞,通常发生在PHP等服务器端脚本语言中。这种漏洞允许攻击者在应用程序中包含外部文件,通常是恶意文件,从而执行恶意代码或获取敏感信息。
文件包含漏洞通常出现在应用程序中使用了用户提供的输入来动态包含文件时,但未对输入进行充分验证或过滤的情况下。攻击者可以通过构造恶意的文件路径或利用未经验证的输入来执行任意代码,包括读取敏感文件、执行系统命令等。
为了防止文件包含漏洞,开发人员应该始终对用户输入进行严格验证和过滤,避免直接将用户输入用作文件包含路径。另外,可以限制应用程序对文件系统的访问权限,避免恶意文件被包含和执行。
文件包含函数:
require()
require_once()
include()
include_once()
include和require区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。
而include_once(),require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。
PHP伪协议:
1.file://协议:
file://协议是一种用于访问本地文件系统的URL协议。通过file://协议,用户可以直接在浏览器或其他应用程序中访问本地计算机上的文件,而不需要通过HTTP或其他网络协议。
file://协议的URL格式通常如下:
file://<host>/<path>
其中:
<host>
:通常是localhost或省略不写,表示本地计算机。<path>
:指定要访问的本地文件的路径,可以是绝对路径或相对路径。
使用file://协议可以方便地在浏览器中打开本地HTML文件、查看本地图片或视频等。但需要注意的是,由于安全原因,大多数浏览器对file://协议有一些限制,例如不允许跨域访问、限制JavaScript执行等,以防止恶意网站利用file://协议进行攻击。
2.PHP://协议:
PHP://协议是PHP中的一种特殊流(stream)协议,用于访问各种输入/输出资源。通过PHP://协议,可以像访问文件一样访问各种输入/输出资源,如标准输入输出、内存缓冲区、网络连接等。
常见的PHP://协议流封装器包括:
- php://stdin:标准输入流,用于从标准输入读取数据。
- php://stdout:标准输出流,用于向标准输出写入数据。
- php://memory:内存流,用于在内存中读写数据。
- php://temp:临时文件流,用于创建临时文件并进行读写操作。
- php://filter:用于读取源码。
- php://input:用于执行php代码
3.zip://协议:
zip 协议是一种用于访问 ZIP 归档文件中内容的 URL 协议。通过 zip 协议,可以像访问普通文件一样访问 ZIP 文件中的文件内容,而无需先解压整个 ZIP 文件。
zip 协议的 URL 格式通常如下:
zip://archive.zip#file.txt
其中:
archive.zip
:指定要访问的 ZIP 归档文件。file.txt
:指定要访问的 ZIP 归档文件中的文件路径。
通过 zip 协议,可以方便地读取 ZIP 归档文件中的文件内容,而无需将整个 ZIP 文件解压到磁盘上。这在处理大型 ZIP 文件或需要临时访问 ZIP 文件中的特定文件时非常有用。在 PHP 中,可以使用 zip 协议和相关函数来处理 ZIP 归档文件,例如 file_get_contents('zip://archive.zip#file.txt')
可以读取 ZIP 文件中的指定文件内容。
RCE文件包含:
1.php://input:
分析代码:
-
if (isset($_GET['file'])) {
: 这行代码检查是否存在名为'file'的GET参数。 -
if ( substr($_GET["file"], 0, 6) === "php://" ) {
: 这行代码检查GET参数'file'的前6个字符是否为"php://"。如果是,则执行文件包含操作。 -
include($_GET["file"]);
: 如果GET参数'file'以"php://"开头,则直接包含用户指定的文件。这样的操作可能导致代码执行漏洞,允许攻击者包含恶意文件。 -
echo "Hacker!!!";
: 如果GET参数'file'不以"php://"开头,则输出"Hacker!!!"。这是一种简单的防御措施,但并不足以阻止攻击。 -
} else {
: 如果不存在GET参数'file',则执行以下操作。 -
highlight_file(__FILE__);
: 这行代码会高亮显示当前文件的源代码。这是一种展示源代码的方式。
BP抓包:
构造?file=php://input
2.远程包含:
-
error_reporting(0);
: 这行代码将错误报告级别设置为0,即禁用错误报告。这可以防止泄露敏感信息给用户。 -
if (isset($_GET['file'])) {
: 这行代码检查是否存在名为'file'的GET参数。 -
if (!strpos($_GET["file"], "flag")) {
: 这行代码使用strpos()
函数检查GET参数'file'中是否包含"flag"字符串。如果不包含,则执行文件包含操作。 -
include $_GET["file"];
: 如果GET参数'file'中不包含"flag"字符串,则直接包含用户指定的文件。这样的操作可能导致代码执行漏洞,允许攻击者包含恶意文件。 -
} else {
: 如果GET参数'file'中包含"flag"字符串,执行以下操作。 -
echo "Hacker!!!";
: 输出"Hacker!!!"。这是一种简单的防御措施,但并不足以阻止攻击。
BP抓包:
构造?file=php://input <?php system("ls /");?>
获得flag
读取源代码:
发现include函数:php://filter:用于读取源码。构造?file=php://filter/resource=/flag