From 4317b90953b115f2c2709f9df4b6ee906e3fc2c2 Mon Sep 17 00:00:00 2001 From: HackTricks News Bot Date: Thu, 28 May 2026 15:52:25 +0000 Subject: [PATCH] Add content from: Authenticated RCE via Argument Injection in Gogs Rebase Merg... --- src/SUMMARY.md | 1 + src/pentesting-ci-cd/gogs-security/README.md | 121 +++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 src/pentesting-ci-cd/gogs-security/README.md diff --git a/src/SUMMARY.md b/src/SUMMARY.md index 6d869aa4e..249c7d286 100644 --- a/src/SUMMARY.md +++ b/src/SUMMARY.md @@ -21,6 +21,7 @@ - [Basic Github Information](pentesting-ci-cd/github-security/basic-github-information.md) - [Gitea Security](pentesting-ci-cd/gitea-security/README.md) - [Basic Gitea Information](pentesting-ci-cd/gitea-security/basic-gitea-information.md) +- [Gogs Security](pentesting-ci-cd/gogs-security/README.md) - [Concourse Security](pentesting-ci-cd/concourse-security/README.md) - [Concourse Architecture](pentesting-ci-cd/concourse-security/concourse-architecture.md) - [Concourse Lab Creation](pentesting-ci-cd/concourse-security/concourse-lab-creation.md) diff --git a/src/pentesting-ci-cd/gogs-security/README.md b/src/pentesting-ci-cd/gogs-security/README.md new file mode 100644 index 000000000..f0073a559 --- /dev/null +++ b/src/pentesting-ci-cd/gogs-security/README.md @@ -0,0 +1,121 @@ +# Gogs Security + +{{#include ../../banners/hacktricks-training.md}} + +## What is Gogs + +**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. + +## Git option injection through refs / branch names + +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. + +Typical dangerous pattern: + +```bash +git +``` + +Safer pattern expected in defensive code: + +```bash +git -- +# or +git --end-of-options +``` + +A common false assumption is that validating the ref with `git rev-parse --verify ` is enough. It is **not**: + +- the attacker can first **create a real branch** whose name starts with `--` +- `rev-parse --verify` only checks that the ref resolves to an object +- a later unsafe Git invocation may still parse the same value as an **option** + +This turns any Git-hosting feature that reuses stored branch names into a potential RCE primitive. + +## Abusing `git rebase --exec` for RCE + +`git rebase` supports `--exec=`, which runs the command through `sh -c` after replaying commits. Therefore, if the base branch of a pull request reaches a call similar to: + +```bash +git rebase --quiet +``` + +and `` is attacker-controlled, a branch such as: + +```bash +--exec=touch${IFS}/tmp/rce_proof +``` + +can be interpreted as a **Git flag** instead of a branch name. + +### Why `${IFS}` matters + +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: + +```bash +--exec=touch${IFS}/tmp/rce_proof +--exec=id${IFS}>/tmp/out +``` + +For payloads requiring Git-forbidden characters (`:`, `~`, `^`, `?`, `*`, `[`, `\\`, `//`), encode the real command and decode it at execution time: + +```bash +--exec=echo${IFS}|base64${IFS}-d|sh +``` + +## Windows-specific payload delivery + +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: + +1. Commit a payload script into the repository (for example `.abcdef`) +2. Create a branch like: + +```bash +--exec=sh${IFS}.abcdef +``` + +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: + +```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 - Authenticated RCE via Argument Injection in Gogs (NOT 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}}