Translated ['src/pentesting-ci-cd/gogs-security/README.md'] to zh

This commit is contained in:
Translator
2026-06-05 13:57:18 +00:00
parent 8929e34ec6
commit c2c8290f76
@@ -0,0 +1,103 @@
# Gogs Security
{{#include ../../banners/hacktricks-training.md}}
## 什么是 Gogs
**Gogs** 是一个用 Go 编写的**self-hosted 轻量级 Git service**。从攻击者的角度看,可以将其视为一个**multi-tenant Git hosting platform**,即使低权限用户也可能控制 branch names、pull requests、webhooks、tokens 和 repository settings。
## 通过 refs / branch names 进行 Git option 注入
如果应用程序将攻击者控制的 **ref name** 直接传给 Git command**而没有使用 `--``--end-of-options`**,那么以 `--` 开头的 branch 可能会被解析为 **Git option**,而不是数据。
Typical dangerous pattern:
```bash
git <subcommand> <user-controlled-ref>
```
防御性代码中期望的更安全模式:
```bash
git <subcommand> -- <user-controlled-ref>
# or
git <subcommand> --end-of-options <user-controlled-ref>
```
一个常见的错误假设是,用 `git rev-parse --verify <ref>` 验证 ref 就足够了。事实并**非如此**:
- 攻击者可以先**创建一个真实分支**,其名称以 `--` 开头
- `rev-parse --verify` 只检查该 ref 是否解析到一个 object
- 后续不安全的 Git 调用仍可能将同一个值解析为一个**option**
这会把任何重用已存储 branch 名称的 Git-hosting 功能变成潜在的 RCE primitive。
## 利用 `git rebase --exec` 实现 RCE
`git rebase` 支持 `--exec=<cmd>`,它会在回放 commits 后通过 `sh -c` 运行该命令。因此,如果一个 pull request 的 base branch 触发了类似下面的调用:
```bash
git rebase --quiet <baseBranch> <headBranch>
```
`<baseBranch>` 是由 attacker 控制的,一个诸如以下的 branch:
```bash
--exec=touch${IFS}/tmp/rce_proof
```
可以被解释为一个 **Git flag**,而不是一个 branch name。
### 为什么 `${IFS}` 重要
Git refs 不能包含字面上的空格,但当 Git 通过 `sh -c` 执行 `--exec` 时,shell expansion 仍然会发生。`${IFS}` 会在运行时展开为空白,因此可以使用如下 payload:
```bash
--exec=touch${IFS}/tmp/rce_proof
--exec=id${IFS}>/tmp/out
```
对于需要 Git 禁止字符(`:`, `~`, `^`, `?`, `*`, `[`, `\\`, `//`)的 payload,将真实命令进行编码,并在执行时解码:
```bash
--exec=echo${IFS}<base64_payload>|base64${IFS}-d|sh
```
## Windows-specific payload delivery
在 Windows 上,inline payloads 受限更多,因为 Git 将 branch refs 存储为文件,而 NTFS 禁止在文件名中使用诸如 `|` 之类的字符。一个实用的替代方法是:
1. 将一个 payload script 提交到 repository 中(例如 `.abcdef`
2. 创建一个 branch,如:
```bash
--exec=sh${IFS}.abcdef
```
如果 Git for Windows 通过 **MSYS2 `sh`** 启动 payloadPowerShell 元字符可能会被破坏。一个实用的 workaround 是让已提交的 script 调用:
```bash
cmd.exe //c .abcdef.bat
```
where `//c` is the MSYS2-safe form of Windows `/c`.
## Merge / PR state-machine abuse
When testing Git-hosting platforms, do not only review the final dangerous command. Also review **earlier validation paths** and **background rechecks**.
A useful exploitation pattern is:
1. Initial validation path uses a **safe** clone/fetch flow with `--end-of-options`, so the malicious branch is accepted as data
2. The pull request becomes **mergeable**
3. A later merge or checkout path reuses the stored branch name in an **unsafe** Git call
4. Code execution happens even if a later step fails and the UI returns **HTTP 500**
This means a feature can be exploitable even when the final merge ends in an error, and the target repository may be left in a **corrupted partial rebase state** after the payload already ran.
## Practical hunting ideas
When reviewing a Gogs instance or similar Git service, check for:
- Branch names beginning with `--`
- Merge failures involving `git checkout '--exec=...'`
- Pull requests stuck as mergeable even though later branch validation fails
- Repositories left in partial rebase / broken Git state after failed merges
- Unexpected committed helper files on Windows payload paths (for example dotfiles plus `.bat` launchers)
- Suspicious API tokens created shortly before failed PR merges
Example log artifact:
```text
merge: git checkout '--exec=<...>': exit status 128 - error: unknown option `exec=<...>'
```
## References
- [Rapid7 - 通过 Gogs 中的 Argument Injection 实现经过身份验证的 RCENOT FIXED](https://www.rapid7.com/blog/post/ve-authenticated-rce-via-argument-injection-gogs-unfixed)
- [Metasploit module PR for Gogs rebase argument injection](https://github.com/rapid7/metasploit-framework/pull/21515)
- [Git rebase documentation (`--exec`)](https://git-scm.com/docs/git-rebase)
{{#include ../../banners/hacktricks-training.md}}