• Pikachu靶场——PHP反序列化漏洞


    1. PHP反序列化

    可参考我写的另一篇博客:反序列化漏洞及漏洞复现

    序列化serialize()

    序列化说通俗点就是把一个对象变成可以传输的字符串,比如下面是一个对象:

    class S{
        public $test="pikachu";
    }
    
    $s=new S(); 		//创建一个对象
    
    serialize($s); 		//把这个对象进行序列化
    
    序列化后得到的结果是这个样子的:O:1:"S":1:{s:4:"test";s:7:"pikachu";}
        O:代表object
        1:表示该对象的类名的字节数(即类名长度为1S:对象的名称
        1:表示该对象有 1 个属性。
        s:数据类型
        4:变量名称的长度
        test:变量名称
        s:数据类型
        7:变量值的长度
        pikachu:变量值
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    反序列化unserialize()

    就是把被序列化的字符串还原为对象,然后在接下来的代码中继续使用。

    $u=unserialize("O:1:"S":1:{s:4:"test";s:7:"pikachu";}");
    
    echo $u->test; //得到的结果为pikachu
    
    • 1
    • 2
    • 3

    注意序列化和反序列化本身没有问题,但是如果反序列化的内容是用户可以控制的,且后台不正当的使用了PHP中的魔法函数,就会导致安全问题

    常见的几个魔法函数:

    __construct():当一个对象创建时被调用。
    
    __destruct():当一个对象销毁时被调用。
    
    __toString():当一个对象被当作一个字符串使用。
    
    __sleep():在对象在被序列化之前运行。
    
    __wakeup:将在序列化之后立即被调用。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    漏洞举例:

    class S{
        var $test = "pikachu";
        function __destruct(){
            echo $this->test;
        }
    }
    $s = $_GET['test'];
    @$unser = unserialize($a);
    
    payload:O:1:"S":1:{s:4:"test";s:29:"";}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    开始闯关

    image-20230909155450025

    输入正常的序列化字符串

    O:1:"S":1:{s:4:"test";s:7:"pikachu";}
    
    • 1

    image-20230909155751128

    因为这里没有对输入的数据进行过滤。可以结合XSS漏洞来构造我们的攻击字符串。

    O:1:"S":1:{s:4:"test";s:30:"";}
    
    • 1

    image-20230909160349235

    1.1 反序列化代码审计

    表单接受序列化后的数据进行传递。

    image-20230909160600053

    注意:PHP中的__construct()这个函数虽然在对象创建时会被调用,但反序列化(unserialize())的时候并不会被调用。当使用 unserialize() 函数从序列化的字符串中恢复对象时,构造函数 __construct() 不会被调用。这是因为在反序列化过程中,对象是从已有的数据恢复出来的,不需要再进行初始化。所以这里的__construct()没有启动任何作用!!!

    image-20230916150000718

    下面的代码是对输入的值进行判断,当输入的值为序列化后的值时,unserialize()可以对其进行反序列化,if条件判断为假,进入else。并没有对用户输入的序列化字符串进行过滤以及识别。

    image-20230909160648527

    反序列化后的对象 u n s e r 调用其属性 t e s t ,并且将值赋值给了 unser调用其属性test,并且将值赋值给了 unser调用其属性test,并且将值赋值给了html,然后输出显示$html。

    1.2 漏洞防御

    • 对反序列化数据进行校验,在反序列化操作前,对输入的序列化字符串进行校验,过滤和验证,判断数据是否合法。
    • 限制应用程序运行账户的权限,降低攻击者在利用反序列化漏洞的影响范围。
    • 所以安全序列化机制,采用安全稳定的序列化协议
    • 安全开发规范。
  • 相关阅读:
    Leetcode第150题—逆波兰表达式
    2022宁夏杯C新冠疫情对宁夏旅游业的影响分析及对策研究
    数学分析:级数
    Flume系列:Flume通道拓扑结构
    ORA-01005 vs ORA-28040
    Icon闪烁/设定蜂鸣器响的次数
    94. 二叉树的中序遍历(递归+迭代)
    终于把相册集成到摄像头APP
    PLC数据采集案例
    springmvc总结
  • 原文地址:https://blog.csdn.net/weixin_58783105/article/details/133427636