php反序列化

清茶先生發表於2021-11-10

PHP反序列化

概念:

序列化就是將物件轉換成字串,反序列化相反,把字串轉換為物件。資料的格式的轉換物件的序列化有利於物件的儲存和傳輸,也可以讓多個檔案共享物件。

使用的函式:

序列化:serialize()
反序列化:unserialize()

演示(無類)

需要用線上的php程式碼線上測試,地址:https://www.dooccn.com/php/
首先定義一個變數KEY,然後給這個變數賦值,用序列化:serialize()函式輸出這個變數

我們可以看到輸出的結果,s是string代表的是字串,16代表的是變數名長度,變數名也就是qingchaxiansheng。

再演示一個

這裡i是int代表的是整型。

以上就是一個序列化的演示,接下來再看反序列化的演示,反序列化其實就是序列化的逆推。

再看整型的

PHP反序列化漏洞

漏洞原理:未對使用者輸入的序列化字串進行檢測,導致攻擊者可以控制反序列化過程,從而導致程式碼執行,sql注入,目錄遍歷等不可控後果,在反序列化的過程中自動觸發了某些魔術方法。當進行反序列化的時候就有可能會觸發物件中的一些魔術方法。

注:反序列化本身沒有沒有漏洞

觸發

unserialize()函式的變數可控,檔案中存在可利用的類,類中有魔術方法:

_construct() //建立物件時觸發

_destruct() //物件被銷燬觸發

_csll() //在物件上下文中呼叫不可訪問的方法時觸發

_callStatic() //在靜態上下文中呼叫不可訪問的方法時觸發

_get() //用於從不可訪問的屬性讀取資料

_set() //用於將資料寫入不可訪問的屬性

_isset() //在不可訪問的屬性上呼叫isset()或empty()觸發

_unset() //在不可訪問的屬性上使用unset()時觸發

_invoke() //當指令碼嘗試將物件呼叫為函式時觸發

簡單列出一些常用的魔術方法。還有很多,大家可以自行搜尋一下。

打靶

網鼎杯2020青龍大賽真題
地址:https://www.ctfhub.com/#/index

由題可知:

由題目命名和函式unserialize可以判斷此題目考察的是反序列化知識點。
主要是獲取flag--儲存flag.php
先進行程式碼分析,看看程式碼說了什麼,看這段程式碼

這段程式碼從下往上看,GET接收一個str引數,然後用is_valid進行檢測,檢測通過就將str進行反序列化,中間一段程式碼是is_valid的檢測內容。最後一段程式碼執行完成以後,也就是銷燬了,在銷燬的時候觸發了解構函式_destruct.然後解構函式就開始執行。如果op===2,則會強制讓他轉為1.

isset()函式用於檢測變數是否已設定並且非 NULL,符合返回ture,不符合返回false

is_valid()函式檢查物件變數是否已經例項化,即例項變數的值是否是個有效的物件。如果指定物件已經建立了對此案例項,那麼IsValid()函式返回True,否則返回FALSE。如果引數obejctname的值為NULL,IsValid()函式返回NULL。

接著看下面的程式碼

傳入的op=1就執行write寫入,如果為2,就執行讀取,因為我們是要flag,所以肯定是要他執行讀取。
_destruct函式對$this->op進行了=的判斷,但是process函式中使用的是對$this->op進行判斷。所以我們要繞過_destruct函式的判斷,進入到process函式中的讀取。這裡使用字串' 2'(空格2)進行繞過。這樣就可以執行讀取。

因為最後一步是將str進行反序列化,我們傳入的時候就應該是序列化。

傳入到str,右鍵檢視原始碼。

感覺我解的也有點亂,大家主要是明白這個反序列化。
簡單總結一下:
本題除了對反序列魔術方法的一個考察,還涉及到了弱型別的繞過
===會對型別、值進行對比,驗證的比較嚴格。
==弱型別對比,僅驗證數值
歡迎大家公眾號關注:小艾搞安全

相關文章