前幾天網上爆出一個zend framework 漏洞 作者:mkods
具體描述如下: https://www.sec-consult.com/files/20120626-0_zend_framework_xxe_injection.txt ; 根據描述,該漏洞是發生在zend 架構 xmlrpc子產品的一個 xxe(XML external entity) injection漏洞,利用這個漏洞可以讀取伺服器上任意檔案,例如php檔案源代碼; xmlrpc是提供rpc (遠端過程調用)服務的一個子產品,采用xml語言在服務端跟用戶端之間進行資料互動;問題就出在服務端跟用戶端對xml的解析上;
網上已經有文章證明了這個漏洞,并給出了成功讀出”/etc/passwd”檔案的截圖;但我沒看明白具體是如何爆出檔案内容的; 為了明白這個漏洞到底如何利用,以及成功利用需要什麼條件,我寫了個簡單的程式測試; 既然是rpc服務,那就得有一個用戶端,一個服務端; 服務端提供了一個程式hello,當有用戶端向服務端請求執行hello函數時,服務端就會執行hello函數,并把運作結果”this is a zend framework xmlrpc helloword”傳回給用戶端; 具體代碼如下
服務端代碼server.php:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/QQ%E6%88%AA%E5%9B%BE20120711171601.png"></a>
用戶端代碼client.php
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/520.png"></a>
把代碼server.php、client.php部署到apache,開啟wireshark抓包,然後在浏覽器通路http://localhost/zendtest/client.php,頁面成功顯示來自server.php的字元串
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/firefox.png"></a>
打開wireshark 檢視這個過程中産生的資料包
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/wireshark.png"></a>
執行流程是這樣的
浏覽器——>client.php——->server.php;
server.php——–>client.php->浏覽器;
最關鍵的兩個資料包:第4個資料包是client.php請求server.php執行hello函數的post資料;第5個資料包是server.php傳回給client.php的資料;
包内容如下:
資料包4:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/data1.png"></a>
資料包5:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/data2.png"></a>
通過檢視資料包,熟悉了 zend_xmlrpc的工作流程,以及所發資料的格式及意思; 現在我們根據已知格式來構造會觸發漏洞的資料包:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/QQ%E6%88%AA%E5%9B%BE20120711171924.png"></a>
該惡意資料包的目的是讀取服務端系統的 “/etc/passwd”檔案;
為了測試友善,我寫了一個python腳本向server.php發包,代碼如下:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/2.png"></a>
執行這個python腳本,傳回結果如下:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/result.png"></a>
成功爆出了”/etc/passwd”檔案的内容;
現在來整理下該漏洞産生的流程:
1: server.php 收到xml資料,交給zend_xmlrpc_server:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/31.png"></a>
2:Zend_Xmlrpc_server子產品直接使用 new simpleXMLElement($xml)解析xml,并建立執行個體;解析後的xml執行個體為:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/4.png"></a>
3:zend_xmlrpc_server讀取methodname的值(即紅色字型文字)作為用戶端請求執行的函數;
4: 由于請求的函數不存在,zend_xmlrpc_server傳回錯誤資訊 xxx does not exits;(xxx為 /etc/passwd 的内容)
由此洩漏了”/etc/passwd”的内容
zend framework的新版本修複了這個漏洞,截圖中紅線處的代碼是更新檔代碼:
<a href="http://www.h4ck.cc/wp-content/uploads/2012/07/catch.png"></a>
執行 libxml_disable_entity_loader(true),這樣SimpleXMLElement在解析xml的時候就不會解析entity;也就防止了檔案洩漏的産生