【转】浅谈php://filter的妙用
php://filter是PHP中独有的协议,利用这个协议可以创造很多“妙用”,本文说几个有意思的点,剩下的大家自己下去体会。
XXE中的使用
php://filter之前最常出镜的地方是XXE。由于XXE漏洞的特殊性,我们在读取HTML、PHP等文件时可能会抛出此类错误parser error : StartTag: invalid element name
。其原因是,PHP是基于标签的脚本语言,<?php ... ?>
这个语法也与XML相符合,所以在解析XML的时候会被误认为是XML,而其中内容(比如特殊字符)又有可能和标准XML冲突,所以导致了出错。
那么,为了读取包含有敏感信息的PHP等源文件,我们就要先将“可能引发冲突的PHP代码”编码一遍,这里就会用到php://filter。
php://filter是PHP语言中特有的协议流,作用是作为一个“中间流”来处理其他流。比如,我们可以用如下一行代码将POST内容转换成base64编码并输出:
readfile("php://filter/read=convert.base64-encode/resource=php://input");
如下:
所以,在XXE中,我们也可以将PHP等容易引发冲突的文件流用php://filter协议流处理一遍,这样就能有效规避特殊字符造成混乱。
如下,我们使用的是php://filter/read=convert.base64-encode/resource=./xxe.php
巧用编码与解码
使用编码不光可以帮助我们获取文件,也可以帮我们去除一些“不必要的麻烦”。
记得前段时间三个白帽有个比赛,其中有一部分代码大概类似于以下:
<?php $content = '<?php exit; ?>'; $content .= $_POST['txt']; file_put_contents($_POST['filename'], $content);
$content
在开头增加了exit过程,导致即使我们成功写入一句话,也执行不了(这个过程在实战中十分常见,通常出现在缓存、配置文件等等地方,不允许用户直接访问的文件,都会被加上if(!defined(xxx))exit;之类的限制)。那么这种情况下,如何绕过这个“死亡exit”?
幸运的是,这里的$_POST['filename']
是可以控制协议的,我们即可使用 php://filter协议来施展魔法:使用php://filter流的base64-decode方法,将$content
解码,利用php base64_decode函数特性去除“死亡exit”。
众所周知,base64编码中只包含64个可打印字符,而PHP在解码base64时,遇到不在其中的字符时,将会跳过这些字符,仅将合法字符组成一个新的字符串进行解码。
所以,一个正常的base64_decode实际上可以理解为如下两个步骤:
<?php $_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; ?>
没有了。
最后效果是 :
利用字符串操作方法
有的同学说,base64的算法我不懂,上面的方法太复杂了。
其实,除了使用base64特性的方法外,我们还可以利用php://filter字符串处理方法来去除“死亡exit”。我们观察一下,这个<?php exit; ?>
实际上是什么?
实际上是一个XML标签,既然是XML标签,我们就可以利用strip_tags函数去除它,而php://filter刚好是支持这个方法的。
编写如下测试代码即可查看 php://filter/read=string.strip_tags/resource=php://input 的效果:
echo readfile('php://filter/read=string.strip_tags/resource=php://input');
可见,<?php exit; ?>
被去除了。但回到上面的题目,我们最终的目的是写入一个webshell,而写入的webshell也是php代码,如果使用strip_tags同样会被去除。
万幸的是,php://filter允许使用多个过滤器,我们可以先将webshell用base64编码。在调用完成strip_tags后再进行base64-decode。“死亡exit”在第一步被去除,而webshell在第二步被还原。
最终的数据包如下:
除此之外,我们还可以利用rot13编码独立完成任务。原理和上面类似,核心是将“死亡exit”去除。<?php exit; ?>
在经过rot13编码后会变成<?cuc rkvg; ?>
,在PHP不开启short_open_tag时,php不认识这个字符串,当然也就不会执行了:
当然,这个方法的条件就是不开启短标签。
您可以考虑给博主来个小小的打赏以资鼓励,您的肯定将是我最大的动力。thx.
微信打赏
支付宝打赏
作 者: Angel_Kitty
出 处:http://www.cnblogs.com/ECJTUACM-873284962/
关于作者:潜心机器学习以及信息安全的综合研究。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信我
声援博主:如果您觉得文章对您有帮助,可以点击右下角【推荐】推荐一下该博文。您的鼓励是作者坚持原创和持续写作的最大动力!
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
拯救 Java 开发者,用 Docker 将 Java 应用进行现代化改造(四)
本文首发自“Docker公司”公众号(ID:docker-cn)编译丨小东每周一、三、五 与您不见不散! 将整体应用程序迁移到现代化的云架构上可能会十分困难,而且对于开发人员来说往往需要花费额外的精力来开展这项工作。但是,当使用 Docker EE 时,开发人员就可以在整个的迁移过程中,享受 Docker 所带来的可移植性、安全性和高效性,并且无需花费额外的精力来修改代码。 系列视频的第四部分利用了我在第三部分中增加的消息服务功能。在本部分中,我将添加由开源的 Elasticsearch / Kibana 应用栈提供的自助式分析功能。报告数据库和分析界面运行在容器中,并更新了工作节点将数据存储在 Elasticsearch 中。Docker 平台支持在运行部署过程中为应用程序添加新组件,并且无需关闭当前正在运行应用程序的容器。您将了解到 Docker 是如何在生产环节中让您在零宕机的情况下为应用程序添加新功能,详情请从以下渠道观看完整视频: Docker官方微信公众号入口:https://mp.weixin.qq.com/s?__biz=MzI0OTg4NTE3Ng==&mid...
- 下一篇
JavaScript中的单引号和双引号
JavaScript中的单引号和双引号 今天来聊一聊单引号和双引号在JavaScript中的使用,做web的经常会在HTML中或者JavaScript中拼接字符串,这个时候就会用到单引号与双引号混合使用,如果使用不当还会造成意想不到的bug。 单引号和双引号都可以作为字符串的开始符和关闭符,并且只能同一种单或者双引号来定义开始和结束; 在同一种引号中使用相同的引号,需要转义后才能使用。不同引号可以嵌套使用。 下面就来聊一聊这些小细节。 首先,描述一下,具体的应用场景。 第一:从后台界面传递的数据在HTML或者jsp页面展示的时候,我们可能把这些数据直接展示,又或者以变量的形式传递给js函数。 第二:我们用到ajax的时候,从后端异步获取数据,需要把这些数据结合HTML标签CSS属性拼接在一起,然后斧子给某个标签在页面上展示。 具体来说一些这些应用场景。 第一:在HTML或者Jsp中使用 有一个需求,在后台传递一个List集合的数据将要在前台页面展示 前台页面 我们看onclick="test('${str}')"我们给js函数test()需要传递一个参数,这个时候就需要用到双引号中嵌...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- CentOS7,CentOS8安装Elasticsearch6.8.6
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Linux系统CentOS6、CentOS7手动修改IP地址
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS7编译安装Cmake3.16.3,解决mysql等软件编译问题
- SpringBoot2全家桶,快速入门学习开发网站教程
- CentOS7设置SWAP分区,小内存服务器的救世主
- Docker快速安装Oracle11G,搭建oracle11g学习环境