天天看點

對zend framework xxe injection 的分析

前幾天網上爆出一個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>

執行流程是這樣的

浏覽器——&gt;client.php——-&gt;server.php;

server.php——–&gt;client.php-&gt;浏覽器;

最關鍵的兩個資料包:第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;也就防止了檔案洩漏的産生