浅谈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 相关文章推荐
使用adodb lite解决问题
Dec 31 PHP
Thinkphp搭建包括JS多语言的多语言项目实现方法
Nov 24 PHP
php+mysqli使用预处理技术进行数据库查询的方法
Jan 28 PHP
php集成套件服务器xampp安装使用教程(适合第一次玩PHP的新手)
Jun 03 PHP
php并发加锁示例
Oct 17 PHP
php读取qqwry.dat ip地址定位文件的类实例代码
Nov 15 PHP
php 中奖概率算法实现代码
Jan 25 PHP
php输出图像的方法实例分析
Feb 16 PHP
safari下载文件自动加了html后缀问题
Nov 09 PHP
浅谈PHP无限极分类原理
Mar 14 PHP
PHP中__set()实例用法和基础讲解
Jul 23 PHP
tp5框架前台无限极导航菜单类实现方法分析
Mar 29 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
php db类库进行数据库操作
2009/03/19 PHP
制作安全性高的PHP网站的几个实用要点
2014/12/30 PHP
php编程中echo用逗号和用点号连接的区别
2016/03/26 PHP
jQuery.get、jQuery.getJSON、jQuery.post无法返回JSON问题的解决方法
2011/07/28 Javascript
js获取客户端网卡的IP地址、MAC地址
2014/03/26 Javascript
javascript中的循环语句for语句深入理解
2014/04/04 Javascript
window.onload与$(document).ready()的区别分析
2015/05/30 Javascript
Bootstrap每天必学之工具提示(Tooltip)插件
2016/04/26 Javascript
深入理解JavaScript中的浮点数
2016/05/18 Javascript
JS实现控制文本框的内容
2016/07/10 Javascript
jQuery Masonry瀑布流插件使用方法详解
2017/01/18 Javascript
vue使用axios跨域请求数据问题详解
2017/10/18 Javascript
js实现数组内数据的上移和下移的实例
2017/11/14 Javascript
JQuery 又谈ajax局部刷新
2017/11/27 jQuery
在vue中,v-for的索引index在html中的使用方法
2018/03/06 Javascript
JavaScript实现shuffle数组洗牌操作示例
2019/01/03 Javascript
微信小程序实现的日期午别医生排班表功能示例
2019/01/09 Javascript
[01:21]2018DOTA2亚洲邀请赛4.5采访 打DOTA2也能有女朋友?
2018/04/06 DOTA
[42:52]IG vs VGJ.T 2018国际邀请赛小组赛BO2 第二场 8.18
2018/08/19 DOTA
[48:24]完美世界DOTA2联赛循环赛LBZS vs Forest 第一场 10月30日
2020/10/31 DOTA
Python变量和数据类型详解
2017/02/15 Python
浅谈Django+Gunicorn+Nginx部署之路
2019/09/11 Python
keras和tensorflow使用fit_generator 批次训练操作
2020/07/03 Python
CSS3 Flex 弹性布局实例代码详解
2018/11/01 HTML / CSS
CSS3 旋转立方体问题详解
2020/01/09 HTML / CSS
html5指南-7.geolocation结合google maps开发一个小的应用
2013/01/07 HTML / CSS
canvas需要在标签里直接定义宽高
2014/12/17 HTML / CSS
沪江旗下的海量优质课程平台:沪江网校
2017/11/07 全球购物
分公司经理岗位职责
2013/11/11 职场文书
公司财务自我评价分享
2013/12/17 职场文书
银行求职信范文
2014/05/26 职场文书
学校搬迁方案
2014/06/15 职场文书
教学改革问题查摆整改措施
2014/09/27 职场文书
2016年社会管理综治宣传月活动总结
2016/03/16 职场文书
游戏开发中如何使用CocosCreator进行音效处理
2021/04/14 Javascript
Python编写nmap扫描工具
2021/07/21 Python