談談微信支付曝出的漏洞

Linux愛好者2018-07-09 03:04:37

(點擊上方公眾號,可快速關注)


來源:編程迷思

www.cnblogs.com/kismetv/p/9266224.html




在DTD中,引進實體,在解析XML時,實體將會被替換成相應的引用內容。該實體可以由外部引入(支持http、ftp等協議,後文以http為例說明),如果通過該外部實體進行攻擊,就是XXE攻擊。


可以說,XXE之所以能夠存在,本質上在於在解析XML的時候,可以與外部進行通信;當XML文檔可以由任意構造時,攻擊便成為可能。在利用XXE漏洞可以做的事情當中,最常見最容易實現的,便是讀取服務器的信息,包括目錄結構、文件內容等;本次爆出的漏洞便屬於這一種。


2.  微信支付漏洞


本次漏洞影響的範圍是:在微信支付異步回調接口中,使用微信支付SDK進行XML解析的應用。注意這裡的SDK是服務器端的SDK,APP端使用SDK並不受影響。


SDK下載地址如下(目前微信官方宣傳漏洞已修復):

https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA_v3.zip


SDK中導致漏洞的代碼是WXPayUtil工具類中的xmlToMap()方法:



如上圖所示,由於在解析XML時沒有對外部實體的訪問做任何限制,如果攻擊者惡意構造xml請求,便可以對服務器進行攻擊。下面通過實例介紹攻擊的方法。


3.  攻擊復現


下面在本機環境下進行復現。


假設本地的web服務器127.0.0.1:8080中存在POST接口:/wxpay/callback,該接口中接收xml字符串做參數,並調用前述的WXPayUtil.xmlToMap(strXml)對xml參數進行解析。此外,/etc/password中存儲了重要的密碼數據(如password1234)。


攻擊時構造的請求如下:



其中xml內容如下:



通過xml+dtd文件,攻擊者便可以在服務器http://127.0.0.1:9000中收到如下請求:


http://127.0.0.1:9000/evil/password1234


這樣,攻擊者便得到了/etc/password文件的內容。


在本例中,攻擊者竊取了/etc/password文件中的內容,實際上攻擊者還可以獲取服務器中的目錄結構以及其他文件,只要啟動web應用的用戶具有相應的讀權限。如果獲取的信息比較複雜,如包含特殊符號,無法直接通過http的URL發送,則可以採用對文件內容進行Base64編碼等方法解決。


三、漏洞的解決


解決該漏洞的原理非常簡單,只要禁止解析XML時訪問外部實體即可。


漏洞曝出以後,微信進行了緊急修復,一方面是更新了SDK,並提醒開發者使用最新的SDK;SDK中修復代碼如下:



加入瞭如下兩行代碼:


documentBuilderFactory.setExpandEntityReferences(false);

documentBuilderFactory.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, true);


更新:微信表示上述2條語句無法禁止該漏洞,又雙叒叕更新了官方SDK,加了以下語句(對於微信的這波操作,不知如何評價):



此外,微信官方也給出了關於XXE漏洞的最佳安全實踐,可以參考:


https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5


筆者本人使用上述方案中建議的如下代碼修復了該漏洞:


DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();

documentBuilderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);

DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

……


四、擴展與反思


1.  危害不只是“0元也能買買買”


在很多媒體的報道中,強調該漏洞的風險在於攻擊者可以不支付也可以獲得商品。確實,攻擊者在通過上述漏洞獲得微信支付的祕鑰以後,有不止一種途徑可以做到不支付就獲得商品:例如,攻擊者首先在系統中下單,獲得商戶訂單號;然後便可以調用微信支付的異步回調,其中的簽名參數便可以使用前面獲取的祕鑰對訂單號等信息進行MD5獲得;這樣攻擊者的異步回調就可以通過應用服務器的簽名認證,從而獲得商品。不過,在很多有一定規模的購物網站(或其他有支付功能的網站),會有對賬系統,如定時將系統中的訂單狀態與微信、支付寶的後臺對比,如果出現不一致可以及時報警並處理,因此該漏洞在這方面的影響可能並沒有想象的那麼大。


然而,除了“0元也能買買買”,攻擊者可以做的事情還有很多很多;理論上來說,攻擊者可能獲得應用服務器上的目錄結構、代碼、數據、配置文件等,可以根據需要進行進一步破壞。


2.  漏洞不限於微信支付SDK


雖然微信支付曝出該漏洞受到了廣泛關注,但該漏洞絕不僅僅存在於微信支付中:由於眾多XML解析器默認不會禁用對外部實體的訪問,因此應用的接口如果有以下幾個特點就很容易掉進XXE漏洞的坑裡:


(1)接口使用xml做請求參數


(2)接口對外公開,或容易獲得:例如一些接口提供給外部客戶調用,或者接口使用http很容易抓包,或者接口比較容易猜到(如微信支付的異步回調接口)


(3)接口中解析xml參數時,沒有禁用對外部實體的訪問


建議大家最好檢查一下自己的應用中是否有類似的漏洞,及時修復。



參考文獻


  • https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=23_5

  • http://seclists.org/fulldisclosure/2018/Jul/3

  • https://www.cnblogs.com/tongwen/p/5194483.html



【關於投稿】


如果大家有原創好文投稿,請直接給公號發送留言。


① 留言格式:
【投稿】+《 文章標題》+ 文章鏈接

② 示例:
【投稿】《不要自稱是程序員,我十多年的 IT 職場總結》:http://blog.jobbole.com/94148/

③ 最後請附上您的個人簡介哈~



看完本文有收穫?請分享給更多人

關注「Linux 愛好者」,提升Linux技能

閱讀原文

TAGS: