在理解這個漏洞前,你需要先搞清楚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>";}