Skip to content

Commit 4317b90

Browse files
author
HackTricks News Bot
committed
Add content from: Authenticated RCE via Argument Injection in Gogs Rebase Merg...
1 parent 2aea30d commit 4317b90

2 files changed

Lines changed: 122 additions & 0 deletions

File tree

src/SUMMARY.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
- [Basic Github Information](pentesting-ci-cd/github-security/basic-github-information.md)
2222
- [Gitea Security](pentesting-ci-cd/gitea-security/README.md)
2323
- [Basic Gitea Information](pentesting-ci-cd/gitea-security/basic-gitea-information.md)
24+
- [Gogs Security](pentesting-ci-cd/gogs-security/README.md)
2425
- [Concourse Security](pentesting-ci-cd/concourse-security/README.md)
2526
- [Concourse Architecture](pentesting-ci-cd/concourse-security/concourse-architecture.md)
2627
- [Concourse Lab Creation](pentesting-ci-cd/concourse-security/concourse-lab-creation.md)
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
# Gogs Security
2+
3+
{{#include ../../banners/hacktricks-training.md}}
4+
5+
## What is Gogs
6+
7+
**Gogs** is a **self-hosted lightweight Git service** written in Go. From an attacker point of view, treat it as a **multi-tenant Git hosting platform** where a low-privileged user may still control branch names, pull requests, webhooks, tokens, and repository settings.
8+
9+
## Git option injection through refs / branch names
10+
11+
If an application passes an attacker-controlled **ref name** directly to a Git command **without `--` or `--end-of-options`**, a branch beginning with `--` can be parsed as a **Git option** instead of as data.
12+
13+
Typical dangerous pattern:
14+
15+
```bash
16+
git <subcommand> <user-controlled-ref>
17+
```
18+
19+
Safer pattern expected in defensive code:
20+
21+
```bash
22+
git <subcommand> -- <user-controlled-ref>
23+
# or
24+
git <subcommand> --end-of-options <user-controlled-ref>
25+
```
26+
27+
A common false assumption is that validating the ref with `git rev-parse --verify <ref>` is enough. It is **not**:
28+
29+
- the attacker can first **create a real branch** whose name starts with `--`
30+
- `rev-parse --verify` only checks that the ref resolves to an object
31+
- a later unsafe Git invocation may still parse the same value as an **option**
32+
33+
This turns any Git-hosting feature that reuses stored branch names into a potential RCE primitive.
34+
35+
## Abusing `git rebase --exec` for RCE
36+
37+
`git rebase` supports `--exec=<cmd>`, which runs the command through `sh -c` after replaying commits. Therefore, if the base branch of a pull request reaches a call similar to:
38+
39+
```bash
40+
git rebase --quiet <baseBranch> <headBranch>
41+
```
42+
43+
and `<baseBranch>` is attacker-controlled, a branch such as:
44+
45+
```bash
46+
--exec=touch${IFS}/tmp/rce_proof
47+
```
48+
49+
can be interpreted as a **Git flag** instead of a branch name.
50+
51+
### Why `${IFS}` matters
52+
53+
Git refs cannot contain literal spaces, but shell expansion still happens when Git executes `--exec` via `sh -c`. `${IFS}` expands to whitespace at runtime, allowing payloads such as:
54+
55+
```bash
56+
--exec=touch${IFS}/tmp/rce_proof
57+
--exec=id${IFS}>/tmp/out
58+
```
59+
60+
For payloads requiring Git-forbidden characters (`:`, `~`, `^`, `?`, `*`, `[`, `\\`, `//`), encode the real command and decode it at execution time:
61+
62+
```bash
63+
--exec=echo${IFS}<base64_payload>|base64${IFS}-d|sh
64+
```
65+
66+
## Windows-specific payload delivery
67+
68+
On Windows, inline payloads are more constrained because Git stores branch refs as files and NTFS forbids characters such as `|` in filenames. A practical alternative is:
69+
70+
1. Commit a payload script into the repository (for example `.abcdef`)
71+
2. Create a branch like:
72+
73+
```bash
74+
--exec=sh${IFS}.abcdef
75+
```
76+
77+
If Git for Windows launches the payload through **MSYS2 `sh`**, PowerShell metacharacters may be mangled. A practical workaround is to let the committed script call:
78+
79+
```bash
80+
cmd.exe //c .abcdef.bat
81+
```
82+
83+
where `//c` is the MSYS2-safe form of Windows `/c`.
84+
85+
## Merge / PR state-machine abuse
86+
87+
When testing Git-hosting platforms, do not only review the final dangerous command. Also review **earlier validation paths** and **background rechecks**.
88+
89+
A useful exploitation pattern is:
90+
91+
1. Initial validation path uses a **safe** clone/fetch flow with `--end-of-options`, so the malicious branch is accepted as data
92+
2. The pull request becomes **mergeable**
93+
3. A later merge or checkout path reuses the stored branch name in an **unsafe** Git call
94+
4. Code execution happens even if a later step fails and the UI returns **HTTP 500**
95+
96+
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.
97+
98+
## Practical hunting ideas
99+
100+
When reviewing a Gogs instance or similar Git service, check for:
101+
102+
- Branch names beginning with `--`
103+
- Merge failures involving `git checkout '--exec=...'`
104+
- Pull requests stuck as mergeable even though later branch validation fails
105+
- Repositories left in partial rebase / broken Git state after failed merges
106+
- Unexpected committed helper files on Windows payload paths (for example dotfiles plus `.bat` launchers)
107+
- Suspicious API tokens created shortly before failed PR merges
108+
109+
Example log artifact:
110+
111+
```text
112+
merge: git checkout '--exec=<...>': exit status 128 - error: unknown option `exec=<...>'
113+
```
114+
115+
## References
116+
117+
- [Rapid7 - Authenticated RCE via Argument Injection in Gogs (NOT FIXED)](https://www.rapid7.com/blog/post/ve-authenticated-rce-via-argument-injection-gogs-unfixed)
118+
- [Metasploit module PR for Gogs rebase argument injection](https://github.com/rapid7/metasploit-framework/pull/21515)
119+
- [Git rebase documentation (`--exec`)](https://git-scm.com/docs/git-rebase)
120+
121+
{{#include ../../banners/hacktricks-training.md}}

0 commit comments

Comments
 (0)