PHP反序列化漏洞

簡介

  • 序列化就是把對象轉換成字節流,便於保存在內存、文件、數據庫中;反序列化即逆過程,由字節流還原成對象

  • php對象注入是一個非常常見的漏洞,這個類型的漏洞雖然有些難以利用,但仍舊非常危險。

  • 類和變量是非常容易理解的php概念。

  • 舉個例子,magic.php在一個類中定義了一個變量和一個方法。它創建了一個對象並且調用了PrintVariable函數,該函數會輸出變量variable。
    在這裏插入圖片描述在這裏插入圖片描述

  • php類可能會包含一些特殊的函數叫magic函數,magic函數命名是以符號__開頭的,比如__construct, __destruct, __toString, __sleep, __wakeup等等。
    這些函數在某些情況下會自動調用,比如__construct當一個對象創建時被調用,__destruct當一個對象銷燬時被調用,__toString當一個對象被當作一個字符串使用。

  • 爲了更好的理解magic方法是如何工作的,在magic.php中增加了三個magic方法,
    __construct, __destruct和__toString。可以看出,
    __construct在對象創建時調用,
    __destruct在php腳本結束時調用,
    __toString在對象被當作一個字符串使用時調用。
    在這裏插入圖片描述
    在這裏插入圖片描述
    php允許保存一個對象方便以後重用,這個過程被稱爲序列化。爲什麼要有序列化這種機制呢?在傳遞變量的過程中,有可能遇到變量值要跨腳本文件傳遞的過程。試想,如果爲一個腳本中想要調用之前一個腳本的變量,但是前一個腳本已經執行完畢,所有的變量和內容釋放掉了,我們要如何操作呢?難道要前一個腳本不斷的循環,等待後面腳本調用?這肯定是不現實的。
    serialize和unserialize就是用來解決這一問題的。
    serialize可以將變量轉換爲字符串並且在轉換中可以保存當前變量的值;
    unserialize則可以將serialize生成的字符串變換回變量。

讓我們在m3.php中添加序列化的例子,看看php對象序列化之後的格式。
在這裏插入圖片描述
在這裏插入圖片描述
在這裏插入圖片描述
爲了使用這個對象,在m4.php中用unserialize重建對象。(這個過程被稱爲反序列化)
在這裏插入圖片描述
在這裏插入圖片描述

  • magic函數__construct和__destruct會在對象創建或者銷燬時自動調用;
  • sleep magic方法在一個對象被序列化的時候調用;
  • wakeup magic方法在一個對象被反序列化的時候調用;

在m5.php中添加這幾個magic函數的例子。
在這裏插入圖片描述
在這裏插入圖片描述
現在我們瞭解序列化是如何工作的,但是我們如何利用它呢?有多種可能的方法,取決於應用程序、可用的類和magic函數。
記住,序列化對象包含攻擊者控制的對象值。你可能在Web應用程序源代碼中找到一個定義__wakeup或__destruct的類,這些函數會影響Web應用程序。例如,我們可能會找到一個臨時將日誌存儲到文件中的類。

當銷燬時對象可能不再需要日誌文件並將其刪除。把下面這段代碼保存爲logfile.php。
在這裏插入圖片描述
這是一個使用它的例子。
在這裏插入圖片描述
在其它腳本中我們可能找到一個unserialize的調用,並且參數是用戶提供的。把下面這段代碼保存爲test.php。
在這裏插入圖片描述
創建利用代碼test2.php ,並瀏覽,發現果然刪除了1.txt文件
在這裏插入圖片描述
在這裏插入圖片描述
• 使用瀏覽器瀏覽:
http://localhost/baji/vul/serialize/test.php?url=O:7:"LogFile":1:{s:8:"filename";s:5:"1.txt";}
在這裏插入圖片描述
顯示已經刪除了1.txt。驗證一下,再次刷新果然成功刪除了。
在這裏插入圖片描述
這就是漏洞名稱的由來:
在變量可控並且進行了unserialize操作的地方注入序列化對象,實現代碼執行或者其它坑爹的行爲。

先不談 __wakeup 和 __destruct,還有一些很常見的注入點允許你利用這個類型的漏洞,一切都是取決於程序邏輯。

舉個例子,某用戶類定義了一個__toString爲了讓應用程序能夠將類作爲一個字符串輸出(echo $obj),而且其他類也可能定義了一個類允許__toString讀取某個文件。把下面這段代碼保存爲test.php。

在這裏插入圖片描述
瀏覽:
http://localhost/PHPxuliehua/h1.php?usr_serialized=O:4:“User”:2:{s:3:“age”;i:20;s:4:“name”;s:4:“John”;}
在這裏插入圖片描述
但是如果我們用序列化調用FileClass呢?先建立一個1.txt。
在這裏插入圖片描述
創建利用代碼h2.php。
在這裏插入圖片描述
http://localhost/PHPxuliehua/h1.php?usr_serialized=O:9:“FileClass”:1:{s:8:“filename”;s:5:“1.txt”;}
在這裏插入圖片描述

  • 成功顯示了文本內容。也可以使用其他magic函數:
  • 如果對象將調用一個不存在的函數__call將被調用;
  • 如果對象試圖訪問不存在的類變量__get和__set將被調用。但是利用這種漏洞並不侷限於magic函數,在普通的函數上也可以採取相同的思路。例如User類可能定義一個get方法來查找和打印一些用戶數據,但是其他類可能定義一個從數據庫獲取數據的get方法,這從而會導致SQL注入漏洞。set或write方法會將數據寫入任意文件,可以利用它獲得遠程代碼執行。唯一的技術問題是注入點可用的類,但是一些框架或腳本具有自動加載的功能。最大的問題在於人:理解應用程序以能夠利用這種類型的漏洞,因爲它可能需要大量的時間來閱讀和理解代碼。

原文地址: https://securitycafe.ro/2015/01/05/understanding- php-object-injection/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章