Abusing Github Actions
Last updated
Last updated
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)
In this page you will find:
A summary of all the impacts of an attacker managing to access a Github Action
Different ways to get access to an action:
Having permissions to create the action
Abusing pull request related triggers
Abusing other external access techniques
Pivoting from an already compromised repo
Finally, a section about post-exploitation techniques to abuse an action from inside (cause the mentioned impacts)
For an introduction about Github Actions check the basic information.
If you can execute arbitrary code in GitHub Actions within a repository, you may be able to:
Kraść sekrety zamontowane w pipeline i nadużywać uprawnień pipeline do uzyskania nieautoryzowanego dostępu do zewnętrznych platform, takich jak AWS i GCP.
Kompromentować wdrożenia i inne artefakty.
Jeśli pipeline wdraża lub przechowuje zasoby, możesz zmienić końcowy produkt, umożliwiając atak na łańcuch dostaw.
Wykonywać kod w niestandardowych workerach w celu nadużycia mocy obliczeniowej i przejścia do innych systemów.
Nadpisywać kod repozytorium, w zależności od uprawnień związanych z GITHUB_TOKEN
.
Ten "sekret" (pochodzący z ${{ secrets.GITHUB_TOKEN }}
i ${{ github.token }}
) jest przyznawany, gdy administrator włączy tę opcję:
Ten token jest tym samym, który aplikacja Github będzie używać, więc może uzyskać dostęp do tych samych punktów końcowych: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Github powinien wydać flow, który pozwala na dostęp między repozytoriami w GitHub, aby repozytorium mogło uzyskać dostęp do innych wewnętrznych repozytoriów za pomocą GITHUB_TOKEN
.
You can see the possible permissions of this token in: https://docs.github.com/en/actions/security-guides/automatic-token-authentication#permissions-for-the-github_token
Note that the token expires after the job has completed.
These tokens looks like this: ghs_veaxARUji7EXszBMbhkr4Nz2dYz0sqkeiur7
Some interesting things you can do with this token:
Zauważ, że w kilku przypadkach będziesz mógł znaleźć tokeny użytkowników githuba w zmiennych środowiskowych Github Actions lub w sekretach. Te tokeny mogą dać ci więcej uprawnień do repozytorium i organizacji.
Możliwe jest sprawdzenie uprawnień nadanych tokenowi Github w repozytoriach innych użytkowników sprawdzając logi akcji:
To byłby najłatwiejszy sposób na kompromitację akcji Github, ponieważ ten przypadek zakłada, że masz dostęp do utworzenia nowego repozytorium w organizacji lub masz uprawnienia do zapisu w repozytorium.
Jeśli jesteś w tym scenariuszu, możesz po prostu sprawdzić techniki po eksploatacji.
W przypadku, gdy członkowie organizacji mogą tworzyć nowe repozytoria i możesz wykonywać akcje github, możesz utworzyć nowe repozytorium i ukraść sekrety ustawione na poziomie organizacji.
Jeśli możesz utworzyć nową gałąź w repozytorium, które już zawiera skonfigurowaną akcję Github, możesz ją zmodyfikować, załadować zawartość, a następnie wykonać tę akcję z nowej gałęzi. W ten sposób możesz wyeksfiltrować sekrety na poziomie repozytorium i organizacji (ale musisz wiedzieć, jak się nazywają).
Możesz uczynić zmodyfikowaną akcję wykonalną ręcznie, gdy zostanie utworzony PR lub gdy zostanie przesłany jakiś kod (w zależności od tego, jak głośny chcesz być):
Istnieją różne wyzwalacze, które mogą pozwolić atakującemu na wykonanie akcji Github innego repozytorium. Jeśli te wyzwalane akcje są źle skonfigurowane, atakujący może być w stanie je skompromitować.
pull_request
Wyzwalacz workflow pull_request
wykona workflow za każdym razem, gdy otrzyma pull request z pewnymi wyjątkami: domyślnie, jeśli to pierwszy raz, gdy współpracujesz, niektórzy utrzymujący będą musieli zatwierdzić wykonanie workflow:
Ponieważ domyślne ograniczenie dotyczy pierwszych współpracowników, możesz przyczynić się do naprawy ważnego błędu/ortografii, a następnie wysłać inne PR-y, aby nadużyć swoich nowych uprawnień pull_request
.
Testowałem to i to nie działa: Inną opcją byłoby stworzenie konta o nazwie kogoś, kto przyczynił się do projektu i usunięcie jego konta.
Ponadto, domyślnie zapobiega uprawnieniom do zapisu i dostępowi do sekretów w docelowym repozytorium, jak wspomniano w dokumentacji:
Z wyjątkiem
GITHUB_TOKEN
, sekrety nie są przekazywane do runnera, gdy workflow jest wyzwalany z forkowanego repozytorium. `GITHUB_TOKEN ma uprawnienia tylko do odczytu w pull requestach z forkowanych repozytoriów.
Atakujący mógłby zmodyfikować definicję akcji Github, aby wykonać dowolne rzeczy i dodać dowolne akcje. Jednak nie będzie w stanie ukraść sekretów ani nadpisać repozytorium z powodu wspomnianych ograniczeń.
Tak, jeśli atakujący zmieni w PR akcję github, która zostanie wyzwolona, jego akcja Github będzie używana, a nie ta z repozytorium źródłowego!
Ponieważ atakujący kontroluje również kod, który jest wykonywany, nawet jeśli nie ma sekretów ani uprawnień do zapisu na GITHUB_TOKEN
, atakujący mógłby na przykład przesłać złośliwe artefakty.
pull_request_target
Wyzwalacz workflow pull_request_target
ma uprawnienia do zapisu w docelowym repozytorium i dostęp do sekretów (i nie prosi o pozwolenie).
Zauważ, że wyzwalacz workflow pull_request_target
działa w kontekście bazowym i nie w tym, który jest podany przez PR (aby nie wykonywać nieufnego kodu). Aby uzyskać więcej informacji na temat pull_request_target
, sprawdź dokumentację.
Ponadto, aby uzyskać więcej informacji na temat tego konkretnego niebezpiecznego użycia, sprawdź ten post na blogu githuba.
Może się wydawać, że ponieważ wykonywany workflow jest tym zdefiniowanym w bazie i nie w PR, jest bezpieczne używanie pull_request_target
, ale istnieje kilka przypadków, w których tak nie jest.
A ten będzie miał dostęp do sekretów.
workflow_run
Wyzwalacz workflow_run pozwala na uruchomienie workflow z innego, gdy jest ukończony
, zażądany
lub w trakcie
.
W tym przykładzie workflow jest skonfigurowany do uruchomienia po zakończeniu oddzielnego workflow "Uruchom testy":
Moreover, according to the docs: Workflow uruchomiony przez zdarzenie workflow_run
ma możliwość dostępu do sekretów i zapisywania tokenów, nawet jeśli poprzedni workflow nie miał.
Tego rodzaju workflow może być zaatakowany, jeśli zależy od workflow, który może być wyzwolony przez zewnętrznego użytkownika za pomocą pull_request
lub pull_request_target
. Kilka podatnych przykładów można znaleźć w tym blogu. Pierwszy z nich polega na tym, że workflow_run
wyzwolony workflow pobiera kod atakującego: ${{ github.event.pull_request.head.sha }}
Drugi polega na przekazywaniu artefaktu z nieufnego kodu do workflow workflow_run
i używaniu zawartości tego artefaktu w sposób, który czyni go podatnym na RCE.
workflow_call
TODO
TODO: Sprawdź, czy podczas wykonywania z pull_request używany/pobierany kod pochodzi z oryginału czy z forkowanego PR
Wspomnieliśmy o wszystkich sposobach, w jakie zewnętrzny atakujący mógłby sprawić, że workflow githuba zostanie wykonany, teraz przyjrzyjmy się, jak te wykonania, jeśli są źle skonfigurowane, mogą być wykorzystywane:
W przypadku pull_request
workflow będzie wykonywany w kontekście PR (więc wykona złośliwy kod PR), ale ktoś musi najpierw to autoryzować i będzie działać z pewnymi ograniczeniami.
W przypadku workflow używającego pull_request_target
lub workflow_run
, który zależy od workflow, który może być wyzwolony z pull_request_target
lub pull_request
, kod z oryginalnego repozytorium zostanie wykonany, więc atakujący nie może kontrolować wykonanego kodu.
Jednakże, jeśli akcja ma wyraźny checkout PR, który pobierze kod z PR (a nie z bazy), użyje kodu kontrolowanego przez atakującego. Na przykład (sprawdź linię 12, gdzie kod PR jest pobierany):
Potencjalnie nieufny kod jest uruchamiany podczas npm install
lub npm build
, ponieważ skrypty budujące i odwołane pakiety są kontrolowane przez autora PR.
Dork githuba do wyszukiwania podatnych akcji to: event.pull_request pull_request_target extension:yml
, jednak istnieją różne sposoby konfigurowania zadań, aby były wykonywane bezpiecznie, nawet jeśli akcja jest skonfigurowana niebezpiecznie (jak używanie warunków dotyczących tego, kto jest aktorem generującym PR).
Zauważ, że istnieją pewne konteksty githuba, których wartości są kontrolowane przez użytkownika tworzącego PR. Jeśli akcja githuba używa tych danych do wykonania czegokolwiek, może to prowadzić do wykonania dowolnego kodu:
Gh Actions - Context Script InjectionsZ dokumentacji: Możesz udostępnić zmienną środowiskową dla wszystkich kolejnych kroków w zadaniu workflow, definiując lub aktualizując zmienną środowiskową i zapisując ją w pliku środowiskowym GITHUB_ENV
.
Jeśli atakujący mógłby wstrzyknąć dowolną wartość do tej zmiennej env, mógłby wstrzyknąć zmienne środowiskowe, które mogłyby wykonać kod w kolejnych krokach, takie jak LD_PRELOAD lub NODE_OPTIONS.
Na przykład (to i to), wyobraź sobie workflow, który ufa przesłanemu artefaktowi, aby przechować jego zawartość w zmiennej środowiskowej GITHUB_ENV
. Atakujący mógłby przesłać coś takiego, aby to skompromitować:
Jak wspomniano w tym poście na blogu, ta Akcja Githuba pozwala na dostęp do artefaktów z różnych workflow, a nawet repozytoriów.
Problem polega na tym, że jeśli parametr path
nie jest ustawiony, artefakt jest wyodrębniany w bieżącym katalogu i może nadpisywać pliki, które mogą być później używane lub nawet wykonywane w workflow. Dlatego, jeśli artefakt jest podatny, atakujący mógłby to wykorzystać, aby skompromitować inne workflow ufające artefaktowi.
Przykład podatnego workflow:
To można zaatakować za pomocą tego przepływu pracy:
Jeśli konto zmieni swoją nazwę, inny użytkownik może zarejestrować konto o tej samej nazwie po pewnym czasie. Jeśli repozytorium miało mniej niż 100 gwiazdek przed zmianą nazwy, Github pozwoli nowemu zarejestrowanemu użytkownikowi o tej samej nazwie na utworzenie repozytorium o tej samej nazwie co usunięte.
Jeśli akcja korzysta z repozytorium z nieistniejącego konta, nadal istnieje możliwość, że atakujący mógłby utworzyć to konto i skompromitować akcję.
Jeśli inne repozytoria korzystały z zależności z repozytoriów tego użytkownika, atakujący będzie mógł je przejąć. Oto bardziej szczegółowe wyjaśnienie: https://blog.nietaanraken.nl/posts/gitub-popular-repository-namespace-retirement-bypass/
W tej sekcji omówimy techniki, które pozwolą na przełączenie z jednego repozytorium do drugiego, zakładając, że mamy jakiś rodzaj dostępu do pierwszego (sprawdź poprzednią sekcję).
Pamięć podręczna jest utrzymywana między uruchomieniami workflow w tej samej gałęzi. Oznacza to, że jeśli atakujący skompromituje pakiet, który następnie jest przechowywany w pamięci podręcznej i pobierany oraz wykonywany przez bardziej uprzywilejowany workflow, będzie mógł również skompromitować ten workflow.
GH Actions - Cache PoisoningWorkflow mogą korzystać z artefaktów z innych workflow, a nawet repozytoriów. Jeśli atakujący zdoła skompromitować Github Action, która przesyła artefakt, który jest później używany przez inny workflow, może skompromitować inne workflow:
Gh Actions - Artifact PoisoningSprawdź następujące strony:
AWS - Federation AbuseGCP - Federation AbuseJeśli wstrzykujesz zawartość do skryptu, warto wiedzieć, jak możesz uzyskać dostęp do sekretów:
Jeśli sekret lub token jest ustawiony jako zmienna środowiskowa, można go bezpośrednio uzyskać przez środowisko, używając printenv
.
Jeśli sekret jest używany bezpośrednio w wyrażeniu, wygenerowany skrypt powłoki jest przechowywany na dysku i jest dostępny.
cat /home/runner/work/_temp/*
Dla niestandardowej akcji ryzyko może się różnić w zależności od tego, jak program używa uzyskanego sekretu z argumentu:
Sposobem na znalezienie, które Github Actions są wykonywane w infrastrukturze nie-Github jest wyszukiwanie runs-on: self-hosted
w konfiguracji yaml akcji Github.
Samodzielnie hostowane runnery mogą mieć dostęp do dodatkowych wrażliwych informacji, do innych systemów sieciowych (wrażliwe punkty końcowe w sieci? usługa metadanych?) lub, nawet jeśli są izolowane i zniszczone, więcej niż jedna akcja może być uruchamiana jednocześnie i złośliwa mogłaby ukraść sekrety innej.
W samodzielnie hostowanych runnerach możliwe jest również uzyskanie sekretów z procesu _Runner.Listener_** który będzie zawierał wszystkie sekrety workflow w dowolnym kroku, zrzucając jego pamięć:
Sprawdź ten post, aby uzyskać więcej informacji.
Możliwe jest tworzenie akcji Github, które budują i przechowują obraz Docker wewnątrz Github. Przykład można znaleźć w następującym rozwijanym:
Learn & practice AWS Hacking:HackTricks Training AWS Red Team Expert (ARTE) Learn & practice GCP Hacking: HackTricks Training GCP Red Team Expert (GRTE)