
Wprowadzenie do problemu / definicja
Kampania oznaczona jako Gheist pokazuje, jak groźne mogą być skradzione tokeny GitHub z uprawnieniami zapisu do repozytoriów. Atakujący wykorzystują legalnie działające mechanizmy platformy do dodawania złośliwych workflow GitHub Actions, których celem jest ujawnienie sekretów projektu w logach wykonania.
Najbardziej zagrożone są prywatne repozytoria oraz środowiska GitHub Enterprise, gdzie ochrona przed podejrzanymi uruchomieniami workflow nie zawsze zapewnia taki sam poziom zabezpieczeń jak w publicznych projektach. To sprawia, że pojedynczy przejęty token może stać się punktem wejścia do szerszej kompromitacji organizacji.
W skrócie
Badacze opisali zautomatyzowaną operację, w której przejęte tokeny GitHub służą do tworzenia nowych gałęzi i osadzania w nich pliku workflow uruchamianego przez GitHub Actions. Workflow wypisuje dostępne sekrety oraz zmienne środowiskowe do logów, a następnie operatorzy kampanii pobierają te logi przez API i usuwają ślady aktywności.
- atak wykorzystuje skradzione tokeny z prawem zapisu do repozytorium,
- złośliwe workflow uruchamiane są z nowo tworzonych gałęzi,
- sekrety trafiają do logów w postaci utrudniającej maskowanie,
- po eksfiltracji logi i uruchomienia workflow są szybko usuwane,
- zagrożenie obejmuje także środowiska enterprise i self-hosted runners.
Kontekst / historia
Kampania była obserwowana od połowy września 2026 roku. Jej nazwa pochodzi od identyfikatora user-agent używanego przez narzędzie atakujących podczas komunikacji z API GitHub.
Z ustaleń badaczy wynika, że operatorzy wykorzystywali tokeny pochodzące między innymi z logów infostealerów oraz z wcześniejszych incydentów w łańcuchu dostaw. Oznacza to, że atak nie musi zaczynać się od włamania do samego GitHub, lecz często jest efektem wtórnego użycia już skradzionych poświadczeń deweloperskich.
Ofiarami były zarówno prywatne projekty pojedynczych użytkowników, jak i repozytoria należące do organizacji korporacyjnych. W części przypadków po kompromitacji repozytoriów obserwowano dalszą aktywność w środowiskach chmurowych, co sugeruje, że wyciek sekretów z pipeline’ów CI/CD bywa jedynie etapem pośrednim prowadzącym do kolejnych naruszeń.
Analiza techniczna
Mechanizm działania kampanii jest prosty, ale wyjątkowo skuteczny. Jeśli przejęty token posiada uprawnienia zapisu, narzędzie atakującego tworzy nową gałąź o schemacie nazewniczym ci-sync-xxxxxx, a następnie dodaje do niej plik .github/workflows/sync-check.yml. Commit zwykle otrzymuje komunikat ci: sync config, a samo wypchnięcie zmian uruchamia workflow.
Zadaniem złośliwego workflow jest wydobycie wszystkiego, do czego proces CI/CD ma dostęp. Mogą to być sekrety repozytorium, sekrety organizacyjne, zmienne środowiskowe joba, a w niektórych wariantach również sekrety przypisane do środowisk deploymentowych.
Istotnym elementem techniki jest obejście standardowego maskowania sekretów w logach. Zamiast wypisywać je w oryginalnej postaci, workflow koduje wartości w base32. Dzięki temu zakodowane dane mogą nie zostać rozpoznane przez mechanizmy ochronne jako wrażliwe i zostają zapisane w logach w sposób czytelny dla atakującego.
Następnie operatorzy pobierają logi wykonania przez API GitHub i usuwają uruchomienie workflow w krótkim czasie po zakończeniu zadania. Takie działanie utrudnia analizę incydentu, ale nie zmniejsza skali szkód, ponieważ sekrety mogły już zostać przejęte.
W niektórych wariantach odnotowano również próby ataku na self-hosted runners. W takim scenariuszu złośliwy kod może przeszukiwać hosta w poszukiwaniu dodatkowych poświadczeń, kluczy prywatnych, tokenów środowiskowych, danych chmurowych oraz lokalnych artefaktów konfiguracyjnych. To rozszerza zakres zagrożenia z poziomu repozytorium na cały serwer wykonujący zadania CI/CD.
Dodatkowymi wskaźnikami kompromitacji mogą być:
- workflow uruchamiane z gałęzi
ci-sync-*, - szybkie usuwanie runów po ich zakończeniu,
- operacje wykonywane przez user-agent
gheist, - nietypowe użycie federacji OIDC do uzyskiwania tymczasowych poświadczeń chmurowych.
Konsekwencje / ryzyko
Ryzyko związane z kampanią Gheist jest wysokie, ponieważ incydent nie ogranicza się do samego kodu źródłowego. Ujawnione sekrety mogą otworzyć drogę do kompromitacji usług chmurowych, systemów wdrożeniowych, rejestrów artefaktów oraz środowisk produkcyjnych.
- wyciek kluczy API i tokenów dostępowych,
- przejęcie kont i ról w chmurze,
- kompromitacja środowisk produkcyjnych,
- dalszy ruch boczny w organizacji,
- naruszenie łańcucha dostaw oprogramowania.
Szczególnie narażone są organizacje przechowujące w GitHub Actions sekrety o szerokim zakresie uprawnień oraz korzystające z self-hosted runners bez odpowiedniej izolacji. Dodatkowym problemem jest fakt, że eksfiltracja odbywa się z użyciem natywnych funkcji platformy, dlatego tradycyjne monitorowanie ruchu sieciowego może nie wykryć takiego scenariusza w odpowiednim czasie.
Rekomendacje
Organizacje korzystające z GitHub powinny potraktować ten scenariusz jako incydent wysokiego priorytetu i połączyć działania detekcyjne z twardymi środkami prewencyjnymi.
W pierwszej kolejności warto przeprowadzić przeszukanie repozytoriów pod kątem charakterystycznych artefaktów kampanii:
- gałęzi zgodnych z wzorcem
ci-sync-[0-9a-z]{6}, - pliku
.github/workflows/sync-check.yml, - commitów z komunikatem
ci: sync config, - śladów usuniętych runów workflow wykonywanych krótko po zakończeniu.
Następnie należy przeanalizować logi audytowe GitHub oraz logi środowisk chmurowych, zwłaszcza pod kątem nietypowych uruchomień workflow, użycia user-agent gheist oraz operacji OIDC powiązanych z tymczasowymi gałęziami.
Jeżeli istnieje podejrzenie kompromitacji, konieczne są natychmiastowe działania:
- unieważnienie tokenów używanych do pushowania zmian,
- rotacja wszystkich sekretów dostępnych z poziomu zagrożonego repozytorium,
- weryfikacja stacji roboczych właścicieli tokenów pod kątem infostealerów,
- traktowanie self-hosted runnera jako potencjalnie przejętego i jego pełna rekonstrukcja.
Długoterminowo warto wdrożyć dobre praktyki ograniczające skutki podobnych incydentów:
- zastępowanie długowiecznych tokenów rozwiązaniami krótkoterminowymi,
- stosowanie minimalnych uprawnień dla tokenów i sekretów,
- ograniczenie zaufania OIDC do chronionych gałęzi i zatwierdzonych środowisk,
- wymuszanie zatwierdzeń dla środowisk zawierających sekrety produkcyjne,
- izolowanie self-hosted runners i uruchamianie ich jako zasobów efemerycznych,
- ograniczenie dostępu runnerów do metadanych chmurowych i zasobów lokalnych.
Podsumowanie
Gheist jest przykładem dojrzałej kampanii wymierzonej w tożsamości deweloperskie oraz zaufane mechanizmy CI/CD. Kluczowym elementem ataku nie jest klasyczny exploit, lecz nadużycie legalnych uprawnień przejętych tokenów GitHub do uruchomienia workflow ujawniających sekrety w logach.
Dla organizacji to wyraźny sygnał, że tokeny GitHub należy traktować jak poświadczenia uprzywilejowane. Skuteczna obrona wymaga ścisłej segmentacji sekretów, ograniczania uprawnień, monitorowania GitHub Actions i izolacji środowisk wykonawczych, ponieważ bezpieczeństwo pipeline’ów DevSecOps jest dziś bezpośrednio powiązane z bezpieczeństwem całej infrastruktury.