php://filter是PHP中独有的一种协议,它是一种过滤器,可以作为一个中间流来过滤其他的数据流。通常使用该协议来读取或者写入部分数据,且在读取和写入之前对数据进行一些过滤,例如base64编码处理,rot13处理等。官方解释为:php://filter 是一种元封装器,设计用于数据流打开时的筛选过滤应用。
php://data协议是PHP中的一种特殊协议,可以在包含函数中被用来执行一些特殊的操作。它没有条件限制,但仅能用于在CTF(Capture The Flag)中读取本地文件,且不受allow_url_fopen与allow_url_include的影响。
php://input是PHP提供的一个伪协议,允许开发者访问POST请求的原始内容。它是一个只读流,可以获取POST请求数据的协议。当enctype="multipart/form-data"时, php://input是无效的。
出题人:末心
题目难度:★
题目描述:你能否获取Flag呢,flag格式为:qsnctf{xxx}。
error_reporting(0);
if (isset($_GET['file'])) {
if (!strpos($_GET["file"], "flag")) {
include $_GET["file"];
} else {
echo "Hack!!!";
}
} else {
highlight_file(__FILE__);
}
?>
<hr>
你能否获取Flag?<br>
<a href="hello.php">hello</a>
你能否获取Flag?
hello
PHP代码审计
1.给了一个参数file
2.strpos函数用来查找flag在字符串中第一次出现的位置
3.!是取反就是相反的意思 如果存在flag关键字那么就会显示Hack!!!
那么简单来说就是我们的flag关键字被过滤了!
绕过方式也有很多种 这里就主要通过字符来绕过这个flag关键字过滤
filter伪协议
查看index.php的内容
并将其内容以base64编码形式显示出来
?file=php://filter/read=convert.base64-encode/resource=index.php
解码之后也就是题目的源码
查看flag的内容
并将其内容以base64编码显示出来
使用*号绕过flag关键字过滤 意为查看f开头的所有文件
?file=php://filter/read=convert.base64-encode/resource=f*
没有显示任何内容
显然filter协议是不适合这道题目的
data伪协议
第一种解法
使用data协议获取本地内容
phpinfo()打开PHP配置信息
成功执行
Ctrl+F搜索flag在配置信息中的位置
在第五条信息中发现了flag的存在
第二种解法
使用data伪协议获取本地内容
并且调用外部执行命令
system外部执行命令
列出根目录下的所有目录以及文件
bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var
在根目录下发现了flag文件的存在
查看根目录下的flag文件内容
f*代表f开头的所有文件
因为根目录下只有flag这一个f开头的文件 所以查看的就是flag文件的内容咯
input伪协议
需要的工具
火狐浏览器
Max HacKBar插件
第一种解法
访问POST请求的原始内容
phpinfo()查看PHP的配置信息
URL网页链接就是GET请求数据
?file=php://input
POST请求数据
成功执行
Ctrl+F搜索flag在配置信息中的位置
在第五条信息中发现了flag的存在
第二种解法
使用input伪协议访问POST请求的原始内容
并且调用外部执行命令
system外部执行命令
URL网页链接就是GET请求数据
?file=php://input
POST请求数据
列出根目录下的所有目录以及文件
bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var
在根目录下发现flag文件的存在
查看根目录下的flag文件内容
通过fl\ag绕过flag关键字过滤
GET请求数据不用管了
POST请求数据
得到flag:qsnctf{5f6cef0f-f83c-4b60-a0a8-e97c755ae457}
出题人:末心
题目难度:★
题目描述:这道题修改了一些东西哦!你还能做出来吗,flag格式为:qsnctf{xxx}。
禁用了input伪协议
输入框随便输入值进入check.php界面
删除file参数查看check.php源代码
error_reporting(0);
if (isset($_GET['file'])) {
if (!strpos($_GET["file"], "input") && !strpos($_GET["file"], "flag")) {
include $_GET["file"];
} else {
echo "Hack!!!";
}
} else {
highlight_file(__FILE__);
}
?>
<hr>
你能否获取Flag?<br>
<a href="hello.php">hello</a>
你能否获取Flag?
hello
PHP代码审计
相比include01 这道题目多增加了一个过滤
过滤了input关键字 进而导致input伪协议不能使用
filter伪协议
查看flag的内容
并将其内容以base64编码形式显示出来
f???代替flag
意思是文件名f开头并且文件名是4位的文件
?file=php://filter/read=convert.base64-encode/resource=f???
filter伪协议依旧是不适用此题目
由于input关键字被过滤导致input伪协议不能使用
就直接使用data伪协议了
data伪协议
第一种解法
使用data伪协议获取本地内容
phpinfo()打开PHP配置信息
成功执行
Ctrl+F搜索flag在配置信息中的位置
在第五条信息中发现了flag
第二种解法
使用data协议获取本地内容
并且调用外部执行命令
system外部执行命令
列出根目录下的所有目录以及文件
bin dev etc flag home lib media mnt opt proc root run sbin srv sys tmp usr var
在根目录下发现了flag文件的存在
查看根目录下的flag文件内容
f???代替flag
意思是文件名f开头并且文件名是4位的文件
得到flag:qsnctf{0ed8d987-ba51-490e-9775-e0974ccf0a06}