mirror of
https://github.com/HackTricks-wiki/hacktricks-cloud.git
synced 2026-01-08 19:30:51 -08:00
Translated ['src/banners/hacktricks-training.md', 'src/pentesting-ci-cd/
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Concourse Security
|
||||
# Sicurezza di Concourse
|
||||
|
||||
{{#include ../../banners/hacktricks-training.md}}
|
||||
|
||||
@@ -8,13 +8,13 @@ Concourse ti consente di **creare pipeline** per eseguire automaticamente test,
|
||||
|
||||
## Architettura di Concourse
|
||||
|
||||
Scopri come è strutturato l'ambiente concourse in:
|
||||
Scopri come è strutturato l'ambiente di concourse in:
|
||||
|
||||
{{#ref}}
|
||||
concourse-architecture.md
|
||||
{{#endref}}
|
||||
|
||||
## Laboratorio Concourse
|
||||
## Laboratorio di Concourse
|
||||
|
||||
Scopri come puoi eseguire un ambiente concourse localmente per fare i tuoi test in:
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
|
||||
Concourse viene fornito con cinque ruoli:
|
||||
|
||||
- _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.
|
||||
- _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.
|
||||
@@ -23,8 +23,8 @@ Nota che Concourse **raggruppa le pipeline all'interno dei Team**. Pertanto, gli
|
||||
|
||||
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`.
|
||||
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 _**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
|
||||
|
||||
@@ -34,16 +34,16 @@ Le variabili statiche possono essere specificate nei **passaggi delle attività*
|
||||
file: booklit/ci/unit.yml
|
||||
vars: { tag: 1.13 }
|
||||
```
|
||||
Or usando i seguenti `fly` **argomenti**:
|
||||
Oppure utilizzando i seguenti `fly` **argomenti**:
|
||||
|
||||
- `-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.
|
||||
- `-i` o `--instance-var` `NAME=VALUE` analizza `VALUE` come YAML e lo imposta come valore per la var di istanza `NAME`. Vedi [Grouping Pipelines](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.
|
||||
|
||||
#### Gestione delle Credenziali
|
||||
|
||||
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).\
|
||||
Ci sono diversi modi in cui un **Credential Manager 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:
|
||||
|
||||
- [Il gestore di credenziali Vault](https://concourse-ci.org/vault-credential-manager.html)
|
||||
@@ -52,9 +52,9 @@ Inoltre, Concourse supporta diversi gestori di credenziali:
|
||||
- [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)
|
||||
- [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)
|
||||
|
||||
> [!CAUTION]
|
||||
> 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.
|
||||
@@ -63,7 +63,7 @@ Inoltre, Concourse supporta diversi gestori di credenziali:
|
||||
|
||||
Per enumerare un ambiente concourse devi prima **raccogliere credenziali valide** o trovare un **token autenticato** probabilmente in un file di configurazione `.flyrc`.
|
||||
|
||||
#### Login e enumerazione dell'Utente Corrente
|
||||
#### Login e enumerazione dell'utente corrente
|
||||
|
||||
- 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]`
|
||||
@@ -92,7 +92,7 @@ Per enumerare un ambiente concourse devi prima **raccogliere credenziali valide*
|
||||
- `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**
|
||||
- Ottieni tutte le **var dichiarate nella config 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
|
||||
@@ -142,7 +142,7 @@ Con questi permessi potresti essere in grado di:
|
||||
|
||||
#### Creazione/Modifica della Pipeline
|
||||
|
||||
Se hai privilegi sufficienti (**ruolo di membro o superiore**) sarai in grado di **creare/modificare nuove pipeline.** Controlla questo esempio:
|
||||
Se hai privilegi sufficienti (**ruolo membro o superiore**) sarai in grado di **creare/modificare nuove pipeline.** Controlla questo esempio:
|
||||
```yaml
|
||||
jobs:
|
||||
- name: simple
|
||||
@@ -168,12 +168,12 @@ SUPER_SECRET: ((super.secret))
|
||||
```
|
||||
Con la **modifica/creazione** di un nuovo pipeline sarai in grado di:
|
||||
|
||||
- **Rubare** i **segreti** (facendo un echo o entrando nel container e eseguendo `env`)
|
||||
- **Evasione** al **nodo** (dandoti abbastanza privilegi - `privileged: true`)
|
||||
- **Rubare** i **segreti** (facendo l'echo o entrando nel container e eseguendo `env`)
|
||||
- **Evasione** verso il **nodo** (dandoti abbastanza privilegi - `privileged: true`)
|
||||
- Enumerare/Abusare dell'endpoint **cloud metadata** (dal pod e dal nodo)
|
||||
- **Eliminare** il pipeline creato
|
||||
|
||||
#### Esegui un Compito Personalizzato
|
||||
#### Esegui 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
|
||||
@@ -260,11 +260,11 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
cat /output
|
||||
```
|
||||
> [!WARNING]
|
||||
> 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
|
||||
> Come avrai notato, questo è solo un [**escape regolare di 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
|
||||
|
||||
#### Uscire verso il nodo da un contenitore Worker
|
||||
#### Escape al nodo da un contenitore Worker
|
||||
|
||||
Un escape regolare del release_agent con una modifica minore è sufficiente per questo:
|
||||
Un escape regolare di 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
|
||||
|
||||
@@ -291,7 +291,7 @@ sh -c "echo \$\$ > /tmp/cgrp/x/cgroup.procs"
|
||||
# Reads the output
|
||||
cat /output
|
||||
```
|
||||
#### Uscire verso il nodo dal contenitore Web
|
||||
#### Uscire dal nodo dal contenitore Web
|
||||
|
||||
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).
|
||||
|
||||
@@ -327,12 +327,12 @@ select * from refresh_token;
|
||||
select * from teams; #Change the permissions of the users in the teams
|
||||
select * from users;
|
||||
```
|
||||
#### Abusare del Servizio Garden - Non un vero Attacco
|
||||
#### Abusare del Servizio Garden - Non un vero attacco
|
||||
|
||||
> [!WARNING]
|
||||
> 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
|
||||
> 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.
|
||||
|
||||
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:
|
||||
Per impostazione predefinita, ogni worker di concourse eseguirà un [**Garden**](https://github.com/cloudfoundry/garden) servizio 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:
|
||||
|
||||
- È **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.
|
||||
@@ -348,7 +348,7 @@ 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
|
||||
Seccomp: disabled
|
||||
```
|
||||
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.
|
||||
Tuttavia, tecniche come **mounting** del 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]
|
||||
> 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**.
|
||||
@@ -387,7 +387,7 @@ wget -v -O- --post-data='{"id":"task2","path":"sh","args":["-cx","sleep 20000"],
|
||||
--header='Content-Type:application/json' \
|
||||
'http://127.0.0.1:7777/containers/ac793559-7f53-4efc-6591-0171a0391e53/processes'
|
||||
```
|
||||
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:
|
||||
Tuttavia, il server web controlla ogni pochi secondi i contenitori 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 contenitori inaspettati:
|
||||
```
|
||||
GET /containers HTTP/1.1.
|
||||
Host: 127.0.0.1:7777.
|
||||
|
||||
@@ -73,21 +73,21 @@ Un pipeline è composto da un elenco di [Jobs](https://concourse-ci.org/jobs.htm
|
||||
|
||||
### Steps
|
||||
|
||||
Possono essere utilizzati diversi tipi di passi:
|
||||
Possono essere utilizzati diversi tipi di passaggi:
|
||||
|
||||
- **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
|
||||
- il [`in_parallel` step](https://concourse-ci.org/in-parallel-step.html) esegue i passaggi in parallelo
|
||||
- il [`do` step](https://concourse-ci.org/do-step.html) esegue i passaggi in sequenza
|
||||
- il [`across` step modifier](https://concourse-ci.org/across-step.html#schema.across) esegue un passaggio 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 passaggio e ha successo anche se il passaggio fallisce
|
||||
|
||||
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.
|
||||
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 passaggi, Concourse creerà cinque container, uno per ogni passaggio.
|
||||
|
||||
Pertanto, è possibile indicare il tipo di container in cui ogni passo deve essere eseguito.
|
||||
Pertanto, è possibile indicare il tipo di container in cui ogni passaggio deve essere eseguito.
|
||||
|
||||
### Esempio di Pipeline Semplice
|
||||
```yaml
|
||||
@@ -136,7 +136,7 @@ Non è necessario attivare manualmente i lavori ogni volta che devi eseguirli, p
|
||||
- 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/)
|
||||
- Recupera o invia l'immagine più recente della tua app: [Registry-image resource](https://github.com/concourse/registry-image-resource/)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user