手机版

谈PHP ://滤镜的妙用

时间:2021-08-27 来源:互联网 编辑:宝哥软件园 浏览:

Php ://过滤器是PHP中一个独特的协议。使用这个协议可以创造许多“奇妙的用途”。这篇文章会讲一些有趣的点,剩下的大家自己体会。本来打算用这篇文章的思路作为上半年XDCTF2016的话题,没想到被三个白帽子中的一个先用了,只好提前分享了。

在XXE使用

XXE是php://filter之前最受欢迎的地方。由于XXE漏洞的特殊性,在读取HTML、PHP等文件时,我们可能会抛出解析器错误: starttag 3360无效元素名等错误。原因是PHP是一种基于标签的脚本语言。服务器端编程语言(Professional Hypertext Preprocessor的缩写).这种语法也与XML一致,所以在解析XML时,会被误认为是XML,其内容(如特殊字符)可能与标准的XML冲突,从而导致错误。

然后,为了读取PHP和其他包含敏感信息的源文件,我们必须先对“可能导致冲突的PHP代码”进行编码,这里将使用php://filter。

Php://filter是Php语言中特有的协议流,作为“中间流”来处理其他流。例如,我们可以使用以下代码行将POST内容转换为base64编码并输出:

read file(' PHP ://filter/read=convert . base64-encode/resource=PHP ://input ');

如下所示:

所以在XXE我们也可以处理PHP等容易与PHP 3360//Filter协议流冲突的文件流,有效避免特殊字符带来的混乱。

如下所示,我们使用PHP ://filter/read=convert . base64-encode/resource=。/xxe.php。

编码和解码的巧妙运用

使用编码不仅可以帮助我们获取文件,还可以帮助我们摆脱一些“不必要的麻烦”。

我记得前一段时间三个白帽子有个比赛,有些代码大概和下面的差不多:

?php$content='?php退出;';$内容。=$ _ POST[' txt '];file _ put _ contents($ _ POST[' filename '],$ content);$content在开头增加了一个退出过程,导致我们即使成功写了一个字,也无法执行(这个过程在实战中非常常见,通常出现在缓存、配置文件等中。不允许用户直接访问的文件将使用if(!defined(xxx))退出;等等)。那么在这种情况下,如何绕过这个“死亡出口”呢?

好在这里的$_POST['filename']可以控制协议,所以我们可以使用php://filter协议施展魔法:使用PHP 3360//filter stream的base64-decode方法解码$content,使用php base64_decode函数去除“死亡退出”。

众所周知,base64编码只包含64个可打印字符。当PHP解码base64时,它将跳过这些字符,只将合法字符组成一个新的字符串进行解码。

因此,正常的base64_decode实际上可以理解为以下两个步骤:

?PHP $ _ get[' txt ']=preg_replace('|[^a-z0-9a-z/]| s ','',$ _ get[' txt ']);base64 _ decode($ _ GET[' txt ']);那么,当添加$content时?php退出;以后我们可以用PHP ://filter/write=convert . base64-decode先解码。在解码过程中,人物,共7个字符,如、空格等。不符合base64编码的字符将被忽略,因此,唯一要解码的字符是“phpexit”和我们传入的其他字符。

“phpexit”共有7个字符。因为base64算法以4个字节为一组进行解码,所以会在其中添加一个总共8个字符的“A”。这样,‘phpexita’被正常解码,我们后面介绍的webshell的base64内容也被正常解码。结果是?php退出;它不见了。

最后的效果是:

使用字符串操作方法

有同学说,我不懂base64算法,上面的方法太复杂了。

其实除了使用base64特性之外,我们还可以使用PHP ://过滤字符串的处理方法来去除“死亡退出”。让我们看看,这个?php退出;到底是什么?

其实是一个XML标签,既然是XML标签,我们可以用strip_tags函数去掉,php://filter正好支持这个方法。

编写以下测试代码来检查PHP ://filter/read=string . strip _ tags/resource=PHP ://input的效果:

echo read file(' PHP ://filter/read=string . strip _ tags/resource=PHP ://input ');

可见,php退出;已被移除。但是回到上面的主题,我们的最终目标是编写一个webshell,并且编写的webshell也是php代码,如果使用strip_tags,也将删除该代码。

幸运的是,php://filter允许多个过滤器,所以我们可以先用base64编码webshell。调用strip_tags后进行base64解码。第一步删除“死亡出口”,第二步恢复webshell。

最后一个数据包如下:

此外,我们可以使用rot13编码独立完成任务。原理和上面差不多,核心是去掉“死亡出口”。php退出;被rot13编码后,会变成?cuc rkvg?当php没有打开short_open_tag时,PHP不知道这个字符串,当然也不会执行它:

当然,这个方法的条件是不要打开短标签。

这就是对php://filter妙用的所有质疑。谢谢你的支持。

版权声明:谈PHP ://滤镜的妙用是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。

相关文章推荐