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