詳解PHP反序列化漏洞示例與原理
預(yù)備知識(shí)
PHP序列化與反序列化
序列化:將一個(gè)復(fù)雜的數(shù)據(jù)類(lèi)型(如對(duì)象、數(shù)組、變量等)轉(zhuǎn)換為字符串表示,以便于在網(wǎng)絡(luò)中傳輸和在數(shù)據(jù)庫(kù)中存儲(chǔ)。在PHP語(yǔ)言中使用serialize()
函數(shù)實(shí)現(xiàn)。
反序列化:將一個(gè)序列化的字符串重新轉(zhuǎn)換為一個(gè)具體的數(shù)據(jù)類(lèi)型。在PHP語(yǔ)言中使用unserialize()
函數(shù)實(shí)現(xiàn)。 PHP對(duì)象中只有數(shù)據(jù)會(huì)被序列化,方法不會(huì)被序列化。
序列化字符串格式
PHP中經(jīng)過(guò)序列化的字符串格式如下:
類(lèi)型:類(lèi)名長(zhǎng)度:“類(lèi)名”:類(lèi)屬性數(shù)量:{屬性類(lèi)型:屬性長(zhǎng)度:“屬性?xún)?nèi)容”}
序列化字符串中的屬性命名規(guī)則:如果變量為public,則值保持不變;如果變量為private,則在值開(kāi)頭加上類(lèi)名前綴;如果變量為protected,則在值開(kāi)頭加*
符號(hào)。
下面給出序列化字符串中的屬性類(lèi)型:
類(lèi)型 | 解釋 |
---|---|
s:length:“value” | 字符串 |
i:value | 整數(shù)值 |
d:value | 浮點(diǎn)數(shù)值 |
b:value | 布爾值 |
a:length:{…} | 數(shù)組 |
O:length:“name”:number:{…} | 對(duì)象 |
N | NULL |
PHP魔術(shù)方法
簡(jiǎn)介:魔術(shù)方法是一種以2個(gè)下劃線開(kāi)頭的特殊方法,對(duì)一個(gè)對(duì)象執(zhí)行魔術(shù)方法時(shí)會(huì)覆蓋PHP默認(rèn)的操作。
常見(jiàn)的PHP魔術(shù)方法如下:
方法 | 調(diào)用時(shí)間 |
---|---|
__construct(構(gòu)造函數(shù)) | 創(chuàng)建新對(duì)象時(shí) |
__destruct (析構(gòu)函數(shù)) | 銷(xiāo)毀對(duì)象時(shí) |
__call | 在對(duì)象中調(diào)用不可用方法時(shí) |
__callStatic | 在上下文中調(diào)用不可用方法時(shí) |
__get | 讀不可用值時(shí) |
__set | 寫(xiě)不可用值時(shí) |
__isset | 對(duì)不可用值調(diào)用isset() 或empty() 時(shí) |
__unset | 對(duì)不可用值調(diào)用unset() 時(shí) |
__sleep | 序列化對(duì)象時(shí) |
__wakeup | 反序列化對(duì)象時(shí) |
__toString | 對(duì)象被作為字符串使用時(shí) |
__invoke | 嘗試以調(diào)用函數(shù)方式調(diào)用對(duì)象時(shí) |
示例
<?php class Test{ public $a="aaa"; private $b="bbb"; protected $c=123; function __construct($a,$b,$c) { $this->a=$a; $this->b=$b; $this->c=$c; echo("Constructor called.<br>"); } function __destruct() { echo("Destructor called.<br>"); } function show() { echo($this->a."\n".$this->b."\n".$this->c."<br>"); } } $data=new Test("a",1,1.1); $data_str=serialize($data); echo($data_str."\n"); $data_new=unserialize($data_str); echo("<br>"); $data_new->show(); ?>
反序列化漏洞
反序列化漏洞指網(wǎng)站未對(duì)被用戶(hù)所控制的序列化字符串做檢查,攻擊者提交了精心構(gòu)造的有害序列化字符串,導(dǎo)致惡意代碼被執(zhí)行。常見(jiàn)于PHP、Python、Java等允許對(duì)象序列化功能的編程語(yǔ)言中。
在PHP中,導(dǎo)致反序列化漏洞的原因大多是魔術(shù)方法的不規(guī)范使用。(如輸出變量?jī)?nèi)容、寫(xiě)文件操作、寫(xiě)數(shù)據(jù)庫(kù)操作等參數(shù)用戶(hù)可控)
構(gòu)造函數(shù)&析構(gòu)函數(shù)
假設(shè)網(wǎng)站頁(yè)面部分代碼編寫(xiě)如下:
<?php class Test { var $a="aaa"; function __construct($a) { $this->a=$a; echo("Info:<br>".$a); } } $data_new=unserialize($_GET['data']); var_dump($data_new); ?>
當(dāng)對(duì)象創(chuàng)建(或銷(xiāo)毀)時(shí),程序會(huì)輸出對(duì)象中三個(gè)成員變量的值;程序還從API接口讀取了一個(gè)序列化字符串并試圖將其反序列化。此時(shí)如果將序列化字符串中的值修改為惡意代碼,類(lèi)名修改為Test
,會(huì)導(dǎo)致反序列化漏洞攻擊。
EXP:O:4:“Test”:1:{s:4:“test”;s:29:“<script>alert(‘xss’)</script>”;}
CVE-2016-7124
在PHP5 <5.6.25
、PHP7 <7.0.10
的環(huán)境中,如果類(lèi)中存在__wakeup
魔術(shù)方法,則在反序列化之前會(huì)先調(diào)用該方法。但當(dāng)序列化字符串中屬性數(shù)量大于真實(shí)屬性數(shù)量時(shí),該方法不會(huì)執(zhí)行。
<?php class Test { var $mess="111"; function __wakeup() { $this->mess="failed"; echo("Please try again.<br>"); } } $new_data=unserialize($_GET['ins']); var_dump($new_data); ?>
代碼中,當(dāng)反序列化一個(gè)字符串時(shí),程序會(huì)執(zhí)行__wakeup
方法,將$mess
設(shè)置為字符串,并顯示失敗信息。此時(shí)把序列化字符串中的屬性數(shù)量值改大,__wakeup
方法會(huì)失效。
EXP:http://127.0.0.1/serialize.php?ins=O:4:“Test”:2:{s:4:“mess”;s:25:"
<script>alert(1)</script>";}
到此這篇關(guān)于詳解PHP反序列化漏洞示例與原理的文章就介紹到這了,更多相關(guān)PHP反序列化漏洞內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Docker 安裝 PHP并與Nginx的部署實(shí)例講解
這篇文章主要介紹了Docker 安裝 PHP并與Nginx的部署實(shí)例講解,文中圖文操作步驟講解的很清楚,有感興趣的同學(xué)可以研究下2021-02-02php加速緩存器opcache,apc,xcache,eAccelerator原理與配置方法實(shí)例分析
這篇文章主要介紹了php加速緩存器opcache,apc,xcache,eAccelerator原理與配置方法,結(jié)合實(shí)例形式分析了php加速緩存器opcache,apc,xcache,eAccelerator的基本功能、原理及擴(kuò)展配置相關(guān)操作技巧,需要的朋友可以參考下2020-03-03PHP獲取文件擴(kuò)展名的常用方法小結(jié)【五種方式】
這篇文章主要介紹了PHP獲取文件擴(kuò)展名的常用方法,結(jié)合實(shí)例形式總結(jié)分析了php獲取文件擴(kuò)展名的五種常見(jiàn)操作技巧,需要的朋友可以參考下2018-04-04PHP實(shí)現(xiàn)的AES加密、解密封裝類(lèi)與用法示例
這篇文章主要介紹了PHP實(shí)現(xiàn)的AES加密、解密封裝類(lèi)與用法,結(jié)合實(shí)例形式分析了php封裝的aes加密解密操作類(lèi)及相關(guān)使用技巧,需要的朋友可以參考下2018-08-08WordPress用戶(hù)登錄框密碼的隱藏與部分顯示技巧
這篇文章主要介紹了WordPress用戶(hù)登錄框密碼的隱藏與部分顯示技巧,需要的朋友可以參考下2015-12-12分享下php5類(lèi)中三種數(shù)據(jù)類(lèi)型的區(qū)別
這篇文章主要介紹了php5類(lèi)中三種數(shù)據(jù)類(lèi)型的區(qū)別,需要的朋友可以參考下2015-01-01