Translated ['src/pentesting-ci-cd/gogs-security/README.md'] to es

This commit is contained in:
Translator
2026-06-05 13:58:21 +00:00
parent a70d67b7cc
commit f4d499df05
@@ -0,0 +1,103 @@
# Gogs Security
{{#include ../../banners/hacktricks-training.md}}
## Qué es Gogs
**Gogs** es un **servicio Git ligero autoalojado** escrito en Go. Desde el punto de vista de un atacante, trátalo como una **plataforma de hosting Git multi-tenant** donde un usuario con pocos privilegios aún puede controlar nombres de ramas, pull requests, webhooks, tokens y la configuración del repositorio.
## Inyección de opciones de Git a través de refs / nombres de ramas
Si una aplicación pasa un **ref name** controlado por el atacante directamente a un comando de Git **sin `--` o `--end-of-options`**, una rama que comience con `--` puede ser analizada como una **opción de Git** en lugar de como datos.
Patrón peligroso típico:
```bash
git <subcommand> <user-controlled-ref>
```
Patrón más seguro esperado en código defensivo:
```bash
git <subcommand> -- <user-controlled-ref>
# or
git <subcommand> --end-of-options <user-controlled-ref>
```
Una suposición falsa común es que validar el ref con `git rev-parse --verify <ref>` es suficiente. **No** lo es:
- el atacante puede primero **crear una branch real** cuyo nombre empiece con `--`
- `rev-parse --verify` solo comprueba que el ref resuelve a un object
- una posterior invocación insegura de Git aún puede interpretar el mismo valor como una **option**
Esto convierte cualquier feature de Git-hosting que reutilice nombres de branch almacenados en un posible primitive de RCE.
## Abusing `git rebase --exec` for RCE
`git rebase` soporta `--exec=<cmd>`, que ejecuta el comando a través de `sh -c` después de reaplicar commits. Therefore, si la base branch de una pull request llega a una llamada similar a:
```bash
git rebase --quiet <baseBranch> <headBranch>
```
y `<baseBranch>` está controlado por el atacante, una rama como:
```bash
--exec=touch${IFS}/tmp/rce_proof
```
puede interpretarse como una **Git flag** en lugar de un nombre de branch.
### Por qué importa `${IFS}`
Las refs de Git no pueden contener espacios literales, pero la expansión del shell sigue ocurriendo cuando Git ejecuta `--exec` mediante `sh -c`. `${IFS}` se expande a espacios en tiempo de ejecución, permitiendo payloads como:
```bash
--exec=touch${IFS}/tmp/rce_proof
--exec=id${IFS}>/tmp/out
```
Para payloads que requieran caracteres prohibidos por Git (`:`, `~`, `^`, `?`, `*`, `[`, `\\`, `//`), codifica el comando real y decodifícalo en tiempo de ejecución:
```bash
--exec=echo${IFS}<base64_payload>|base64${IFS}-d|sh
```
## Entrega de payload específica de Windows
En Windows, los inline payloads están más limitados porque Git almacena los branch refs como archivos y NTFS prohíbe caracteres como `|` en los nombres de archivo. Una alternativa práctica es:
1. Hacer commit de un script de payload en el repository (por ejemplo `.abcdef`)
2. Crear un branch como:
```bash
--exec=sh${IFS}.abcdef
```
Si Git for Windows lanza el payload a través de **MSYS2 `sh`**, los metacaracteres de PowerShell pueden quedar alterados. Un workaround práctico es dejar que el script comprometido llame:
```bash
cmd.exe //c .abcdef.bat
```
donde `//c` es la forma compatible con MSYS2 de Windows `/c`.
## Abuso de la state-machine de Merge / PR
Al probar plataformas de alojamiento Git, no revises solo el comando peligroso final. Revisa también las **rutas de validación anteriores** y las **revalidaciones en background**.
Un patrón útil de explotación es:
1. La ruta de validación inicial usa un flujo de clone/fetch **seguro** con `--end-of-options`, así que la rama maliciosa se acepta como datos
2. El pull request pasa a ser **mergeable**
3. Una ruta posterior de merge o checkout reutiliza el nombre de la rama almacenado en una llamada Git **insegura**
4. La ejecución de código ocurre incluso si un paso posterior falla y la UI devuelve **HTTP 500**
Esto significa que una feature puede ser explotable incluso cuando el merge final termina en error, y el repositorio objetivo puede quedar en un estado de **rebase parcial corrupto** después de que el payload ya se ejecutó.
## Ideas prácticas de hunting
Al revisar una instancia de Gogs o un servicio Git similar, comprueba:
- Nombres de ramas que empiezan por `--`
- Fallos de merge que involucren `git checkout '--exec=...'`
- Pull requests atascados como mergeable aunque la validación posterior de la rama falle
- Repositorios dejados en un estado de rebase parcial / Git roto después de merges fallidos
- Archivos helper comprometidos inesperados en rutas de payload de Windows (por ejemplo, dotfiles junto con launchers `.bat`)
- API tokens sospechosos creados poco antes de merges fallidos de PR
Ejemplo de artefacto de log:
```text
merge: git checkout '--exec=<...>': exit status 128 - error: unknown option `exec=<...>'
```
## References
- [Rapid7 - Authenticated RCE via Argument Injection in Gogs (NOT FIXED)](https://www.rapid7.com/blog/post/ve-authenticated-rce-via-argument-injection-gogs-unfixed)
- [Metasploit module PR for Gogs rebase argument injection](https://github.com/rapid7/metasploit-framework/pull/21515)
- [Git rebase documentation (`--exec`)](https://git-scm.com/docs/git-rebase)
{{#include ../../banners/hacktricks-training.md}}