用户
搜索
  • TA的每日心情
    奋斗
    2020-12-3 11:56
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]初来乍到

    i春秋-见习白帽

    Rank: 3Rank: 3

    8

    主题

    31

    帖子

    390

    魔法币
    收听
    1
    粉丝
    1
    注册时间
    2017-12-25
    发表于 2020-12-9 15:05:00 719748
    打开题目,我们可以看到的是这样一个页面
    1.png
    2.png
    3.png
    4.png



    当我看到unserialize的时候 我知道了 这是一道PHP反序列化的题目了
    在这里我先说一下反序列化的常年事故,借用一下freebuf的文章:
    什么是反序列化:
    php程序为了保存和转储对象,提供了序列化的方法,php序列化是为了在程序运行的过程中对对象进行转储而产生的。序列化可以将对象转换成字符串,但仅保留对象里的成员变量,不保留函数方法。
    php序列化的函数为serialize。反序列化的函数为unserialize。
    基本上都是围绕着 这两个函数来展开的
    通俗的说反序列化 序列化的意思就是:
    序列化:将对象转换成字符串
    反序列化:将序列化后的字符串转换为对象 还原
    这两个关系相当于一正一反
    接下来我们来介绍对象中的魔术方法:
    __construct: 在创建对象时候初始化对象,一般用于对变量赋初值。
    __destruct: 和构造函数相反,当对象所在函数调用完毕后执行。
    __toString:当对象被当做一个字符串使用时调用。
    __sleep:序列化对象之前就调用此方法(其返回需要一个数组)
    __wakeup:反序列化恢复对象之前调用该方法
    __call:当调用对象中不存在的方法会自动调用该方法。
    __get:在调用私有属性的时候会自动执行
    __isset()在不可访问的属性上调用isset()或empty()触发
    __unset()在不可访问的属性上使用unset()时触发

    这道题目我们主要介绍这两个魔术方法:
    __construct  构造方法 在对象调用的时候触发
    5.png
    在对象调用的时候 会执行__construct里面的代码

    __destruct 恰好跟构造方法相反 在对象销毁的时候调用
    6.png
    查看一下
    图片1.png

    在对象销毁的时候就是结束的时候会调用这个析构方法
    我们再来看一下反序列化 序列化的这个函数
    序列化:
    7.png
    输出为:
    8.png
    为什么输出这么一个字符串
    O:2:"AB":1:{s:4:"name";N;}
    这个字符串的意思就是:
    O 代表 object 对象的意思
    2 代表2个元素
    AB 是对象的名字
    S 代表string类型

    接下来我来解开这道题:
    9.png

    可以看到isset判断get传过来的参数有没有数据
    然后if判断,这里用到了一个过滤的函数 我们不用管
    $obj = unserialize($str);
    这里使用到了一个反序列化的函数
    反序列化 GET传过来的参数
    10.png
    然后我们可以看到这里
    当对象结束(销毁)的时候会调用这个函数
    我们可以看到if 判断 op === “2” 注意:这是三个等于号
    强制给他转换成”1”
    在这里我们可以绕过这个限制
    利用php弱类型的特性 我们可以想象把op想象成 “  2” (空格2)
    这样子就不会执行后面的这个语句了
    然后他调用了$this->process() 这个函数
    11.png
    我们可以看到 如果op == “1” 他会调用write 写入函数 如果op == “2” 的话他会调用查看函数
    既然我们要拿flag 当然查看比较好了
    上面说过 op == “  2”(空格2) 因为他会自动转换 注意这次是二个等于号
    php比较的时候如果和数字比较会把不是数字的转换成数字在进行比较
    相互之间会互相转换!
    这样我们会执行这个函数:
    $this->read();
    12.png
    这样子就可以拿到flag 肯定有人会问filename要怎么构造?
    我们来构造这个语句:
    13.png
    整体的语句是这样子的
    我来解释一下:
    定义这个类 必须和题目的类名是一样的
    Public 这是权限修饰符 最高权限 谁都可以访问的 公共的
    我们定义 op = ‘  2’(空格2
    Filename  = “flag.php”
    Contennt 给随便的值都是可以的
    然后我们来new 这个对象
    这时候我们来 serialize 序列化这个对象 $flag01 = serialize($flag);
    因为题目要反序列化 我们写的化当然是要来序列化
    序列化的结果就是:
    15.png
    O:11:"FileHandler":3:{s:2:"op";s:2:" 2";s:8:"filename";s:8:"flag.php";s:8:"contennt";s:2:"nc";}
    序列化之后的结果就是这样子的 这就是我们最终的payload
    我们直接把payload放上去执行:
    16.png
    这时候我右键源代码:
    17.png
    这就是flag的值



    14.png
    发表于 2020-12-9 15:40:35
    卧槽,这字体看着好费劲……
    使用道具 举报 回复
    ROTC 发表于 2020-12-9 15:40
    卧槽,这字体看着好费劲……

    截图没整好。。
    使用道具 举报 回复
    感谢分享
    使用道具 举报 回复
    发表于 2020-12-13 21:30:59
    牛批牛批,带带我!!!
    使用道具 举报 回复
    发表于 2020-12-15 14:50:21
    很强啊师傅
    使用道具 举报 回复
    排排版就好了
    使用道具 举报 回复
    发表于 2021-1-14 15:56:36
    大佬 tql
    使用道具 举报 回复
    发新帖
    您需要登录后才可以回帖 登录 | 立即注册