PHP 任意文件包含
PHP Arbitrary File Inclusion
假设我们有一个 script.php,它根据 Windows 上的 GET 参数(比如 load)加载文件。
script.php:
<?php include 'D:\mydir\' . $_GET['load'] . '.php'; ?>
该脚本不检查有效输入,因此攻击者可以轻松地将参数更改为任何文件:http://address/script.php?load=mymaliciousinput.ext%00
再假设Windows安装在C盘,而我们的webserver安装在D盘。
有哪些可能的漏洞?是否可以包含来自另一个 server/website 的恶意文件?
Is it possible to include a malicious file from another server/website?
长话短说:是的。这可能是可能的,但这也取决于您的 PHP 版本和服务器配置。
What are the possible vulnerabilities?
下面描述的情况是典型的file injection vulnerability,在这种情况下,如果不过滤请求数据,您很容易受到本地文件注入(LFI)和远程文件注入(RFI)。
记住这一点也很好:
include
或 require
将加载并执行 php 中的任何好的代码,无论它是否在 php 文件中。查看 here 例如带有 php 代码的 jpg 图像(这个文件甚至被 mimetype 识别为 image/jpg!)。
如果您使用默认 Apache/PHP 设置,include
或 require
也将打开纯文本文件,例如您的 etc/hosts
而不会出现错误。
使用像您一样的 GET 变量,在 Windows 中,最终用户可以使用带有“..\”路径的变量。所以可以松散地检查所有目录。
Here 您可以查看如何包含远程文件。根据那里的答案,您可以轻松地重新配置 server/php 堆栈并测试漏洞。
编辑:
as for point 3, do you know of any example how you can jump to the other drive?
在您的示例中,对于具有 PHP5 默认配置的 Apache2 或 Nginx,我无法找到跳转到另一个驱动器的方法。放置退格键 (%08)、转义码等不会删除之前添加的磁盘字母。
所以对于 include 'D:\mydir\' . $_GET['load'] . '.php';
你必须留在同一个驱动器中。当然include $_GET['load'] . '.php';
你可以选择任何你喜欢的url/drive。
我不知道您可以将任何内容附加到 Windows 路径名,该路径名已经使用驱动器标识符作为根目录以更改为另一个驱动器。
但这肯定不是您应该依赖的东西。除了晦涩难懂的 Windows 路径技巧外,在驱动器上包含其他项目 PHP 文件可能存在特定于应用程序的漏洞,如果有任何其他方式用户可以将文件写入 D: 驱动器他们可以升级。
例如,如果站点具有将数据存储在 D: 驱动器上的图像上传功能,则攻击者可以上传包含字符串 <?php
的图像,然后包含它以执行任意代码。或者,如果驱动器上的文件记录了任何内容,攻击者可以发出导致 <?php
写入日志文件的请求,然后包含日志文件。
假设我们有一个 script.php,它根据 Windows 上的 GET 参数(比如 load)加载文件。
script.php:
<?php include 'D:\mydir\' . $_GET['load'] . '.php'; ?>
该脚本不检查有效输入,因此攻击者可以轻松地将参数更改为任何文件:http://address/script.php?load=mymaliciousinput.ext%00
再假设Windows安装在C盘,而我们的webserver安装在D盘。 有哪些可能的漏洞?是否可以包含来自另一个 server/website 的恶意文件?
Is it possible to include a malicious file from another server/website?
长话短说:是的。这可能是可能的,但这也取决于您的 PHP 版本和服务器配置。
What are the possible vulnerabilities?
下面描述的情况是典型的file injection vulnerability,在这种情况下,如果不过滤请求数据,您很容易受到本地文件注入(LFI)和远程文件注入(RFI)。
记住这一点也很好:
include
或require
将加载并执行 php 中的任何好的代码,无论它是否在 php 文件中。查看 here 例如带有 php 代码的 jpg 图像(这个文件甚至被 mimetype 识别为 image/jpg!)。
如果您使用默认 Apache/PHP 设置,include
或require
也将打开纯文本文件,例如您的etc/hosts
而不会出现错误。使用像您一样的 GET 变量,在 Windows 中,最终用户可以使用带有“..\”路径的变量。所以可以松散地检查所有目录。
Here 您可以查看如何包含远程文件。根据那里的答案,您可以轻松地重新配置 server/php 堆栈并测试漏洞。
编辑:
as for point 3, do you know of any example how you can jump to the other drive?
在您的示例中,对于具有 PHP5 默认配置的 Apache2 或 Nginx,我无法找到跳转到另一个驱动器的方法。放置退格键 (%08)、转义码等不会删除之前添加的磁盘字母。
所以对于 include 'D:\mydir\' . $_GET['load'] . '.php';
你必须留在同一个驱动器中。当然include $_GET['load'] . '.php';
你可以选择任何你喜欢的url/drive。
我不知道您可以将任何内容附加到 Windows 路径名,该路径名已经使用驱动器标识符作为根目录以更改为另一个驱动器。
但这肯定不是您应该依赖的东西。除了晦涩难懂的 Windows 路径技巧外,在驱动器上包含其他项目 PHP 文件可能存在特定于应用程序的漏洞,如果有任何其他方式用户可以将文件写入 D: 驱动器他们可以升级。
例如,如果站点具有将数据存储在 D: 驱动器上的图像上传功能,则攻击者可以上传包含字符串 <?php
的图像,然后包含它以执行任意代码。或者,如果驱动器上的文件记录了任何内容,攻击者可以发出导致 <?php
写入日志文件的请求,然后包含日志文件。