php://filter利用条件,浅谈php://filter技巧

php://filter

php://filter可以作为一个中间流来处理其他流,具有四个参数:

名称

描述

备注

resource=

指定了你要筛选过滤的数据流

必选

read=

可以设定一个或多个过滤器名称,以管道符(|)分隔。

可选

write=

可以设定一个或多个过滤器名称,以管道符(|)分隔。

可选

任何没有以 read= 或 write= 作前缀的筛选器列表会视情况应用于读或写链。

巧用编码与解码

$content = '<?php exit; ?>';

$content .= $_POST['txt'];

file_put_contents($_POST['filename'], $content);

$content在开头增加了exit过程,导致即使成功写入一句话,也执行不了(这个过程在实战中十分常见,通常出现在缓存、配置文件等等地方,不允许用户直接访问的文件,都会被加上if(!defined(xxx))exit;之类的限制)。

但是这里的$_POST['filename']是可以控制协议的,可以使用php://filter流的base64-decode方法,将$content解码,利用php base64_decode函数特性绕过。

base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。

一个正常的base64_decode实际上可以理解为如下两个步骤:

$_GET['txt'] = preg_replace('|[^a-z0-9A-Z+/]|s', '', $_GET['txt']);

base64_decode($_GET['txt']);

所以,当$content被加上了<?php exit; ?>以后,我们可以使用 php://filter/write=convert.base64-decode 来首先对其解码。在解码的过程中,字符、空格等一共有7个字符不符合base64编码的字符范围将被忽略,所以最终被解码的字符仅有“phpexit”和我们传入的其他字符。

“phpexit”一共7个字符,因为base64算法解码时是4个byte一组,所以给他增加1个“a”一共8个字符。这样,"phpexita"被正常解码,而后面我们传入的webshell的base64内容也被正常解码。结果就是<?php exit; ?>没有了。

pyload:

txt=aPD9waHAgcGhwaW5mbygpOyA/Pg==&filename=php://filter/write=convert.base64-decode/resource=shell.php

f99a297d11227beefbd7eb8cb3f29c87.png

利用字符串操作方法

<?php exit; ?>实际上是一个XML标签,既然是XML标签,我们就可以利用strip_tags函数去除它,而php://filter刚好是支持这个方法的。

29a20bef61015788a686bf1af3cb31b9.png

编写如下测试代码即可查看 php://filter/read=string.strip_tags/resource=php://input的效果:

echo readfile('php://filter/read=string.strip_tags/resource=php://input');

f3078dfc3c34899afc594d8e568b0521.png

可见,<?php exit; ?>被去除了。但回到上面的题目,我们最终的目的是写入一个webshell,而写入的webshell也是php代码,如果使用strip_tags同样会被去除。

万幸的是,php://filter允许使用多个过滤器,我们可以先将webshell用base64编码。在调用完成strip_tags后再进行base64-decode。<?php exit; ?>在第一步被去除,而webshell在第二步被还原。

最终的数据包如下:

pyload:

txt=PD9waHAgcGhwaW5mbygpOyA/Pg==&filename=php://filter/write=string.strip_tages | convert.base64-decode/resource=shell.php

d0d621c03d39578cf1b67f9cb93d457d.png

利用rot13操作方法

原理和上面类似,核心是将“死亡exit”去除。<?php exit; ?>在经过rot13编码后会变成<?cuc rkvg; ?>,在PHP不开启short_open_tag时,php不认识这个字符串,当然也就不会执行了:

0f17f3371e6d48aef7701f34c36f349e.png

pyload:

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

69b267b7c709287c4abdec5b78b70fff.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值