Sploitus

Exploit for Code Injection in Gitea

githubexploit · 2026-08-30

Exploit Code

README250 lines
## https://sploitus.com/exploit?id=3D4E19EA-2FCB-5209-9D72-74A347D2AC80
# 🫖 CVE-2026-60004 Gitea Validator

> A standalone discovery, assessment, and contract-correlated validation tool for the Gitea `diffpatch` Git-hook remote code execution vulnerability.

[![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
[![CVE](https://img.shields.io/badge/CVE-2026--60004-critical)](https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m)

`scanner.py` gives penetration testers, defenders, and security researchers one dependency-free tool for:

- 🔎 Passive Gitea discovery through LeakIX's existing index
- 🧭 Single-target public-route and Swagger reconnaissance
- 🩺 Non-destructive version assessment
- 🧪 Bounded, authenticated proof-of-concept validation
- 🧾 Contract-correlated JSON evidence and command-output capture
- 🛡️ Single-target controls, version gates, private output files, and same-origin credential handling

## ⚠️ Legal and ethical disclaimer

This project is provided **only for authorized security testing, defensive validation, research, and education**. Run active modes solely against systems you own or have explicit written permission to assess. You are responsible for complying with all applicable laws, contracts, rules of engagement, and disclosure requirements.

The authors and contributors are not responsible for misuse, damage, service interruption, data loss, or legal consequences. The active PoC executes a command as the Gitea operating-system user and changes server state by creating a private repository. Treat it like any other RCE validation tool.

## 🧠 Vulnerability summary

CVE-2026-60004 affects Gitea's repository `diffpatch` workflow. A repository writer can submit controlled patch content that installs a Git hook in a shared bare temporary clone. Applying the crafted patch twice triggers an add/add collision and causes the hook to execute as the Gitea service account.

| Item | Detail |
| --- | --- |
| Product | Gitea |
| Affected releases | `>= 1.17.0, < 1.27.1` |
| Patched release | `1.27.1` |
| Impact | Remote command execution as the Gitea OS user |
| Access required | Repository write access; open registration may allow an attacker to create it |
| Advisory | [GHSA-rcr6-4jqh-j84m](https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m) |

Forgejo and other forks are **not automatically classified as vulnerable**. Their implementation must be reviewed independently.

## ✨ What each mode does

| Mode | Network behavior | Changes target state? | Purpose |
| --- | --- | --- | --- |
| `discover` | Queries LeakIX only | No | Searches an existing third-party index; it does not contact discovered hosts |
| `recon` | One exact target | No | Inventories fixed public routes and the target-published Swagger document |
| `verify` | One exact target | No | Reads `/api/v1/version` and classifies the reported Gitea version |
| `test` | One exact target | **Yes** | Convenience flow: version gate, registration check, disposable account, marker, `id`, and evidence |
| `confirm` | One exact target | **Yes** | Controlled confirmation with an approved account or explicit disposable registration |

The active modes do not accept target lists or wildcards.

## 📦 Requirements

- Python 3.10 or newer
- Git available in `PATH`
- Network access to the explicitly selected Gitea target
- Valid Gitea credentials, or explicitly approved self-registration
- A written authorization/contract reference for active testing
- Optional: a LeakIX API key for `discover`

The scanner uses only Python's standard library. No `pip install` is required.

## 🚀 Install

```bash
git clone https://github.com/InfoSec-DB/CVE-2026-60004-Gitea-Validator.git
cd CVE-2026-60004-Gitea-Validator
python3 scanner.py --help
```

## 🩺 Start with non-destructive checks

### Check the reported version

```bash
python3 scanner.py verify \
  https://gitea.example \
  --contract-number ENG-2026-001 \
  --output evidence/version.json
```

### Inventory public routes and Swagger metadata

```bash
python3 scanner.py recon \
  https://gitea.example \
  --contract-number ENG-2026-001 \
  --output evidence/recon.json
```

Version detection is an assessment signal, not proof of exploitability. Backported patches, custom builds, reverse proxies, and forks can require manual review.

## 🧪 Authorized active confirmation

### Existing approved test account

Keep the password out of shell history by placing it in the environment for the command:

```bash
GITEA_PASSWORD='replace-with-approved-test-password' \
python3 scanner.py confirm \
  https://gitea.example \
  --contract-number ENG-2026-001 \
  --username audit-user \
  --execute-poc \
  --write-client-marker \
  --output evidence/confirmation.json
```

Unless `--yes-i-am-authorized` is supplied for automation, `confirm` asks you to type the contract-bound confirmation phrase. The default remote command is `id`.

### Disposable self-registration

Use this only when account creation is permitted by the rules of engagement:

```bash
python3 scanner.py confirm \
  https://gitea.example \
  --contract-number ENG-2026-001 \
  --register-test-account \
  --credential-log evidence/credentials.txt \
  --execute-poc \
  --write-client-marker \
  --output evidence/confirmation.json
```

The password is stored only in the private credential log, not duplicated into the JSON evidence or terminal result panel.

### One-command test profile

```bash
python3 scanner.py test \
  https://gitea.example \
  --contract-number ENG-2026-001
```

🚨 `test` is an **active** convenience command. On an affected target with registration enabled, it automatically creates an account and private repository, writes the contract marker, runs `id`, and saves results beneath `afterdark-results/`. It intentionally has no extra interactive prompt, so invoking it is the authorization acknowledgement.

### Custom command

For narrowly scoped, explicitly approved validation, `confirm` and `test` accept `--cmd`. Prefer the default `id` profile whenever it is sufficient.

```bash
GITEA_PASSWORD='replace-with-approved-test-password' \
python3 scanner.py confirm \
  https://gitea.example \
  --contract-number ENG-2026-001 \
  --username audit-user \
  --execute-poc \
  --cmd 'uname -a' \
  --output evidence/confirmation.json
```

## 🌐 Passive LeakIX discovery

```bash
export LEAKIX_API_KEY='replace-with-your-key'
python3 scanner.py discover \
  --method app \
  --pages 3 \
  --output evidence/leakix.json
```

To inspect LeakIX records for one known host without contacting that host:

```bash
python3 scanner.py discover \
  --method host \
  --target gitea.example \
  --pages 1 \
  --output evidence/leakix-host.json
```

Discovery results are leads, not authorization to scan or exploit the listed systems.

## 🔬 How the embedded PoC works

1. Confirms that the reported product/version passes the active-test gate.
2. Authenticates with an approved account or creates one disposable account when explicitly requested.
3. Creates a uniquely named private repository initialized with a default branch.
4. Builds a patch that adds an executable `hooks/post-index-change` file.
5. Submits the patch twice to the repository `diffpatch` API endpoint.
6. The hook runs the selected command and writes its combined output into Git objects.
7. A temporary Git client fetches the unique output reference.
8. The scanner writes contract-correlated evidence using private `0600` files and refuses to overwrite existing evidence.

Authenticated HTTP redirects are restricted to the selected target origin. Git output retrieval also disables redirects while the authorization header is active.

## 🧾 Evidence and sensitive-data handling

Active runs may produce:

- `confirmation.json` — timestamps, target, account name, version assessment, return code, and captured output
- `confirmation.command-output.txt` — full remote command output
- `credentials.txt` — generated disposable-account password, when requested
- `embedded-result.txt` content preserved inside the JSON evidence

These files can contain sensitive engagement data. They are ignored by the included `.gitignore`, created with mode `0600`, and should be encrypted at rest according to your evidence-handling policy.

## 🧹 Cleanup checklist

The tool deliberately avoids automatic deletion so evidence remains available for review. After testing, a target administrator should:

- Delete the generated `audit-*` account, if one was created
- Delete the generated private `afterdark-*` repository
- Remove the optional `/tmp/gitea-validation-*/client.txt` marker
- Securely archive or delete local credentials and evidence
- Upgrade Gitea to `1.27.1` or later
- Replay only the minimum safe validation needed to confirm remediation

Successful PoC execution demonstrates command execution as the Gitea service account. It does **not** by itself prove root access, persistence, lateral movement, or compromise of the underlying host.

## 🛡️ Safety controls

- Exact single-target URL only; no wildcard or target-file support
- Contract number included in the User-Agent and optional marker
- Active version gate blocks known patched releases
- Default command limited to `id` or `whoami`
- Explicit `--execute-poc` switch for `confirm`
- Self-registration is opt-in and skipped when disabled
- Same-origin redirect enforcement for authenticated HTTP requests
- Git redirects disabled during credentialed output retrieval
- Credentials passed to the child process in memory/environment, then redacted from captured output
- Private, exclusive-create evidence files; existing files are never overwritten
- 180-second child-process timeout and bounded output capture

## ✅ Run the tests

The included tests are local and make no network requests:

```bash
python3 -m unittest discover -s tests -v
```

## 🤝 Contributing

Responsible improvements are welcome—especially compatibility fixes, false-positive reductions, evidence-quality improvements, and safer cleanup workflows. Please do not submit real target details, credentials, private evidence, or weaponized payloads.

For a security issue in this tool itself, follow [SECURITY.md](SECURITY.md).

## 📚 References and credit

- [Official Gitea advisory: GHSA-rcr6-4jqh-j84m](https://github.com/go-gitea/gitea/security/advisories/GHSA-rcr6-4jqh-j84m)
- [Gitea releases](https://github.com/go-gitea/gitea/releases)
- CVE reporter credited by the upstream advisory: **NightRang3r**
- Validator maintained by the **AfterDark Security Research Group**

---

Made for careful researchers who believe a good PoC should be reproducible, attributable, and boring to clean up. 🛡️