
Forgejo 16.0.5 - Alta - Remota - Lectura de archivos - restore-repo sigue file:// del lado del volcado hacia los adjuntos
abraxaslabs.tech · github.com/abraxas · @abraxas_null · [email protected] · forgejo-restore-file-open
Clase: Lectura de archivos Alcance: Local
Forgejo 16.0.5 (8d24b7d) - Forgejo
forgejo restore-repo de un volcado no confiable reescribe las URLs de los recursos de la release con filepath.Join(baseDir, download_url) en crudo y les antepone file://. uri.Open sigue haciendo os.Open sobre esa ruta. Un --units vacío restaura las releases. Gitea 1.27.0 añadió localFileURL y omitió el escape de las entradas. Ese helper no está aquí.
La restauración por parte del operador de un volcado no confiable copia un archivo del host que el uid de forgejo puede abrir dentro de un adjunto de release.
| ID | sin CVE todavía |
| Clase | Lectura de archivos |
| Alcance | Local (operador forgejo restore-repo de un volcado no confiable) |
| CWE | CWE-22 / CWE-73 |
| CVSS | Alto: 7.3 CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:C/C:H/I:N/A:N |
| Producto | Forgejo |
| Afectado | hasta v16.0.5 (8d24b7d); restauración por operador local |
| Auth | restauración por operador local de un volcado no confiable |
| Licencia | GNU Affero GPL v3.0 |
| Lab | solo 127.0.0.1 |
Entregar al operador un directorio de volcado (o ya disponer de INTERNAL_TOKEN y una ruta que el servidor pueda leer). Las unidades incluyen releases / release_assets.
| Privilegio | Método / sink | Recon / integridad / disponibilidad | Probado en lab o inferido |
|---|---|---|---|
Leer un archivo del host que el uid de forgejo puede abrir, mediante .. fuera del volcado | release.yml download_url: ../FORGEJO-FILE-WITNESS.txt; la restauración hace el join, uri.Open hace os.Open, los bytes se almacenan como witness.txt | Recon (confidencialidad de archivos del host) | Probado en lab. El cuerpo del adjunto es FORGEJO-RESTORE-FILE-OPEN-WITNESS. El señuelo dentro del volcado INSIDE-DUMP-NOT-HOST no fue servido |
| Mismo resultado con un symlink plantado dentro del volcado | La ruta unida permanece bajo baseDir; os.Open sigue el enlace | Recon | Inferido de uri.Open file -> os.Open. El lab usó .., no un symlink |
| Mismo sink en los parches de PR | pull_request.yml PatchURL se reescribe de la misma forma, y luego uri.Open hacia repo/pulls/<n>.patch | Recon | Inferido de restore.go GetPullRequests. El lab solo restauró releases |
| Los lectores del repo restaurado descargan el archivo del host | GET /<owner>/<repo>/releases/download/<tag>/<name> | Recon | Probado en lab como labadmin Basic sobre el repo público restaurado |
Archivos típicos del host: app.ini, INTERNAL_TOKEN, SECRET_KEY, contraseña de la BD | el uid de forgejo puede leer el árbol de configuración | Recon | Inferido. El testigo del lab era un archivo plantado junto al volcado, no secretos reales |
Descartado aquí: LFI file:// en vivo vía POST /repos/migrate (DownloadFunc establecido; PatchURL de PR verificado por prefijo contra la base HTTP del clon). Escape del join de la raíz del volcado mediante DownloadURL absoluto (en Go filepath.Join("/dump", "/etc/passwd") permanece /dump/etc/passwd). Restauración HTTP sin autenticación (solo CLI / token interno). Empaquetado de app.ini en el dump de backup (secretos por diseño, modo de archivo 0600). No es LPE del SO. No es LFI remoto.
Tenía dos ideas de restauración. Primero imaginé el join absoluto de Gitea en mi cabeza. filepath.Join de Go no descarta un segundo argumento absoluto como sí hace os.path.join de Python. La entrada que funciona es .. relativo. El localFileURL de Gitea no está en este árbol.
Caminos equivocados ya registrados: escape del join de la raíz del volcado mediante un DownloadURL absoluto; LFI file:// en migrate en vivo; X-Forgejo-Internal-Auth (la restauración es CLI como el uid de forgejo, no /api/internal); tratar la restauración HTTP como remota sin autenticación; una reverse shell. Teatro.
python3 forgejo-restore-file-open-Abraxas-Labs.py
o:
cd lab
./run.sh
Objetivo solo http://127.0.0.1:19340. Imagen codeberg.org/forgejo/forgejo:16.0.5. Testigo 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
Contener las rutas unidas bajo baseDir tras EvalSymlinks (Gitea PR 38215 localFileURL). Rechazar ... No seguir symlinks del lado del volcado fuera del volcado. Eliminar file:// de uri.Open salvo en un helper con raíz en el volcado.
restore.go · uri.goGNU Affero GPL v3.0. Ver LICENSE. Solo lab en loopback. Sin garantía.