理解php反序列化漏洞
php對象注入是一個非常常見的漏洞,這個類型的漏洞雖然有些難以利用,但仍舊非常危險。為了理解這個漏洞,請讀者具備基礎(chǔ)的php知識。類和變量是非常容易理解的php概念。舉個例子,1.php在一個類中定義了一個變量和一個方法。它創(chuàng)建了一個對象并且調(diào)用了PrintVariable函數(shù),該函數(shù)會輸出變量variable。
[php]?view plain?copy?
php類可能會包含一些特殊的函數(shù)叫magic函數(shù),magic函數(shù)命名是以符號__開頭的,比如 __construct, __destruct, __toString, __sleep, __wakeup等等。這些函數(shù)在某些情況下會自動調(diào)用,比如__construct當(dāng)一個對象創(chuàng)建時被調(diào)用,__destruct當(dāng)一個對象銷毀時被調(diào)用,__toString當(dāng)一個對象被當(dāng)作一個字符串使用。為了更好的理解magic方法是如何工作的,在2.php中增加了三個magic方法,__construct, __destruct和__toString。可以看出,__construct在對象創(chuàng)建時調(diào)用,__destruct在php腳本結(jié)束時調(diào)用,__toString在對象被當(dāng)作一個字符串使用時調(diào)用。
[php]?view plain?copyphp允許保存一個對象方便以后重用,這個過程被稱為序列化。為什么要有序列化這種機(jī)制呢?在傳遞變量的過程中,有可能遇到變量值要跨腳本文件傳遞的過程。試想,如果為一個腳本中想要調(diào)用之前一個腳本的變量,但是前一個腳本已經(jīng)執(zhí)行完畢,所有的變量和內(nèi)容釋放掉了,我們要如何操作呢?難道要前一個腳本不斷的循環(huán),等待后面腳本調(diào)用?這肯定是不現(xiàn)實(shí)的。serialize和unserialize就是用來解決這一問題的。serialize可以將變量轉(zhuǎn)換為字符串并且在轉(zhuǎn)換中可以保存當(dāng)前變量的值;unserialize則可以將serialize生成的字符串變換回變量。讓我們在3.php中添加序列化的例子,看看php對象序列化之后的格式。
[php]?view plain?copy為了使用這個對象,在4.php中用unserialize重建對象。
[php]?view plain?copymagic函數(shù)__construct和__destruct會在對象創(chuàng)建或者銷毀時自動調(diào)用;__sleep magic方法在一個對象被序列化的時候調(diào)用;__wakeup magic方法在一個對象被反序列化的時候調(diào)用。在5.php中添加這幾個magic函數(shù)的例子。
[php]?view plain?copy
現(xiàn)在我們了解序列化是如何工作的,但是我們?nèi)绾卫盟?有多種可能的方法,取決于應(yīng)用程序、可用的類和magic函數(shù)。記住,序列化對象包含攻擊者控制的對象值。你可能在Web應(yīng)用程序源代碼中找到一個定義__wakeup或__destruct的類,這些函數(shù)會影響Web應(yīng)用程序。例如,我們可能會找到一個臨時將日志存儲到文件中的類。當(dāng)銷毀時對象可能不再需要日志文件并將其刪除。把下面這段代碼保存為logfile.php。
這是一個使用它的例子。
[php]?view plain?copy在其它腳本中我們可能找到一個unserialize的調(diào)用,并且參數(shù)是用戶提供的。把下面這段代碼保存為test.php。
[php]?view plain?copy創(chuàng)建利用代碼111.php。
[php]?view plain?copy訪問http://192.168.153.138/test.php?usr_serialized=O:7:"LogFile":1:{s:8:"filename";s:5:"1.php";}。
顯示已經(jīng)刪除了1.php。驗(yàn)證一下,果然成功刪除了。
這就是漏洞名稱的由來:在變量可控并且進(jìn)行了unserialize操作的地方注入序列化對象,實(shí)現(xiàn)代碼執(zhí)行或者其它坑爹的行為。先不談 __wakeup 和 __destruct,還有一些很常見的注入點(diǎn)允許你利用這個類型的漏洞,一切都是取決于程序邏輯。舉個例子,某用戶類定義了一個__toString為了讓應(yīng)用程序能夠?qū)㈩愖鳛橐粋€字符串輸出(echo $obj),而且其他類也可能定義了一個類允許__toString讀取某個文件。把下面這段代碼保存為test.php。
[php]?view plain?copy訪問http://192.168.153.138/test.php?usr_serialized=O:4:"User":2:{s:3:"age";i:20;s:4:"name";s:4:"John";}。
?
但是如果我們用序列化調(diào)用FileClass呢?先建立一個1.txt。
創(chuàng)建利用代碼123.php。
[php]?view plain?copy訪問http://192.168.153.138/test.php?usr_serialized=O:9:"FileClass":1:{s:8:"filename";s:5:"1.txt";}。
成功顯示了文本內(nèi)容。也可以使用其他magic函數(shù):如果對象將調(diào)用一個不存在的函數(shù)__call將被調(diào)用;如果對象試圖訪問不存在的類變量__get和__set將被調(diào)用。但是利用這種漏洞并不局限于magic函數(shù),在普通的函數(shù)上也可以采取相同的思路。例如User類可能定義一個get方法來查找和打印一些用戶數(shù)據(jù),但是其他類可能定義一個從數(shù)據(jù)庫獲取數(shù)據(jù)的get方法,這從而會導(dǎo)致SQL注入漏洞。set或write方法會將數(shù)據(jù)寫入任意文件,可以利用它獲得遠(yuǎn)程代碼執(zhí)行。唯一的技術(shù)問題是注入點(diǎn)可用的類,但是一些框架或腳本具有自動加載的功能。最大的問題在于人:理解應(yīng)用程序以能夠利用這種類型的漏洞,因?yàn)樗赡苄枰罅康臅r間來閱讀和理解代碼。
原文地址:https://securitycafe.ro/2015/01/05/understanding-php-object-injection/
轉(zhuǎn)載于:https://www.cnblogs.com/gongchixin/articles/8108957.html
總結(jié)
以上是生活随笔為你收集整理的理解php反序列化漏洞的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows和Linux环境下搭建SV
- 下一篇: PHPStorm IDE 快捷键