[SWPUCTF 2021 新生赛]PseudoProtocols
尝试直接访问hint.php,发现并没有效果
联想到题目为PseudoProtocols(伪协议),尝试使用伪协议
php://filter
参数详解
该协议的参数会在该协议路径上进行传递,多个参数都可以在一个路径上传递。具体参考如下:
php://filter 参数 | 描述 | |
---|---|---|
resource=<要过滤的数据流> | 必须项。它指定了你要筛选过滤的数据流。 | |
read=<读链的过滤器> | 可选项。可以设定一个或多个过滤器名称,以管道符( )分隔。 | |
write=<写链的过滤器> | 可选项。可以设定一个或多个过滤器名称,以管道符( )分隔。 | |
<; 两个链的过滤器> | 任何没有以 read= 或 write= 作前缀的筛选器列表会视情况应用于读或写链。 |
php://filter可以获取指定文件源码。当它与包含函数结合时,php://filter流会被当作php文件执行。所以我们一般对其进行编码,让其不执行。利用filter协议读文件,例如将index.php通过base64编码后进行输出。这样做的好处就是如果不进行编码,文件包含后就不会有输出结果,而是当做php文件执行了,而通过编码后则可以读取文件源码。
示例:php://filter/read=convert.base64-encode/resource=[文件名]
读取文件源码(针对php文件需要base64编码)
其中使用的convert.base64-encode,起到过滤作用。
尝试使用http://node4.anna.nssctf.cn:28736/index.php?wllm=php://filter/read=convert.base64-encode/resource=hint.php得到经过base64编码后的hint.php源码
成功获取
将源码进行base64解码
提示进入test2222222222222.php
修改url,访问test2222222222222.php
观察代码功能:
isset($a)
: 这个函数检查变量$a
是否已设置且不为null。
file_get_contents($a,'r')
: 这个函数尝试从由$a
指定的文件路径中读取文件内容。第二个参数'r'
是模式,表示“读取模式”。
===
: 这部分检查从文件中读取的内容是否严格等于字符串'I want flag'
。
file_get_contents() 把整个文件读入一个字符串中。
该函数是用于把文件的内容读入到一个字符串中的首选方法。如果服务器操作系统支持,还会使用内存映射技术来增强性能。
语法
file_get_contents(path,include_path,context,start,max_length)
参数 描述 path 必需。规定要读取的文件。 include_path 可选。如果您还想在 include_path(在 php.ini 中)中搜索文件的话,请设置该参数为 '1'。 context 可选。规定文件句柄的环境。context 是一套可以修改流的行为的选项。若使用 NULL,则忽略。 start 可选。规定在文件中开始读取的位置。该参数是 PHP 5.1 中新增的。 max_length 可选。规定读取的字节数。该参数是 PHP 5.1 中新增的。
此处的关键在于$a如何以文件的形式存放'I want flag',联想到另一个PHP伪协议
data://协议
条件:
allow_url_fopen
:on
allow_url_include
:on
作用:自PHP>=5.2.0
起,可以使用data://
数据流封装器,以传递相应格式的数据。通常可以用来执行PHP代码。
用法:
data://text/plain,
data://text/plain;base64,xxxx (如果此处对某些字符进行了过滤,可以通过base64编码后再输入)
最终构造payload为:
http://node4.anna.nssctf.cn:28736/test2222222222222.php?a=data://text/plain,I want flag
得到flag
NSSCTF{c1783960-8b0c-4bc6-ac17-13a5f2d6a887}