mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-06-12 19:11:44 -07:00
Translated ['src/pentesting-ci-cd/gogs-security/README.md'] to es
This commit is contained in:
@@ -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}}
|
||||
Reference in New Issue
Block a user