php淺析反序列化結(jié)構(gòu)
簡介
序列化的目的是方便數(shù)據(jù)的傳輸和存儲,在PHP中,序列化和反序列化一般用做緩存,比如session緩存,cookie等。
反序列化中常見的魔術(shù)方法
- __wakeup() //執(zhí)行unserialize()時(shí),先會調(diào)用這個(gè)函數(shù)
- __sleep() //執(zhí)行serialize()時(shí),先會調(diào)用這個(gè)函數(shù)
- __destruct() //對象被銷毀時(shí)觸發(fā)
- __call() //在對象上下文中調(diào)用不可訪問的方法時(shí)觸發(fā)
- __callStatic() //在靜態(tài)上下文中調(diào)用不可訪問的方法時(shí)觸發(fā)
- __get() //用于從不可訪問的屬性讀取數(shù)據(jù)或者不存在這個(gè)鍵都會調(diào)用此方法
- __set() //用于將數(shù)據(jù)寫入不可訪問的屬性
- __isset() //在不可訪問的屬性上調(diào)用isset()或empty()觸發(fā)
- __unset() //在不可訪問的屬性上使用unset()時(shí)觸發(fā)
- __toString() //把類當(dāng)作字符串使用時(shí)觸發(fā)
- __invoke() //當(dāng)嘗試將對象調(diào)用為函數(shù)時(shí)觸發(fā)
反序列化繞過小Trick
php7.1+反序列化對類屬性不敏感
我們前面說了如果變量前是protected,序列化結(jié)果會在變量名前加上\x00*\x00
但在特定版本7.1以上則對于類屬性不敏感,比如下面的例子即使沒有\x00*\x00也依然會輸出abc
<?php
class test{
protected $a;
public function __construct(){
$this->a = 'abc';
}
public function __destruct(){
echo $this->a;
}
}
unserialize('O:4:"test":1:{s:1:"a";s:3:"abc";}');繞過_wakeup(CVE-2016-7124)
版本:
? PHP5 < 5.6.25
? PHP7 < 7.0.10
利用方式:序列化字符串中表示對象屬性個(gè)數(shù)的值大于真實(shí)的屬性個(gè)數(shù)時(shí)會跳過__wakeup的執(zhí)行
對于下面這樣一個(gè)自定義類
<?php
class test{
public $a;
public function __construct(){
$this->a = 'abc';
}
public function __wakeup(){
$this->a='666';
}
public function __destruct(){
echo $this->a;
}
}如果執(zhí)行unserialize('O:4:"test":1:{s:1:"a";s:3:"abc";}');輸出結(jié)果為666
而把對象屬性個(gè)數(shù)的值增大執(zhí)行unserialize('O:4:"test":2:{s:1:"a";s:3:"abc";}');輸出結(jié)果為abc
繞過部分正則
preg_match('/^O:\d+/')匹配序列化字符串是否是對象字符串開頭,這在曾經(jīng)的CTF中也出過類似的考點(diǎn)
利用加號繞過(注意在url里傳參時(shí)+要編碼為%2B)
serialize(array(a ) ) ; / / a));//a));//a為要反序列化的對象(序列化結(jié)果開頭是a,不影響作為數(shù)組元素的$a的析構(gòu))
<?php
class test{
public $a;
public function __construct(){
$this->a = 'abc';
}
public function __destruct(){
echo $this->a.PHP_EOL;
}
}
function match($data){
if (preg_match('/^O:\d+/',$data)){
die('you lose!');
}else{
return $data;
}
}
$a = 'O:4:"test":1:{s:1:"a";s:3:"abc";}';
// +號繞過
$b = str_replace('O:4','O:+4', $a);
unserialize(match($b));
// serialize(array($a));
unserialize('a:1:{i:0;O:4:"test":1:{s:1:"a";s:3:"abc";}}');
利用引用
<?php
class test{
public $a;
public $b;
public function __construct(){
$this->a = 'abc';
$this->b= &$this->a;
}
public function __destruct(){
if($this->a===$this->b){
echo 666;
}
}
}
$a = serialize(new test());
上面這個(gè)例子將$b設(shè)置為$a的引用,可以使$a永遠(yuǎn)與$b相等
16進(jìn)制繞過字符的過濾
O:4:“test”:2:{s:4:“%00*%00a”;s:3:“abc”;s:7:“%00test%00b”;s:3:“def”;}
可以寫成
O:4:“test”:2:{S:4:“\00*\00\61”;s:3:“abc”;s:7:“%00test%00b”;s:3:“def”;}
表示字符類型的s大寫時(shí),會被當(dāng)成16進(jìn)制解析。
到此這篇關(guān)于php淺析反序列化結(jié)構(gòu)的文章就介紹到這了,更多相關(guān)php反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
php獲取四位字母和數(shù)字的隨機(jī)數(shù)的實(shí)現(xiàn)方法
這篇文章主要介紹了php做程序開發(fā)的過程中,我們很多時(shí)候會在登錄界面或者評論界面做一些四位數(shù)的驗(yàn)證碼,需要的朋友可以參考下2015-01-01
30 個(gè)很棒的PHP開源CMS內(nèi)容管理系統(tǒng)小結(jié)
本文匯集了30個(gè)優(yōu)秀的開源CMS建站系統(tǒng),采用PHP開發(fā)。以下列表不分先后順序2011-10-10
PHP調(diào)用Webservice實(shí)例代碼
NuSoap是PHP環(huán)境下的WebService編程工具,用于創(chuàng)建或調(diào)用WebService。2011-07-07
使用PHP和Redis實(shí)現(xiàn)消息隊(duì)列功能
這篇文章主要介紹了如何使用PHP和Redis實(shí)現(xiàn)消息隊(duì)列功能,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用PHP具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧<BR>2024-03-03

