通过PHP函数引入文件时,传入的文件名没有经过合理的验证,从而操作了预想之外的文件,就可能导致意外的文件泄漏甚至恶意代码注入。
allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据
allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件
php中常见的文件包含函数有以下四种:
include与require基本是相同的,除了错误处理方面:
include(),只生成警告(E_WARNING),并且脚本会继续
require(),会生成致命错误(E_COMPILE_ERROR)并停止脚本
include_once()与require()_once(),如果文件已包含,则不会包含,其他特性如上
include包含的文件php只能运行解析是读不到的。如果是html是直接解析了。【Linux下是同理的】
PHP 提供了一些杂项输入/输出(IO)流,允许访问 PHP 的输入输出流、标准输入输出和错误描述符, 内存中、磁盘备份的临时文件流以及可以操作其他读取写入文件资源的过滤器。
php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。
所以我们一般对其进行编码,让其不执行。从而导致 任意文件读取。
file:// 协议在双off的情况下也可以正常使用
allow_url_fopen :off/on
allow_url_include:off/on
file:// 用于访问本地文件系统
在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响

cm.php
<meta charset="utf8">
<?php
error_reporting(0);
$file = $_GET["file"];
if(stristr($file,"php://input") || stristr($file,"zip://") || stristr($file,"phar://") || stristr($file,"data:")){
exit('hacker!');
}
if($file){
include($file);
}else{
echo ' tips ';
}
?>
上述代码包含了flag.php文件,我们创建flag.PHP文件。再使用filter获取cm.php源码。

输入协议内容获取源码。
http://127.0.0.1/cm.php?file=file://E:/phpstudy/phpstudy_pro/WWW/include_php/phpinfo.php

发现我们并没有使用包含的文件只是依附于这个文件来查其他位置的文件。为此我们查看不仅限于当前文件
使用php://input、 php://stdin、 php://memory 和 php://temp 的状态
allow_url_fopen :off/on
allow_url_include:on
php://filter*读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。
php://filter在双off的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
php:// 访问各个输入/输出流(I/Ostreams)
在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。

php://filter
?file=php://filter/read=convert.base64-encode/resource=文件相对位置或者绝对位置
测试现象:同样采用cm.php代码
http://127.0.0.1/cm.php?file=php://filter/read=convert.base64-encode/resource=./cm.php
- 1
将获取到的base64进行解码
php://input 可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。
allow_url_fopen :off/on
allow_url_include:on
5.6-7.0版本

测试对象:同样采用cmd.php
因为为POST 我们需要使用Hackebar,我们这抓包更明显一些。
因为input为POST修改模式为POST,并且添加一句话
这里我失败了,因为没有修改配置文件。【修改保存重启服务】
再次尝试
zip://, bzip2://, zlib://协议在双off的情况下也可以正常使用;
allow_url_fopen :off/on
allow_url_include:off/on
zip://, bzip2://, zlib:// 均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名。

allow_url_fopen :off/on
allow_url_include:off/on
zip://archive.zip#dir/file.txt
zip:// [压缩文件绝对路径]#[压缩文件内的子文件名]
由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23,且此处经过测试相对路径是不可行,所以只能用绝对路径。
测试:
压缩txt文件
进行调试?file=zip://E:/phpstudy/phpstudy_pro/WWW/include_php/show.zip%23show.txt
- 1
修改zip为jpg一样有用
应用于后缀为bz2的压缩包
allow_url_fopen :off/on
allow_url_include:off/on
格式:compress.bzip2://file.bz2
?file=compress.bzip2://E:/phpstudy/phpstudy_pro/WWW/include_php/show.bz2
地址栏路径可以是绝对也可以是相对
返回Unable to find the wrapper "compress.bzip2"表示计算机没有bz2模块。
这里bz2的压缩文件在windows中是不支持压缩的好像,需要在linux中安装bzip2,执行bzip2 -z
文件名才可以压缩。为此在可以中Linux实验。
但是为了直观选择依就在Windows下只需要下载bz2模块就可以了。【将Linux中压缩文件下拉到Windows】
在phpstudy中勾选php_bz2进行安装即可
如此正常压缩到了bz2压缩包,并且Windows有bz2的扩展模块
应用于后缀为gz的压缩包
allow_url_fopen :off/on
allow_url_include:off/on
格式:compress.zlib://file.gz

经过测试官方文档上存在一处问题,经过测试PHP版本5.2,5.3,5.5,7.0;data:// 协议是是受限于allow_url_fopen的,官方文档上给出的是NO,所以要使用data://协议需要满足双on条件
data://协议必须双在on才能正常使用;
allow_url_fopen :on
allow_url_include:on

格式:
data://text/plain,[php语句]
data://text/plain;base64,[base64编码后的php语句
例如
http://127.0.0.1/cmd.php?file=data://text/plain,
or
http://127.0.0.1/cmd.php?file=data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
也可以:
http://127.0.0.1/cmd.php?file=data:text/plain,
or
http://127.0.0.1/cmd.php?file=data:text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
PD9waHAgcGhwaW5mbygpPz4=是base64编码过后的一句话

测试:


注意:
1、每个协议allow_url_fopen 与allow_url_include 要求不同。要保证配置满足要求
2、文件或压缩包对应的关键字要一致
3、保证环境有对应功能环境配置
总所周知日志记录了用户的所有操作。为此我们可以把恶意语句放入到日志中。利用日志的恶意语句进行文件包含漏洞注入木马。

查看日志

看见日志发现<的非法字符被转码了,无法显示。为此我们将其拦截修改

refer修改编码后的语句


修改成功

应用文件

成功显示