在理解這個漏洞前,你需要先搞清楚php中serialize(),unserialize()這兩個函數。

序列化serialize()
序列化說通俗點就是把一個對象變成可以傳輸的字符串,比如下面是一個對象:
    class S{
        public $test="bihuoedu";
    }
    $s=new S(); //創建一個對象
    serialize($s); //把這個對象進行序列化
    序列化后得到的結果是這個樣子的:O:1:"S":1:{s:4:"test";s:8:"bihuoedu";}
        O:代表object
        1:代表對象名字長度為一個字符
        S:對象的名稱
        1:代表對象里面有一個變量
        s:數據類型
        4:變量名稱的長度
        test:變量名稱
        s:數據類型
        7:變量值的長度
        bihuoedu:變量值
    
反序列化unserialize()

就是把被序列化的字符串還原為對象,然后在接下來的代碼中繼續使用。

    $u=unserialize("O:1:"S":1:{s:4:"test";s:8:"bihuoedu";}");
    echo $u->test; //得到的結果為bihuoedu
    

序列化和反序列化本身沒有問題,但是如果反序列化的內容是用戶可以控制的,且后臺不正當的使用了PHP中的魔法函數,就會導致安全問題

        常見的幾個魔法函數:
        __construct()當一個對象創建時被調用

        __destruct()當一個對象銷毀時被調用

        __toString()當一個對象被當作一個字符串使用

        __sleep() 在對象在被序列化之前運行

        __wakeup將在序列化之后立即被調用

        漏洞舉例:

        class S{
            var $test = "bihuoedu";
            function __destruct(){
                echo $this->test;
            }
        }
        $s = $_GET['test'];
        @$unser = unserialize($a);

        payload:O:1:"S":1:{s:4:"test";s:29:"<script>alert('xss')</script>";}