PHP反序列化漏洞代碼審計(jì)1、什么是序列化
A、PHP網(wǎng)站的定義:
所有php里面的值都可以使用函數(shù)serialize()來(lái)返回一個(gè)包含字節(jié)流的字符串來(lái)表示。unserialize()函數(shù)能夠重新把字符串變回php原來(lái)的值。 序列化一個(gè)對(duì)象將會(huì)保存對(duì)象的所有變量,但是不會(huì)保存對(duì)象的方法,只會(huì)保存類的名字。
按個(gè)人理解就是:
serialize()將一個(gè)對(duì)象轉(zhuǎn)換成一個(gè)字符串,unserialize()將字符串還原為一個(gè)對(duì)象。
當(dāng)然從本質(zhì)上來(lái)說(shuō),反序列化的數(shù)據(jù)本身是沒(méi)有危害的,用戶可控?cái)?shù)據(jù)進(jìn)行反序列化是存在危害的。
B、PHP反序列化
php允許保存一個(gè)對(duì)象方便以后重用,這個(gè)過(guò)程被稱為序列化。為什么要有序列化這種機(jī)制呢?在傳遞變量的過(guò)程中,有可能遇到變量值要跨腳本文件傳遞的過(guò)程。試想,如果為一個(gè)腳本中想要調(diào)用之前一個(gè)腳本的變量,但是前一個(gè)腳本已經(jīng)執(zhí)行完畢,所有的變量和內(nèi)容釋放掉了,我們要如何操作呢?難道要前一個(gè)腳本不斷的循環(huán),等待后面腳本調(diào)用?這肯定是不現(xiàn)實(shí)的。因?yàn)檫@樣的操作,在小項(xiàng)目還好,在大項(xiàng)目里是極其浪費(fèi)資源的。但是如果你將一個(gè)對(duì)象序列化,那么它就會(huì)變成一個(gè)字符串,等你需要的時(shí)候再通過(guò)反序列化轉(zhuǎn)換回變了變量,在進(jìn)行調(diào)用就好了,在這樣就剩了資源的使用。
2、理解PHP反序列化漏洞
PHP類中有一種特殊函數(shù)體的存在叫魔法函數(shù),magic函數(shù)命名是以符號(hào)__開頭的,比如 __construct, __destruct, __toString, __sleep, __wakeup等等。這些函數(shù)在某些情況下會(huì)自動(dòng)調(diào)用,比如__construct當(dāng)一個(gè)對(duì)象創(chuàng)建時(shí)被調(diào)用,__destruct當(dāng)一個(gè)對(duì)象銷毀時(shí)被調(diào)用,__toString當(dāng)一個(gè)對(duì)象被當(dāng)作一個(gè)字符串使用。
而在反序列化時(shí),如果反序列化對(duì)象中存在魔法函數(shù),使用unserialize()函數(shù)同時(shí)也會(huì)觸發(fā)。這樣,一旦我們能夠控制unserialize()入口,那么就可能引發(fā)對(duì)象注入漏洞。
3、PHP反序列化漏洞利用的前提
a.unserialize()函數(shù)的參數(shù)可控;
b.php文件中存在可利用的類,類中有魔術(shù)方法
游客,如果您要查看本帖隱藏內(nèi)容請(qǐng) 回復(fù)
|