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