DVWA 通关指南:File Inclusion(文件包含)

File Inclusion(文件包含)

Some web applications allow the user to specify input that is used directly into file streams or allows the user to upload files to the server. At a later time the web application accesses the user supplied input in the web applications context. By doing this, the web application is allowing the potential for malicious file execution.
有些 web 应用程序允许用户指定直接文件流的输入,或允许用户将文件上载到服务器。稍后 web 应用程序访问 web 应用程序上下文中用户提供的输入。通过这样种操作,web 应用程序允许恶意文件执行。
If the file chosen to be included is local on the target machine, it is called "Local File Inclusion (LFI). But files may also be included on other machines, which then the attack is a "Remote File Inclusion (RFI).
如果选择要包含的文件是目标计算机上的本地文件,则称为“本地文件包含(LFI)”。但是文件也可能包含在其他机器上,这样的攻击就是“远程文件包含(RFI)”。
When RFI is not an option. using another vulnerability with LFI (such as file upload and directory traversal) can often achieve the same effect.Note, the term "file inclusion" is not the same as "arbitrary file access" or "file disclosure".
当 RFI 不是一个选项时。在 LFI 中使用另一个漏洞(例如文件上传和目录遍历)通常可以达到相同的效果。注意术语“文件包含”与“任意文件访问”或“文件泄漏”不同。
Read all five famous quotes from '../hackable/flags/fi.php' using only the file inclusion.
请在仅使用文件包含的情况下,阅读 “../hackable/flags/fi.php” 中的五句名言。

Low Level

This allows for direct input into one of many PHP functions that will include the content when executing.Depending on the web service configuration will depend if RFI is a possibility.
这允许直接输入到许多 PHP 函数中的一个,这些函数将在执行时包含内容。RFI 是否可行取决于 web 的服务配置。

源码审计

源码很简单,用 GET 方法接收文件路径,然后将其包含进来。服务器包含文件时,无论文件是否是 PHP 文件,都会尝试当做 PHP 文件来执行。如果文件内容确实是 PHP 文件,则会正常执行并返回结果,如果不是则会将文件内容回显到网页中,所以文件包含漏洞常常会导致任意文件读取与任意命令执行。

<?php

// The page we wish to display
$file = $_GET['page'];

?> 

例如靶场提供了 3 个文件,单击这些文件就会显示其执行内容,同时 url 也会用 GET 方法传递参数。

攻击方式

page 参数指的是文件路径,因此我们先传个不存在的文件名测试一下,看看有没有报错信息。传递 page 参数为 “1.php”,靶场报错并返回了文件所在的路径。

Warning: include(1.php): failed to open stream: No such file or directory in D:\DVWA-master\vulnerabilities\fi\index.php on line 36
Warning: include(): Failed opening '1.php' for inclusion (include_path='.;C:\php\pear;../../external/phpids/0.6/lib/') in D:\DVWA-master\vulnerabilities\fi\index.php on line 36

因此我们直接用相对路径,访问上两级文件夹下的 “fi.php'” 文件,构造出 payload。

?page=..\..\hackable\flags\fi.php

Medium Level

The developer has read up on some of the issues with LFI/RFI, and decided to filter the input. However, the patterns that are used, isn't enough.
开发人员已经阅读了 LFI/RFI 的一些问题,并决定过滤输入,然而他所使用的过滤还不够。

源码审计

源码如下,代码增加了 str_replace 函数对 page 参数进行了过滤。将 “http://”、“https://”替换为空阻止远程包含漏洞,将“../”、“..\” 替换为空阻止用相对路径访问文件。

<?php

// The page we wish to display
$file = $_GET['page'];

// Input validation
$file = str_replace(array( "http://", "https://" ), "", $file);
$file = str_replace(array( "../", "..\"" ), "", $file);

?> 

攻击方式

虽然代码将相对路径的语法过滤了,但是绝对路径不受影响,可以利用网页的报错信息推导出其他文件的绝对路径。当然也可以使用双写绕过,也就是让 str_replace 函数替换后的 page 参数是文件路径即可。

?page=...\.\...\.\hackable\flags\fi.php

High Level

The developer has had enough. They decided to only allow certain files to be used. However as there are multiple files with the same basename, they use a wildcard to include them all.
开发者已经受够了,他们决定只允许使用某些文件。但是由于存在多个具有相同基名的文件,因此它们使用通配符将它们全部包括在内。

源码审计

源码如下,使用 fnmatch 根据指定的模式来匹配文件名或字符串。该函数将检查 page 参数开头必须是否是 file,若是服务器才会去包含相应的文件。

<?php

// The page we wish to display
$file = $_GET['page'];

// Input validation
if( !fnmatch("file*", $file) && $file != "include.php"){
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?>

攻击方式

虽然是只能包含 file 开头的文件,但是实在太巧合了,我们依然可以利用 file 伪协议读取到文件内容。

?page=file:///D:\DVWA-master\hackable\flags\fi.php

Impossible Level

The developer calls it quits and hardcodes only the allowed pages, with there exact filenames. By doing this, it removes all avenues of attack.
开发人员只对允许的页面进行硬编码,并提供精确的文件名,这样做消除了所有的攻击途径。

<?php

// The page we wish to display
$file = $_GET['page'];

// Only allow include.php or file{1..3}.php
if($file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php"){
    // This isn't the page we want!
    echo "ERROR: File not found!";
    exit;
}

?>

总结与防御

为了更好地使用代码的重用性,可以使用文件包含函数将文件包含进来,直接使用文件中的代码来提高重用性。但是这也产生了文件包含漏洞,产生原因是在通过 PHP 的函数引入文件时,为了灵活包含文件会将被包含文件设置为变量,通过动态变量来引入需要包含的文件。此时用户可以对变量的值可控,而服务器端未对变量值进行合理地校验或者校验被绕过,就会导致文件包含漏洞。常用的文件包含函数有 include()、include_once()、require()、require_once()。
包含漏洞分为本地包含和原创包含 2 类,当包含的文件在服务器本地时,就形成了本地文件包含。文件包含可以包含任意文件,被包含的文件可以不是 PHP 代码,可以是文本或图片等。只要文件被包含就会被服务器脚本语言执行,如果包含的文件内容不符合 php 语法,会直接将文件内容输出。例如下面这段简易的代码:

<?php
    $file = $_GET['file'];
    include($file);
?>

当包含的文件在远程服务器上时,就形成了远程文件包含。所包含远程服务器的文件后缀不能与目标服务器语言相同,远程文件包含需要在 php.ini 中设置:

allow_url_include = on(是否允许 include/require 远程文件)
allow_url_fopen = on(是否允许打开远程文件)

参考资料

新手指南:DVWA-1.9全级别教程之File Inclusion
CTF-WEB:PHP 伪协议

posted @ 2020-09-13 22:53  乌漆WhiteMoon  阅读(2065)  评论(0编辑  收藏  举报