目录
文件包含漏洞概述
文件包含漏洞的环境要求
常见文件包含函数
php的伪协议
file://协议
php://filter协议
php://input协议
压缩伪协议
zip://协议
bzip://
zlib://
data://协议
总结
文件包含漏洞概述
通过PHP函数引入文件时,传入的文件名没有经过合理的验证,从而操作了预想之外的文件,就可能导致意外的文件泄漏甚至恶意代码注入。
文件包含漏洞的环境要求
-
allow_url_fopen=On(默认为On) 规定是否允许从远程服务器或者网站检索数据
-
allow_url_include=On(php5.2之后默认为Off) 规定是否允许include/require远程文件
常见文件包含函数
php中常见的文件包含函数有以下四种:
-
include()
-
require()
-
include_once()
-
require()_once()
include与require基本是相同的,除了错误处理方面:
-
include(),只生成警告(E_WARNING),并且脚本会继续
-
require(),会生成致命错误(E_COMPILE_ERROR)并停止脚本
-
include_once()与require()_once(),如果文件已包含,则不会包含,其他特性如上
php的伪协议
先了解下一些封装协议,涉及的相关协议:file://、php://filter、php://input、zip://、compress.bzip2://、compress.zlib://、data://等内容。
注意如果直接访问一个写有<?php phpinfo(); ?>
的txt文件,一般是解析不了的。
但是如果我们以文件包含来运行,是可以正常识别的.因为文件包含会将所以的内容全部识别为php文件进行执行。
file://
协议
file:// 用于访问本地文件系统,在CTF中通常用来读取本地文件的且不受allow_url_fopen与allow_url_include的影响。
即在php.ini的两个参数allow_url_fopen:off/on
和allow_url_include:off/on
如果限制,即两个参数都为OFF,我们依然可以使用这个伪协议去读取文件,前提是需要知道文件的物理路径。
我们也可以在后面加上网站地址的文件http://网络路径和文件名
php://filter
协议
php:// 访问各个输入/输出流(I/O streams),在CTF中经常使用的是php://filter和php://input,php://filter用于读取源码,php://input用于执行php代码。详细请参考官方的php://filter协议。
这个协议在php.ini的两个参数allow_url_fopen:off/on
和allow_url_include:off/on
如果限制,即两个参数都为OFF,我们依然可以使用这个伪协议。
php://filter 读取源代码并进行base64编码输出,不然会直接当做php代码执行就看不到源代码内容了。
<span style="background-color:#f8f8f8"><span style="color:#333333"> ?file=php://filter/read=convert.base64-encode/resource=./1.php一个点表示当前目录下</span></span>
php://input
协议
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。并且可以接收数据。可以接收文件。
这个存在限制需要PHP.ini
配置文件中的参数allow_url_fopen :off/on
和allow_url_include:on
中的allow_url_include
参数保持开启。一般情况下默认是关闭的。
通过burpsuite抓包软件演示如下,很容易写一句话木马<?php fputs(fopen(“shell.php”,”w”),’<?php eval($_POST["cmd"];?>’);?>
压缩伪协议
zip://, bzip2://, zlib://
均属于压缩流,可以访问压缩文件中的子文件,更重要的是不需要指定后缀名。这几个协议在php.ini的两个参数allow_url_fopen:off/on
和allow_url_include:off/on
如果限制,即两个参数都为OFF,我们依然可以使用。
具体请参考官方文档zlib://、bzip2://、zip://。
zip://
协议
使用方法:
zip://archive.zip#dir/file.txtzip:// [压缩文件绝对路径]#[压缩文件内的子文件名]
先将要执行的PHP代码写好文件名为phpcode.txt,将phpcode.txt进行zip压缩,压缩文件名为file.zip,如果可以上传zip文件便直接上传,若不能便将file.zip重命名为file.jpg后在上传,其他几种压缩格式也可以这样操作。
由于#在get请求中会将后面的参数忽略所以使用get请求时候应进行url编码为%23,且此处经过测试相对路径是不可行,所以只能用绝对路径。
压缩文件后缀可以修改,修改后上传。但是要注意对文件直接压缩,不要直接连着目录压缩,否则会多一个目录。
bzip://
使用方法:
compress.bzip2://file.bz2
测试现象:
使用的时候格式如下?file=compress.bzip2://./file.jpg
zlib://
使用方法:
compress.zlib://file.gz
测试现象:
使用的时候格式如下?file=compress.zlib://D:/soft/phpStudy/WWW/file.jpg
data://
协议
经过测试官方文档上存在一处问题,经过测试PHP版本5.2,5.3,5.5,7.0;data:// 协议是是受限于allow_url_fopen的,官方文档上给出的是NO,所以要使用data://协议需要满足双on条件.
利用条件相当苛刻,基本上使用不到。
参考自:PHP: data:// - Manual, 官方文档上allow_url_fopen应为yes。
总结
PHP封装协议在CTF蛮常见的,是经常会遇到的出题点。