- 資訊首頁(yè) > 網(wǎng)絡(luò )安全 >
- PHP反序列化的概念和用法
本篇內容介紹了“PHP反序列化的概念和用法”的有關(guān)知識,在實(shí)際案例的操作過(guò)程中,不少人都會(huì )遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學(xué)有所成!
序列化:主要是將變量進(jìn)行轉換,使其變?yōu)樽址?,序列化一個(gè)對象將會(huì )保存對象的所有變量,但是不會(huì )保存對象的方法,只會(huì )保存類(lèi)的名字。在程序執行結束時(shí),內存數據便會(huì )立即銷(xiāo)毀,變量所儲存的數據便是內存數據,而文件、數據庫是“持久數據”,因此PHP序列化就是將內存的變量數據“保存”到文件中的持久數據的過(guò)程。方便保存和傳輸,并且可以達到節省空間的目的
反序列化:主要是在特定的時(shí)候將序列化轉換為字符串的內容再轉換為原來(lái)的變量繼續使用,簡(jiǎn)單來(lái)理解起來(lái)就是將序列化過(guò)存儲到文件中的數據,恢復到程序代碼的變量表示形式的過(guò)程,恢復到變量序列化之前的結果。
PHP反序列化的相關(guān)函數主要是:serialize()和unserialize()
其中serialize()可以將變量轉換為字符串,并且在轉換的過(guò)程中保存當我變量的值
而unserialize()2可以將serialize()轉換的字符串再轉換為變量
主要包括:類(lèi),變量,方法,對象(如下圖)
__construct 當一個(gè)對象創(chuàng )建時(shí)被調用,
__destruct 當一個(gè)對象銷(xiāo)毀時(shí)被調用,
__toString 當一個(gè)對象被當作一個(gè)字符串被調用。
__wakeup() 使用unserialize時(shí)觸發(fā)
__sleep() 使用serialize時(shí)觸發(fā)
__destruct() 對象被銷(xiāo)毀時(shí)觸發(fā)
__call() 在對象上下文中調用不可訪(fǎng)問(wèn)的方法時(shí)觸發(fā)
__callStatic() 在靜態(tài)上下文中調用不可訪(fǎng)問(wèn)的方法時(shí)觸發(fā)
__get() 用于從不可訪(fǎng)問(wèn)的屬性讀取數據
__set() 用于將數據寫(xiě)入不可訪(fǎng)問(wèn)的屬性
__isset() 在不可訪(fǎng)問(wèn)的屬性上調用isset()或empty()觸發(fā)
__unset() 在不可訪(fǎng)問(wèn)的屬性上使用unset()時(shí)觸發(fā)
__toString() 把類(lèi)當作字符串使用時(shí)觸發(fā),返回值需要為字符串
__invoke() 當腳本嘗試將對象調用為函數時(shí)觸發(fā)
<?php class User { public $age = 0; public $name = ''; public function PrintData() { echo 'User '.$this->name.'is'.$this->age.'years old. <br />'; } } //創(chuàng )建一個(gè)對象 $user = new User(); // 設置數據 $user->age = 20; $user->name = 'daye'; //輸出數據 $user->PrintData(); //輸出序列化之后的數據 echo serialize($user); ?>
O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}
對象類(lèi)型:長(cháng)度:"類(lèi)名":類(lèi)中變量的個(gè)數:{類(lèi)型:長(cháng)度:"值";類(lèi)型:長(cháng)度:"值";......}
反序列化
<?php class User { public $age = 0; public $name = ''; public function PrintData() { echo 'User '.$this->name.' is '.$this->age.' years old. <br />'; } } //重建對象 $user = unserialize('O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"daye";}'); $user->PrintData(); ?>
<?php class test{ public $varr1="abc"; public $varr2="123"; public function echoP(){ echo $this->varr1."<br>"; } public function __construct(){ echo "__construct<br>"; } public function __destruct(){ echo "__destruct<br>"; } public function __toString(){ return "__toString<br>"; } public function __sleep(){ echo "__sleep<br>"; return array('varr1','varr2'); } public function __wakeup(){ echo "__wakeup<br>"; } } $obj = new test(); //實(shí)例化對象,調用__construct()方法,輸出__construct $obj->echoP(); //調用echoP()方法,輸出"abc" echo $obj; //obj對象被當做字符串輸出,調用__toString()方法,輸出__toString $s =serialize($obj); //obj對象被序列化,調用__sleep()方法,輸出__sleep echo unserialize($s); //$s首先會(huì )被反序列化,會(huì )調用__wake()方法,被反序列化出來(lái)的對象又被當做字符串,就會(huì )調用_toString()方法。 // 腳本結束又會(huì )調用__destruct()方法,輸出__destruct ?>
當出現PHP反序列化漏洞的時(shí)候,首先我們可以將想要輸入的變量使用serialize()進(jìn)行序列化,如:O:1:"S":1:{s:4:"test";s:28:"<img src=x onerror=alert(1)>";}
其次,將序列化之后的字符串放到url中。在PHP代碼中使用了unserialize(),則會(huì )自動(dòng)執行特定的魔法函數,如果魔法函數中有其他的一些危險函數且是我們可控的,即可進(jìn)行其他操作。
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自互聯(lián)網(wǎng)轉載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權請聯(lián)系QQ:712375056 進(jìn)行舉報,并提供相關(guān)證據,一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容。
Copyright ? 2009-2021 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 珠海市特網(wǎng)科技有限公司 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站