Abusing Github Actions
Basic Information
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)
Impacts Summary
For an introduction about Github Actions check the basic information.
In case you can execute arbitrary Github actions/inject code in a repository, you could be able to:
Kraść sekrety z tego repozytorium/organizacji.
If you can only inject, you can steal whatever is already present in the workflow.
Abuse uprawnień repozytorium do uzyskania dostępu do innych platform, takich jak AWS i GCP.
Wykonywać kod w niestandardowych pracownikach (jeśli używane są niestandardowe pracownicy) i próbować pivotować stamtąd.
Nadpisywać kod repozytorium.
This depends on the privileges of the
GITHUB_TOKEN
(if any).Kompromitować wdrożenia i inne artefakty.
If the code is deploying or storing something you could modify that and obtain some further access.
GITHUB_TOKEN
This "sekret" (coming from ${{ secrets.GITHUB_TOKEN }}
and ${{ github.token }}
) is given when the admin enables this option:
This token is the same one a Github Application will use, so it can access the same endpoints: https://docs.github.com/en/rest/overview/endpoints-available-for-github-apps
Github should release a flow that allows cross-repository access within GitHub, so a repo can access other internal repos using the 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:
Dozwolone Wykonanie
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 poeksploatacyjne.
Wykonanie z Utworzenia Repozytorium
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.
Wykonanie z Nowej Gałęzi
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 PR zostanie utworzony lub gdy jakikolwiek kod zostanie przesłany (w zależności od tego, jak głośny chcesz być):
Forkowane Wykonanie
Istnieją różne wyzwalacze, które mogą pozwolić atakującemu na wykonanie Github Action z innego repozytorium. Jeśli te wyzwalane akcje są źle skonfigurowane, atakujący może być w stanie je skompromitować.
pull_request
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 jest 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/typówki, a następnie wysłać inne PR-y, aby nadużyć swoich nowych uprawnień pull_request
.
Testowałem to i nie działa: Inną opcją byłoby stworzenie konta o nazwie kogoś, kto przyczynił się do projektu i usunął swoje konto.
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ę Github Action, 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 Github Action będzie używana, a nie ta z repozytorium źródłowego!
Ponieważ atakujący również kontroluje 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
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
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 niezaufanego kodu do workflow workflow_run
i używaniu zawartości tego artefaktu w sposób, który czyni go podatnym na RCE.
workflow_call
workflow_call
TODO
TODO: Sprawdź, czy podczas wykonywania z pull_request używany/pobierany kod pochodzi z oryginału czy z forkowanego PR
Wykorzystywanie Wykonania Forkowanego
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:
Wykonanie niezaufanego checkoutu
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 niezaufany 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).
Wstrzyknięcia Skryptów w Kontekście
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 InjectionsWstrzyknięcie Skryptu GITHUB_ENV
Z 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ć:
Podatne Akcje Githuba Trzeciej Strony
Jak wspomniano w tym poście na blogu, ta Akcja Githuba umożliwia 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:
Inny dostęp zewnętrzny
Przejęcie usuniętego repozytorium przestrzeni nazw
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/
Przełączanie repozytoriów
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ę).
Zatrucie pamięci podręcznej
Pamięć podręczna jest utrzymywana między uruchomieniami workflow w tej samej gałęzi. Oznacza to, że jeśli atakujący skomprumituje 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ż skomprumitować ten workflow.
GH Actions - Cache PoisoningZatrucie artefaktów
Workflow mogą korzystać z artefaktów z innych workflow, a nawet repozytoriów. Jeśli atakujący zdoła skomprumotować Github Action, która przesyła artefakt, który jest później używany przez inny workflow, może skomprumotować inne workflow:
Gh Actions - Artifact PoisoningPo eksploatacji z akcji
Uzyskiwanie dostępu do AWS i GCP za pomocą OIDC
Sprawdź następujące strony:
AWS - Federation AbuseGCP - Federation AbuseUzyskiwanie dostępu do sekretów
Jeśli wstrzykujesz zawartość do skryptu, warto wiedzieć, jak 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:
Wykorzystywanie samodzielnie hostowanych runnerów
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 (vulnerable endpoints in the network? metadata service?) 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 na każdym etapie, zrzucając jego pamięć:
Sprawdź ten post, aby uzyskać więcej informacji.
Rejestr obrazów Docker w Github
Możliwe jest tworzenie akcji Github, które budują i przechowują obraz Docker w Github. Przykład można znaleźć w następującym rozwijanym:
Last updated