Zimbra-RCE-分析(CVE-2024-45519)
漏洞简介
在远程 Zimbra 服务器开启了 postjournal 服务时,未授权的远程攻击者可构造特殊的请求包发送至远程的Zimbra系统,在目标系统中执行命令,从而获取目标系统的服务器权限。
影响版本
仅影响 Zimbra Network Edition 付费版本
Zimbra Collaboration < 8.8.15 Patch 46
Zimbra Collaboration < 9.0.0 Patch 41
Zimbra Collaboration < 10.0.9
Zimbra Collaboration < 10.1.1
前置知识
邮件相关的协议
- smtp
- pop3
- imap
邮件基础原理
MUA(Mail User Agent)接收邮件所使用的邮件客户端,使用IMAP或POP3协议与服务器通信;
MTA(Mail Transfer Agent) 通过SMTP协议发送、转发邮件;
MDA(Mail Deliver Agent)将MTA接收到的邮件保存到磁盘或指定地方,进行垃圾邮件及病毒扫描;
MRA(Mail Receive Agent)负责实现IMAP与POP3协议,与MUA进行交互;
SMTP(Simple Mail Transfer Protocol)传输发送邮件所使用的标准协议;
IMAP(Internet Message Access Protocol)接收邮件使用的标准协议之一;
POP3(Post Office Protocol 3) 接收邮件使用的标准协议之一。
概念 | 常用软件 |
---|---|
MUA | outlook、thunderbird、Mac Mail、mutt |
MTA | sendmail、postfix |
MDA | procmail、dropmail |
MRA | dovecot |
邮件过程图示
zimbra架构
Zimbra Collaboration Server(Zimbra协作服务器)简称:ZCS,zimbra目前分为
- Zimbra Open Source (ZOS):开源,免费
- Zimbra Network Edition (ZNE):商业,付费
在安装时会安装以下包:
- zimbra-core:核心组件,libraries, utilities, monitoring tools, and basic configuration files
- zimbra-ldap:用户验证组件
- zimbra-logger:用于系统日志聚合和报告的工具
- zimbra-mta:负责邮件的传输和递送,使用 Postfix。它处理邮件的收发、转发以及垃圾邮件和病毒扫描等功能
- zimbra-dnscache:用于提供本地 DNS 缓存服务
- zimbra-snmp:对 Zimbra 邮件服务器进行监控和管理
- zimbra-store:核心组件,主要负责处理与邮箱相关的所有存储、访问和管理、WEB应用功能
- zimbra-apache:随zimbra-spell自动安装
- zimbra-spell:拼写检查
- zimbra-memcached:一个加快数据访问速度的缓存服务模块,帮助管理会话信息、身份验证状态以及其他需要快速访问的数据
- zimbra-proxy:一种高性能的反向代理服务,用于将IMAP[S]/POP[S]/HTTP[S]客户端请求传递给其他内部ZCS服务
- zimbra-drive:WEB客户端管理文件
- zimbra-patch:修漏洞用
- zimbra-mta-patch:修漏洞用
- zimbra-proxy-patch:修漏洞用
- zimbra-chat:在 Web 客户端中进行实时消息交流
以下是不同端口的功能:https://wiki.zimbra.com/wiki/Ports
- 25:smtp,邮件服务
- 80:web mail client
- 465:smtps,邮件服务 with TLS
- 587:Mail submission over TLS
- 110:POP3
- 143:IMAP
- 993:IMAP over TLS
- 995:POP3 over TLS
- 443:HTTP over TLS
- 8080:Backend HTTP
- 8443:Backend HTTPS
- 7071:admin console HTTP over TLS
- 9071:HTTP over TLS
- 10027:postjournal
postjournal
https://wiki.zimbra.com/wiki/New_Features_ZCS_8.5
该服务可以为所有进入或离开 MTA 并传递到特定地址的消息创建日志,即该服务创建邮件副本,作为日志进行留存。
环境搭建
单服务器搭建参考:https://zimbra.github.io/installguides/latest/single.html
因硬件条件不支持,没有成功安装Network版本,故搭建本地测试环境失败。
漏洞分析
通过下载历史版本安装包:https://files.zimbra.com/downloads/8.8.15_GA/zcs-NETWORK-8.8.15_GA_4177.UBUNTU20_64.20211112014220.tgz ,找到 postjournal 二进制文件,路径:
zcs-NETWORK-8.8.15_GA_4177.UBUNTU20_64.20211112014220\packages\zimbra-core_8.8.15.GA.4177.UBUNTU20.64_amd64.deb\data.tar\.\opt\zimbra\libexec\postjournal |
main通过 get_pj_config 和 get_pf_config 函数配置一些变量
main最后通过 msg_receiver 用于接收处理SMTP消息,间接调用 msg_handler() 处理 MSG 消息对象
在 msg_receiver 中,首先初始化MSG对象
MSG *__cdecl msg_init() |
循环解析出输入流中SMTP命令
匹配RCPT时,调用 rcpt_to_handler
rcpt_to_handler 解析出 RCPT TO:<...>
中的email地址存储在 msg->rcpt_addresses
最后调用 msg_handler 进一步处理SMTP消息
跟进 msg_handler ,通过 find_addresses 获取一个email地址列表,随后将 msg->rcpt_addresses 合并到该列表后调用 expand_addrs 尝试获取列表中的email地址
expand_addrs 通过三种邮件映射类型去获取真正的邮件地址,调用到了 address_lookup
- virtual_alias_maps
- canonical_maps
- local_alias_maps
address_lookup 就是上述三种映射的封装,并调用 map_address
map_address 调用 read_addr_maps
read_addr_maps 调用 read_maps
最终在 read_maps 通过可控的 email addr 进行格式化字符串完成popen命令注入
完整调用链
main |
下载漏洞修复的patch文件:https://repo.zimbra.com/apt/8815-ne/pool/zimbra/z/zimbra-patch/zimbra-patch_8.8.15.1723777774.p46-2.u16_amd64.deb
zimbra-patch_8.8.15.1723777774.p46-2.u16_amd64.deb\data.tar\.\opt\zimbra\lib\patches\ |
在 read_maps 新增函数 run_command 和 is_safe_input
is_safe_input过滤一些注入字符
run_command通过execvp以数组形式更安全的执行命令
漏洞复现
根据文档,10027端口为postjournal端口,构造SMTP结构消息体发过去即可
def smtp_payload_check_vulnerability(host, port, oast): |
漏洞利用限制
默认不开启
postjournal 服务默认不开启,开启命令
zmlocalconfig -e postjournal_enabled=true |
本地运行
Zimbra 中的一些服务是在本地地址上运行,无法通过公网直接访问,当开启该服务时,只能通过25端口进行 “转发” 到该服务,造成RCE
ip限制
zimbra中 postconf 的选项 smtpd_relay_restrictions,仅允许在客户端经过身份验证或客户端在 mynetworks 列表中时发送邮件
当没有经过身份验证时,mynetworks为:公网ip/20的CIDR ,还是有概率被打的 :(
mynetworks = 127.0.0.0/8 [::1]/128 <Public IP>/20 10.47.0.0/16 10.122.0.0/20 |
参考
https://blog.projectdiscovery.io/zimbra-remote-code-execution/