
Forgejo 16.0.5 - Élevé - À distance - Lecture de fichier - restore-repo suit file:// côté dump vers les pièces jointes
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · forgejo-restore-file-open
Classe : Lecture de fichier Portée : Locale
Forgejo 16.0.5 (8d24b7d) - Forgejo
forgejo restore-repo d'un dump non fiable réécrit les URLs des assets de release avec un filepath.Join(baseDir, download_url) brut et préfixe file://. uri.Open fait toujours un os.Open sur ce chemin. Un --units vide restaure les releases. Gitea 1.27.0 a ajouté localFileURL et ignoré l'échappement des entrées. Ce helper n'est pas présent ici.
La restauration par l'opérateur d'un dump non fiable copie un fichier hôte que l'uid forgejo peut ouvrir dans une pièce jointe de release.
| ID | pas encore de CVE |
| Classe | Lecture de fichier |
| Portée | Locale (opérateur forgejo restore-repo d'un dump non fiable) |
| CWE | CWE-22 / CWE-73 |
| CVSS | Élevé : 7.3 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N |
| Produit | Forgejo |
| Affecté | jusqu'à v16.0.5 (8d24b7d) ; restauration par l'opérateur local |
| Auth | restauration par l'opérateur local d'un dump non fiable |
| Licence | GNU Affero GPL v3.0 |
| Lab | 127.0.0.1 uniquement |
Fournir à l'opérateur un répertoire de dump (ou disposer déjà de INTERNAL_TOKEN et d'un chemin que le serveur peut lire). Les units incluent releases / release_assets.
| Privilège | Méthode / sink | Recon / intégrité / disponibilité | Prouvé en lab ou déduit |
|---|---|---|---|
Lire un fichier hôte que l'uid forgejo peut ouvrir, via .. hors du dump | release.yml download_url: ../FORGEJO-FILE-WITNESS.txt ; la restauration joint, uri.Open fait un os.Open, les octets sont stockés comme witness.txt | Recon (confidentialité du fichier hôte) | Prouvé en lab. Le corps de la pièce jointe est FORGEJO-RESTORE-FILE-OPEN-WITNESS. Le leurre dans le dump INSIDE-DUMP-NOT-HOST n'a pas été servi |
| Même résultat avec un lien symbolique planté dans le dump | Le chemin joint reste sous baseDir ; os.Open suit le lien | Recon | Déduit de uri.Open file -> os.Open. Le lab a utilisé .., pas un lien symbolique |
| Même sink sur les patches de PR | pull_request.yml PatchURL est réécrit de la même manière, puis uri.Open vers repo/pulls/<n>.patch | Recon | Déduit de restore.go GetPullRequests. Le lab n'a restauré que les releases |
| Les lecteurs du dépôt restauré téléchargent le fichier hôte | GET /<owner>/<repo>/releases/download/<tag>/<name> | Recon | Prouvé en lab en tant que labadmin Basic sur le dépôt public restauré |
Fichiers hôtes typiques : app.ini, INTERNAL_TOKEN, SECRET_KEY, mot de passe DB | l'uid forgejo peut lire l'arborescence de configuration | Recon | Déduit. Le témoin du lab était un fichier planté à côté du dump, pas des secrets réels |
Écarté ici : LFI file:// en direct via POST /repos/migrate (DownloadFunc défini ; PatchURL de PR vérifié par préfixe contre la base HTTP du clone). Échappement par jointure à la racine du dump via un DownloadURL absolu (en Go filepath.Join("/dump", "/etc/passwd") reste /dump/etc/passwd). Restauration HTTP non authentifiée (CLI / token interne uniquement). Empaquetage de app.ini par le dump de sauvegarde (secrets par conception, mode d'archive 0600). Pas de LPE OS. Pas de LFI distant.
J'avais deux idées de restauration. J'ai d'abord testé mentalement la jointure absolue de Gitea. Le filepath.Join de Go ne supprime pas un second argument absolu comme le fait os.path.join de Python. L'entrée qui fonctionne est le .. relatif. Le localFileURL de Gitea n'est pas dans cet arbre.
Fausses pistes déjà consignées : échappement par jointure à la racine du dump via un DownloadURL absolu ; LFI file:// en direct via migrate ; X-Forgejo-Internal-Auth (la restauration est en CLI en tant qu'uid forgejo, pas /api/internal) ; considérer la restauration HTTP comme distante non authentifiée ; un reverse shell. Du théâtre.
python3 forgejo-restore-file-open-Abraxas-Labs.py
ou :
cd lab
./run.sh
Cible uniquement http://127.0.0.1:19340. Image codeberg.org/forgejo/forgejo:16.0.5. Témoin FORGEJO-RESTORE-FILE-OPEN-WITNESS.
IOC asset name='witness.txt' ...
IOC download status=200 bytes=34 snippet=b'FORGEJO-RESTORE-FILE-OPEN-WITNESS\n'
SUCCESS forgejo-restore-file-open how=live ..-join file:// os.Open FORGEJO-RESTORE-FILE-OPEN-WITNESS
Contenir les chemins joints sous baseDir après EvalSymlinks (Gitea PR 38215 localFileURL). Refuser ... Ne pas suivre les liens symboliques côté dump hors du dump. Supprimer file:// de uri.Open sauf pour un helper enraciné dans le dump.
restore.go · uri.goGNU Affero GPL v3.0. Voir LICENSE. Lab en loopback uniquement. Aucune garantie.