浅谈php://filter的妙用


Posted in PHP onMarch 05, 2019

php://filter是PHP中独有的协议,利用这个协议可以创造很多“妙用”,本文说几个有意思的点,剩下的大家自己下去体会。本来本文的思路我上半年就准备拿来做XDCTF2016的题目的,没想到被三个白帽的一题抢先用了,我也就只好提前分享一下。

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");

如下:

浅谈php://filter的妙用

所以,在XXE中,我们也可以将PHP等容易引发冲突的文件流用php://filter协议流处理一遍,这样就能有效规避特殊字符造成混乱。

如下,我们使用的是php://filter/read=convert.base64-encode/resource=./xxe.php

浅谈php://filter的妙用

巧用编码与解码

使用编码不光可以帮助我们获取文件,也可以帮我们去除一些“不必要的麻烦”。

记得前段时间三个白帽有个比赛,其中有一部分代码大概类似于以下:

<?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; ?>没有了。

最后效果是 :

浅谈php://filter的妙用

利用字符串操作方法

有的同学说,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://filter的妙用

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

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

最终的数据包如下:

浅谈php://filter的妙用

除此之外,我们还可以利用rot13编码独立完成任务。原理和上面类似,核心是将“死亡exit”去除。<?php exit; ?>在经过rot13编码后会变成<?cuc rkvg; ?>,在PHP不开启short_open_tag时,php不认识这个字符串,当然也就不会执行了:

浅谈php://filter的妙用

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

以上就是关于php://filter的妙用的疑惑全部内容,感谢大家对三水点靠木的支持。

PHP 相关文章推荐
攻克CakePHP系列三 表单数据增删改
Oct 22 PHP
php set_time_limit(0) 设置程序执行时间的函数
May 26 PHP
利用php绘制饼状图的实现代码
Jun 07 PHP
解析PHP处理换行符的问题 \r\n
Jun 13 PHP
用php简单实现加减乘除计算器
Jan 06 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(六)
Jun 23 PHP
函数中使用require_once问题深入探讨 优雅的配置文件定义方法推荐
Jul 02 PHP
推荐25款php中非常有用的类库
Sep 29 PHP
PHP正则表达式匹配替换与分割功能实例浅析
Feb 04 PHP
PHP中快速生成随机密码的几种方式
Apr 17 PHP
PHP实现的函数重载功能示例
Aug 03 PHP
ThinkPHP5+Layui实现图片上传加预览功能
Aug 17 PHP
PHP实现微信小程序用户授权的工具类示例
Mar 05 #PHP
统计PHP目录中的文件数方法
Mar 05 #PHP
PHP常见字符串操作函数与用法总结
Mar 04 #PHP
php+Ajax处理xml与json格式数据的方法示例
Mar 04 #PHP
php+Ajax无刷新验证用户名操作实例详解
Mar 04 #PHP
实例介绍PHP删除数组中的重复元素
Mar 03 #PHP
PHP+Ajax简单get验证操作示例
Mar 02 #PHP
You might like
ninety plus是什么?ninety plus咖啡好吗?
2021/03/04 新手入门
采用header定义为文件然后readfile下载(隐藏下载地址)
2014/01/31 PHP
php中call_user_func函数使用注意事项
2014/11/21 PHP
PHP实现过滤掉非汉字字符只保留中文字符
2015/06/04 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
2016/09/22 PHP
简单谈谈PHP面向对象之标识对象
2017/06/27 PHP
Laravel自动生成UUID,从建表到使用详解
2019/10/24 PHP
Laravel框架使用技巧之使用url()全局函数返回前一个页面的地址方法详解
2020/04/06 PHP
javascript类继承机制的原理分析
2009/09/12 Javascript
Javascript 面向对象 继承
2010/05/13 Javascript
js parseInt(&quot;08&quot;)未指定进位制问题
2010/06/19 Javascript
Js判断CSS文件加载完毕的具体实现
2014/01/17 Javascript
javasctipt如何显示几分钟前、几天前等
2014/04/30 Javascript
js仿微博实现统计字符和本地存储功能
2015/12/22 Javascript
需灵活掌握的Bootstrap预定义排版类 你精通吗?
2016/06/20 Javascript
微信小程序实现星星评价效果
2018/11/02 Javascript
简单易扩展可控性强的Jquery转盘抽奖程序
2019/03/16 jQuery
jquery分页优化操作实例分析
2019/08/23 jQuery
微信小程序服务器日期格式化问题
2020/01/07 Javascript
[01:19:11]Ti4 循环赛第二日 NaVi.us vs iG
2014/07/11 DOTA
跟老齐学Python之list和str比较
2014/09/20 Python
Python3.x版本中新的字符串格式化方法
2015/04/24 Python
50行Python代码实现人脸检测功能
2018/01/23 Python
python实现字符串和字典的转换
2018/09/29 Python
python读取文件名并改名字的实例
2019/01/07 Python
Keras使用tensorboard显示训练过程的实例
2020/02/15 Python
keras实现多种分类网络的方式
2020/06/11 Python
使用CSS3制作饼状旋转载入效果的实例
2015/06/23 HTML / CSS
网友共享的几个面试题关于Java和Unix等方面的
2016/09/08 面试题
教师个人剖析材料
2014/02/05 职场文书
档案室主任岗位职责
2014/02/12 职场文书
2014年学生会工作总结范文
2014/11/07 职场文书
工作失职检讨书范文
2015/05/05 职场文书
幼儿园六一主持词开场白
2015/05/28 职场文书
小学生读书笔记范文
2015/06/30 职场文书
男方家长婚礼答谢词
2015/09/29 职场文书