php反序列化漏洞

2021-10-24 22:46:36 字數 4220 閱讀 8544

序列化函式:serialize,反序列化函式:unserialize,例:

<?php 

class

test

}$test

=new

test()

;var_dump

(serialize

($test))

;

輸出如下:

string(84

)"o:4:"test":3:"

其中:

o:代表資料型別是物件object,4:代表該物件名有4個字元,test:表示物件名稱,3:表示物件裡有3個成員。後面花括號裡分三組看,第一組s:1:"a";s:5:"thisa";,分別是對變數名和變數值的序列化表示。

可以看到,雖然test類中有個test1方法,但是序列化後的字串並沒有包含這部分,因此得知序列化不儲存方法。

這裡幾個變數序列化後的變數名都各不相同,因為分別是public, protected, private, php為了區分這些屬性新增了一些修飾。

void __wakeup ( void ):

unserialize( )會檢查是否存在乙個_wakeup( ) 方法。如果存在,則會先呼叫_wakeup 方法,預先準備物件需要的資源。

void __construct ([ mixed $args [, $… ]]):

具有建構函式的類會在每次建立新物件時先呼叫此方法。

void __destruct ( void ):

析構函式會在到某個物件的所有引用都被刪除或者當物件被顯式銷毀時執行。

public string __tostring ( void ):

__tostring( ) 方法用於乙個類被當成字串時應怎樣回應。例如 echo $obj;應該顯示些什麼。

此方法必須返回乙個字串,否則將發出一條 e_recoverable_error 級別的致命錯誤。

這裡舉個例子來說明各個魔術方法自動執行的場景

(參考:

<?php 

class

demo

public

function

__destruct()

public

function

__tostring()

public

function

__sleep()

public

function

__wakeup()

}/**/

echo

"-------new了乙個物件,物件被建立,執行__construct-------\n"

;$test

=new

demo()

;/**/

echo

"-------serialize了乙個物件,物件被序列化,先執行__sleep,再序列化-------\n"

;$stest

=serialize

($test);

/**/

echo

"-------unserialize了乙個序列化字串,物件被反序列化,先反序列化,再執行__wakeup-------\n"

;$ustest

=unserialize

($stest);

/**/

echo

"-------把test這個物件當做字串使用了,執行__tostring-------\n"

;$string

='hello class '

.$test

;/**/

echo

"-------程式執行完畢,物件自動銷毀,執行__destruct-------\n"

;

輸出:

--

----

-new了乙個物件,物件被建立,執行__construct--

----

-construct run

----

---serialize了乙個物件,物件被序列化,先執行__sleep,再序列化--

----

-sleep run

----

---unserialize了乙個序列化字串,物件被反序列化,先反序列化,再執行__wakeup--

----

-wakeup run

----

---把test這個物件當做字串使用了,執行__tostring--

----

-tostring run

----

---程式執行完畢,物件自動銷毀,執行__destruct--

----

-destruct run

destruct run

cve-2016-7124

反序列化時,如果表示物件屬性個數的值大於真實的屬性個數時就會跳過__wakeup( )的執行。

影響版本:

以攻防世界的web_php_unserialize這道題為例,原始碼如下:

<?php 

class

demo

function

__destruct()

function

__wakeup()

}}if(

isset

($_get

['var'])

)else

}else

?>

這裡可以看出有兩個需要繞過的點:

繞過__wakeup()的方式上面已經講了,這裡重點說一下繞過preg_match這一塊,這裡參考乙個大佬的文章:

先說結論吧:

這裡可以將序列化字串o:4:"demo":1:改為o:+4:"demo":1:來繞過正則檢測。因為在php5中,對序列化字串的解析過程中,若o:+4:後面出現+,會跳過它直接檢查下一位是否是數字,若是數字則繼續解析下去。

先看 var_unserializer.c 檔案 441 行

序列化字串的第一位為o,因此這裡跳轉到yy13

注意這裡區分大小寫 !

yy13會判斷下一位的字元是否為:, 若是就跳轉到yy17,若不是就跳轉到yy3,這裡會跳轉到yy17

yy17會判斷下一位是否為數字, 若為數字就跳轉到yy20,若為+就跳轉到yy19

yy19會判斷下一位是否為數字,若為數字就跳轉到yy20,否則跳轉到yy18

問題來了!當反序列化操作讀取到:號時 , 下面不管是數字還是+數字,都會跳轉到yy20,而正則匹配的規則能過濾o:4,卻不會過濾o:+4

因此,我們可以利用o:+4這樣的寫法來繞過正則過濾。

php反序列漏洞 例項 PHP反序列化漏洞

雖然胳膊廢了,也不能停止我更新的腳步。寫個簡單點的吧 0x00 何為類和物件 說到序列化和反序列化就不得不提到兩個詞 類和物件 那麼什麼是類,什麼是物件 教科書式的答案是類是物件的抽象,物件是類的例項 那啥叫個抽象,啥叫個例項呢 簡單的說,類就是物件的乙個標準模板,而物件就是按照模板做出來的實物 一...

PHP反序列化漏洞

序列化簡單利用 serialize 序列化 使用函式serialize 可將例項序列化為字串 unserialize 反序列化 使用函式unserialize 可將序列化的字串還原 示例 class example unserialize get code 漏洞利用 構造漏洞利用的 儲存為test....

PHP反序列化漏洞

前幾天安恆月賽兩道web題中有一道題是關於php反序列化的,然後剛好前幾天剛好看過這個知識點,於是乎這次比賽才沒有爆零,總算是寫出來了一道題 doge 所有php裡面的值都可以使用函式serialize 來返回乙個包含位元組流的字串來表示。unserialize 函式能夠重新把字串變回php原來的值...