Translated ['src/banners/hacktricks-training.md', 'src/pentesting-ci-cd/

This commit is contained in:
Translator
2025-01-02 01:13:27 +00:00
parent 599a50fbec
commit c14d2efa43
215 changed files with 1670 additions and 1679 deletions

View File

@@ -1,4 +1,4 @@
# Concourse Security
# Seguridad de Concourse
{{#include ../../banners/hacktricks-training.md}}

View File

@@ -1,12 +1,12 @@
# Concourse Architecture
# Arquitectura de Concourse
## Concourse Architecture
## Arquitectura de Concourse
{{#include ../../banners/hacktricks-training.md}}
[**Datos relevantes de la documentación de Concourse:**](https://concourse-ci.org/internals.html)
### Architecture
### Arquitectura
![](<../../images/image (187).png>)
@@ -14,24 +14,24 @@
El ATC es el corazón de Concourse. Ejecuta la **interfaz web y API** y es responsable de toda la **programación** de pipelines. Se **conecta a PostgreSQL**, que utiliza para almacenar datos de pipelines (incluidos los registros de compilación).
La responsabilidad del [checker](https://concourse-ci.org/checker.html) es verificar continuamente si hay nuevas versiones de recursos. El [scheduler](https://concourse-ci.org/scheduler.html) es responsable de programar compilaciones para un trabajo y el [build tracker](https://concourse-ci.org/build-tracker.html) es responsable de ejecutar cualquier compilación programada. El [garbage collector](https://concourse-ci.org/garbage-collector.html) es el mecanismo de limpieza para eliminar cualquier objeto no utilizado o desactualizado, como contenedores y volúmenes.
La responsabilidad del [checker](https://concourse-ci.org/checker.html) es verificar continuamente nuevas versiones de recursos. El [scheduler](https://concourse-ci.org/scheduler.html) es responsable de programar compilaciones para un trabajo y el [build tracker](https://concourse-ci.org/build-tracker.html) es responsable de ejecutar cualquier compilación programada. El [garbage collector](https://concourse-ci.org/garbage-collector.html) es el mecanismo de limpieza para eliminar cualquier objeto no utilizado o desactualizado, como contenedores y volúmenes.
#### TSA: registro de trabajadores y reenvío
El TSA es un **servidor SSH construido a medida** que se utiliza únicamente para **registrar** de forma segura a los [**trabajadores**](https://concourse-ci.org/internals.html#architecture-worker) con el [ATC](https://concourse-ci.org/internals.html#component-atc).
La TSA es un **servidor SSH construido a medida** que se utiliza únicamente para **registrar** de forma segura a los [**trabajadores**](https://concourse-ci.org/internals.html#architecture-worker) con el [ATC](https://concourse-ci.org/internals.html#component-atc).
El TSA por **defecto escucha en el puerto `2222`**, y generalmente está colocalizado con el [ATC](https://concourse-ci.org/internals.html#component-atc) y detrás de un balanceador de carga.
La TSA por **defecto escucha en el puerto `2222`**, y generalmente se encuentra junto al [ATC](https://concourse-ci.org/internals.html#component-atc) y detrás de un balanceador de carga.
El **TSA implementa CLI a través de la conexión SSH,** soportando [**estos comandos**](https://concourse-ci.org/internals.html#component-tsa).
La **TSA implementa CLI a través de la conexión SSH,** soportando [**estos comandos**](https://concourse-ci.org/internals.html#component-tsa).
#### Workers
#### Trabajadores
Para ejecutar tareas, Concourse debe tener algunos trabajadores. Estos trabajadores **se registran** a través del [TSA](https://concourse-ci.org/internals.html#component-tsa) y ejecutan los servicios [**Garden**](https://github.com/cloudfoundry-incubator/garden) y [**Baggageclaim**](https://github.com/concourse/baggageclaim).
Para ejecutar tareas, Concourse debe tener algunos trabajadores. Estos trabajadores **se registran** a través de la [TSA](https://concourse-ci.org/internals.html#component-tsa) y ejecutan los servicios [**Garden**](https://github.com/cloudfoundry-incubator/garden) y [**Baggageclaim**](https://github.com/concourse/baggageclaim).
- **Garden**: Esta es la **API de Gestión de Contenedores**, generalmente se ejecuta en **el puerto 7777** a través de **HTTP**.
- **Baggageclaim**: Esta es la **API de Gestión de Volúmenes**, generalmente se ejecuta en **el puerto 7788** a través de **HTTP**.
- **Garden**: Esta es la **API de Gestión de Contenedores**, que generalmente se ejecuta en **el puerto 7777** a través de **HTTP**.
- **Baggageclaim**: Esta es la **API de Gestión de Volúmenes**, que generalmente se ejecuta en **el puerto 7788** a través de **HTTP**.
## References
## Referencias
- [https://concourse-ci.org/internals.html](https://concourse-ci.org/internals.html)

View File

@@ -1,32 +1,32 @@
# Concourse Enumeration & Attacks
# Concourse Enumeración y Ataques
## Concourse Enumeration & Attacks
## Concourse Enumeración y Ataques
{{#include ../../banners/hacktricks-training.md}}
### User Roles & Permissions
### Roles de Usuario y Permisos
Concourse viene con cinco roles:
- _Concourse_ **Admin**: Este rol solo se otorga a los propietarios del **equipo principal** (equipo inicial predeterminado de concourse). Los administradores pueden **configurar otros equipos** (por ejemplo: `fly set-team`, `fly destroy-team`...). Los permisos de este rol no pueden ser afectados por RBAC.
- **owner**: Los propietarios del equipo pueden **modificar todo dentro del equipo**.
- **member**: Los miembros del equipo pueden **leer y escribir** dentro de los **activos del equipo** pero no pueden modificar la configuración del equipo.
- **pipeline-operator**: Los operadores de pipeline pueden realizar **operaciones de pipeline** como activar compilaciones y fijar recursos, sin embargo, no pueden actualizar las configuraciones de pipeline.
- **pipeline-operator**: Los operadores de pipeline pueden realizar **operaciones de pipeline** como activar construcciones y fijar recursos, sin embargo, no pueden actualizar las configuraciones de pipeline.
- **viewer**: Los espectadores del equipo tienen acceso **"solo de lectura" a un equipo** y sus pipelines.
> [!NOTE]
> Además, **los permisos de los roles owner, member, pipeline-operator y viewer pueden ser modificados** configurando RBAC (configurando más específicamente sus acciones). Lee más sobre esto en: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
> Además, los **permisos de los roles owner, member, pipeline-operator y viewer pueden ser modificados** configurando RBAC (configurando más específicamente sus acciones). Lee más sobre esto en: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
Ten en cuenta que Concourse **agrupa pipelines dentro de Equipos**. Por lo tanto, los usuarios que pertenecen a un Equipo podrán gestionar esos pipelines y **pueden existir varios Equipos**. Un usuario puede pertenecer a varios Equipos y tener diferentes permisos dentro de cada uno de ellos.
### Vars & Credential Manager
### Vars y Administrador de Credenciales
En las configuraciones YAML puedes configurar valores usando la sintaxis `((_source-name_:_secret-path_._secret-field_))`.\
[De la documentación:](https://concourse-ci.org/vars.html#var-syntax) El **source-name es opcional**, y si se omite, se utilizará el [gestor de credenciales a nivel de clúster](https://concourse-ci.org/vars.html#cluster-wide-credential-manager), o el valor puede ser proporcionado [estáticamente](https://concourse-ci.org/vars.html#static-vars).\
El **\_secret-field opcional**\_ especifica un campo en el secreto obtenido para leer. Si se omite, el gestor de credenciales puede optar por leer un 'campo predeterminado' del secreto obtenido si el campo existe.\
[De la documentación:](https://concourse-ci.org/vars.html#var-syntax) El **source-name es opcional**, y si se omite, se utilizará el [administrador de credenciales a nivel de clúster](https://concourse-ci.org/vars.html#cluster-wide-credential-manager), o el valor puede ser proporcionado [estáticamente](https://concourse-ci.org/vars.html#static-vars).\
El **\_secret-field opcional**\_ especifica un campo en el secreto obtenido para leer. Si se omite, el administrador de credenciales puede optar por leer un 'campo predeterminado' del secreto obtenido si el campo existe.\
Además, el _**secret-path**_ y _**secret-field**_ pueden estar rodeados por comillas dobles `"..."` si **contienen caracteres especiales** como `.` y `:`. Por ejemplo, `((source:"my.secret"."field:1"))` establecerá el _secret-path_ en `my.secret` y el _secret-field_ en `field:1`.
#### Static Vars
#### Vars Estáticas
Las vars estáticas pueden ser especificadas en **pasos de tareas**:
```yaml
@@ -34,16 +34,16 @@ Las vars estáticas pueden ser especificadas en **pasos de tareas**:
file: booklit/ci/unit.yml
vars: { tag: 1.13 }
```
Or usando los siguientes `fly` **argumentos**:
O usando los siguientes `fly` **argumentos**:
- `-v` o `--var` `NAME=VALUE` establece la cadena `VALUE` como el valor para la var `NAME`.
- `-y` o `--yaml-var` `NAME=VALUE` analiza `VALUE` como YAML y lo establece como el valor para la var `NAME`.
- `-i` o `--instance-var` `NAME=VALUE` analiza `VALUE` como YAML y lo establece como el valor para la var de instancia `NAME`. Consulta [Agrupación de Pipelines](https://concourse-ci.org/instanced-pipelines.html) para aprender más sobre las vars de instancia.
- `-l` o `--load-vars-from` `FILE` carga `FILE`, un documento YAML que contiene la asignación de nombres de var a valores, y los establece todos.
- `-v` o `--var` `NAME=VALUE` establece la cadena `VALUE` como el valor para la variable `NAME`.
- `-y` o `--yaml-var` `NAME=VALUE` analiza `VALUE` como YAML y lo establece como el valor para la variable `NAME`.
- `-i` o `--instance-var` `NAME=VALUE` analiza `VALUE` como YAML y lo establece como el valor para la variable de instancia `NAME`. Consulta [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html) para aprender más sobre las variables de instancia.
- `-l` o `--load-vars-from` `FILE` carga `FILE`, un documento YAML que contiene la asignación de nombres de variables a valores, y los establece todos.
#### Gestión de Credenciales
Hay diferentes formas en que se puede **especificar un Gestor de Credenciales** en un pipeline, lee cómo en [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
Hay diferentes formas en que un **Gestor de Credenciales puede ser especificado** en un pipeline, lee cómo en [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
Además, Concourse admite diferentes gestores de credenciales:
- [El gestor de credenciales Vault](https://concourse-ci.org/vault-credential-manager.html)
@@ -54,7 +54,7 @@ Además, Concourse admite diferentes gestores de credenciales:
- [El gestor de credenciales Conjur](https://concourse-ci.org/conjur-credential-manager.html)
- [Credenciales en caché](https://concourse-ci.org/creds-caching.html)
- [Redacción de credenciales](https://concourse-ci.org/creds-redacting.html)
- [Reintentar recuperaciones fallidas](https://concourse-ci.org/creds-retry-logic.html)
- [Reintentando fetches fallidos](https://concourse-ci.org/creds-retry-logic.html)
> [!CAUTION]
> Ten en cuenta que si tienes algún tipo de **acceso de escritura a Concourse** puedes crear trabajos para **exfiltrar esos secretos** ya que Concourse necesita poder acceder a ellos.
@@ -75,7 +75,7 @@ Para enumerar un entorno de concourse primero necesitas **reunir credenciales v
- `fly -t <target> userinfo`
> [!NOTE]
> Ten en cuenta que el **token de API** se **guarda** en `$HOME/.flyrc` por defecto, al saquear una máquina podrías encontrar allí las credenciales.
> Ten en cuenta que el **token API** se **guarda** en `$HOME/.flyrc` por defecto, si estás saqueando una máquina podrías encontrar allí las credenciales.
#### Equipos y Usuarios
@@ -90,7 +90,7 @@ Para enumerar un entorno de concourse primero necesitas **reunir credenciales v
- **Listar** pipelines:
- `fly -t <target> pipelines -a`
- **Obtener** yaml de pipeline (**información sensible** podría encontrarse en la definición):
- **Obtener** yaml del pipeline (**información sensible** podría encontrarse en la definición):
- `fly -t <target> get-pipeline -p <pipeline-name>`
- Obtener todas las **vars declaradas en la configuración del pipeline**
- `for pipename in $(fly -t <target> pipelines | grep -Ev "^id" | awk '{print $2}'); do echo $pipename; fly -t <target> get-pipeline -p $pipename -j | grep -Eo '"vars":[^}]+'; done`
@@ -125,11 +125,11 @@ rm /tmp/secrets.txt
#### Enumeración de secretos y parámetros
En la sección anterior vimos cómo puedes **obtener todos los nombres y vars de los secretos** utilizados por el pipeline. Las **vars pueden contener información sensible** y el nombre de los **secretos será útil más adelante para intentar robar**los.
En la sección anterior vimos cómo puedes **obtener todos los nombres y vars de los secretos** utilizados por el pipeline. Las **vars pueden contener información sensible** y el nombre de los **secretos será útil más adelante para intentar robarlos**.
#### Sesión dentro de un contenedor en ejecución o recientemente ejecutado
Si tienes suficientes privilegios (**rol de miembro o más**) podrás **listar pipelines y roles** y simplemente obtener una **sesión dentro** del contenedor de `<pipeline>/<job>` usando:
Si tienes suficientes privilegios (**rol de miembro o más**) podrás **listar pipelines y roles** y simplemente obtener una **sesión dentro** del **contenedor** `<pipeline>/<job>` usando:
```bash
fly -t tutorial intercept --job pipeline-name/job-name
fly -t tutorial intercept # To be presented a prompt with all the options
@@ -170,7 +170,7 @@ Con la **modificación/creación** de un nuevo pipeline podrás:
- **Robar** los **secretos** (a través de su impresión o accediendo al contenedor y ejecutando `env`)
- **Escapar** al **nodo** (dándote suficientes privilegios - `privileged: true`)
- Enumerar/Abusar del **endpoint de metadatos de la nube** (desde el pod y desde el nodo)
- Enumerar/Abusar del endpoint de **metadata** de **cloud** (desde el pod y desde el nodo)
- **Eliminar** el pipeline creado
#### Ejecutar Tarea Personalizada
@@ -199,7 +199,7 @@ fly -t tutorial execute --privileged --config task_config.yml
```
#### Escapando al nodo desde una tarea privilegiada
En las secciones anteriores vimos cómo **ejecutar una tarea privilegiada con concourse**. Esto no le dará al contenedor exactamente el mismo acceso que la bandera privilegiada en un contenedor de docker. Por ejemplo, no verá el dispositivo del sistema de archivos del nodo en /dev, por lo que la escapatoria podría ser más "compleja".
En las secciones anteriores vimos cómo **ejecutar una tarea privilegiada con concourse**. Esto no le dará al contenedor exactamente el mismo acceso que la bandera privilegiada en un contenedor docker. Por ejemplo, no verá el dispositivo del sistema de archivos del nodo en /dev, por lo que la escapatoria podría ser más "compleja".
En la siguiente PoC vamos a usar el release_agent para escapar con algunas pequeñas modificaciones:
```bash
@@ -291,7 +291,7 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
# Reads the output
cat /output
```
#### Escapando al nodo desde el contenedor web
#### Escapando al nodo desde el contenedor Web
Incluso si el contenedor web tiene algunas defensas deshabilitadas, **no se está ejecutando como un contenedor privilegiado común** (por ejemplo, **no puedes** **montar** y las **capacidades** son muy **limitadas**, por lo que todas las formas fáciles de escapar del contenedor son inútiles).
@@ -330,11 +330,11 @@ select * from users;
#### Abusando del Servicio Garden - No es un Ataque Real
> [!WARNING]
> Estas son solo algunas notas interesantes sobre el servicio, pero dado que solo está escuchando en localhost, estas notas no presentarán ningún impacto que no hayamos explotado antes.
> Estas son solo algunas notas interesantes sobre el servicio, pero dado que solo está escuchando en localhost, estas notas no presentarán ningún impacto que no hayamos explotado ya antes.
Por defecto, cada trabajador de concourse estará ejecutando un servicio [**Garden**](https://github.com/cloudfoundry/garden) en el puerto 7777. Este servicio es utilizado por el maestro web para indicar al trabajador **lo que necesita ejecutar** (descargar la imagen y ejecutar cada tarea). Esto suena bastante bien para un atacante, pero hay algunas buenas protecciones:
Por defecto, cada trabajador de concourse estará ejecutando un [**Garden**](https://github.com/cloudfoundry/garden) en el puerto 7777. Este servicio es utilizado por el maestro web para indicar al trabajador **lo que necesita ejecutar** (descargar la imagen y ejecutar cada tarea). Esto suena bastante bien para un atacante, pero hay algunas buenas protecciones:
- Está **expuesto localmente** (127..0.0.1) y creo que cuando el trabajador se autentica contra la Web con el servicio SSH especial, se crea un túnel para que el servidor web pueda **hablar con cada servicio Garden** dentro de cada trabajador.
- Está **expuesto localmente** (127..0.0.1) y creo que cuando el trabajador se autentica contra la web con el servicio SSH especial, se crea un túnel para que el servidor web pueda **hablar con cada servicio Garden** dentro de cada trabajador.
- El servidor web está **monitoreando los contenedores en ejecución cada pocos segundos**, y los contenedores **inesperados** son **eliminados**. Así que si quieres **ejecutar un contenedor personalizado** necesitas **manipular** la **comunicación** entre el servidor web y el servicio garden.
Los trabajadores de Concourse se ejecutan con altos privilegios de contenedor:
@@ -353,7 +353,7 @@ Sin embargo, técnicas como **montar** el dispositivo /dev del nodo o release_ag
> [!NOTE]
> En la sección anterior vimos cómo escapar de un contenedor privilegiado, así que si podemos **ejecutar** comandos en un **contenedor privilegiado** creado por el **trabajador** **actual**, podríamos **escapar al nodo**.
Ten en cuenta que al jugar con concourse noté que cuando se genera un nuevo contenedor para ejecutar algo, los procesos del contenedor son accesibles desde el contenedor del trabajador, por lo que es como si un contenedor creara un nuevo contenedor dentro de él.
Ten en cuenta que al jugar con concourse noté que cuando se genera un nuevo contenedor para ejecutar algo, los procesos del contenedor son accesibles desde el contenedor del trabajador, así que es como si un contenedor estuviera creando un nuevo contenedor dentro de él.
**Entrando en un contenedor privilegiado en ejecución**
```bash

View File

@@ -17,7 +17,7 @@ Puedes descargar la línea de comandos `fly` para tu sistema operativo desde la
#### Con Kubernetes (Recomendado)
Puedes desplegar concourse fácilmente en **Kubernetes** (en **minikube** por ejemplo) usando el helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
Puedes desplegar fácilmente concourse en **Kubernetes** (en **minikube** por ejemplo) utilizando el helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
```bash
brew install helm
helm repo add concourse https://concourse-charts.storage.googleapis.com/
@@ -75,17 +75,17 @@ Un pipeline está compuesto por una lista de [Jobs](https://concourse-ci.org/job
Se pueden utilizar varios tipos diferentes de pasos:
- **el** [**paso `task`**](https://concourse-ci.org/task-step.html) **ejecuta una** [**tarea**](https://concourse-ci.org/tasks.html)
- **el** [**`task` step**](https://concourse-ci.org/task-step.html) **ejecuta una** [**tarea**](https://concourse-ci.org/tasks.html)
- el [`get` step](https://concourse-ci.org/get-step.html) obtiene un [recurso](https://concourse-ci.org/resources.html)
- el [`put` step](https://concourse-ci.org/put-step.html) actualiza un [recurso](https://concourse-ci.org/resources.html)
- el [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) configura un [pipeline](https://concourse-ci.org/pipelines.html)
- el [`load_var` step](https://concourse-ci.org/load-var-step.html) carga un valor en una [var local](https://concourse-ci.org/vars.html#local-vars)
- el [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) ejecuta pasos en paralelo
- el [`do` step](https://concourse-ci.org/do-step.html) ejecuta pasos en secuencia
- el modificador de paso [`across`](https://concourse-ci.org/across-step.html#schema.across) ejecuta un paso múltiples veces; una vez por cada combinación de valores de variable
- el modificador [`across` step](https://concourse-ci.org/across-step.html#schema.across) ejecuta un paso múltiples veces; una vez por cada combinación de valores de variable
- el [`try` step](https://concourse-ci.org/try-step.html) intenta ejecutar un paso y tiene éxito incluso si el paso falla
Cada [step](https://concourse-ci.org/steps.html) en un [plan de trabajo](https://concourse-ci.org/jobs.html#schema.job.plan) se ejecuta en su **propio contenedor**. Puedes ejecutar lo que desees dentro del contenedor _(es decir, ejecutar mis pruebas, ejecutar este script bash, construir esta imagen, etc.)_. Así que si tienes un trabajo con cinco pasos, Concourse creará cinco contenedores, uno para cada paso.
Cada [step](https://concourse-ci.org/steps.html) en un [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) se ejecuta en su **propio contenedor**. Puedes ejecutar lo que desees dentro del contenedor _(es decir, ejecutar mis pruebas, ejecutar este script bash, construir esta imagen, etc.)_. Así que si tienes un trabajo con cinco pasos, Concourse creará cinco contenedores, uno para cada paso.
Por lo tanto, es posible indicar el tipo de contenedor en el que cada paso necesita ser ejecutado.
@@ -138,6 +138,6 @@ No necesitas activar los trabajos manualmente cada vez que necesites ejecutarlos
- Nuevas PR's: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
- Obtener o enviar la última imagen de tu aplicación: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
Consulta un ejemplo de tubería YAML que se activa con nuevos commits a master en [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
Consulta un ejemplo de tubería YAML que se activa con nuevos commits en master en [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
{{#include ../../banners/hacktricks-training.md}}