Zatrute pakiety RubyGems i moduły Go atakują pipeline’y CI/CD i wykradają poświadczenia - Security Bez Tabu

Zatrute pakiety RubyGems i moduły Go atakują pipeline’y CI/CD i wykradają poświadczenia

Cybersecurity news

Wprowadzenie do problemu / definicja

Ataki na łańcuch dostaw oprogramowania coraz częściej obejmują nie tylko stacje robocze programistów, ale również środowiska automatyzacji budowania i wdrażania. Najnowsza kampania pokazuje, że złośliwe pakiety publikowane w ekosystemach RubyGems i Go mogą służyć jako nośnik do kradzieży sekretów, manipulowania procesem buildów oraz utrwalania dostępu do przejętych hostów.

To szczególnie groźny scenariusz dla organizacji korzystających z CI/CD, GitHub Actions oraz środowisk DevSecOps, gdzie pojedyncza zależność może uzyskać dostęp do tokenów, kluczy i konfiguracji używanych w całym cyklu dostarczania oprogramowania.

W skrócie

  • Kampania została powiązana z kontem BufferZoneCorp publikującym złośliwe biblioteki podszywające się pod znane pakiety Ruby i Go.
  • Część pakietów działała jako sleeper packages, czyli pozornie niegroźne komponenty wykorzystywane na dalszym etapie ataku.
  • Złośliwe gemy Ruby wykradały sekrety już podczas instalacji.
  • Moduły Go ingerowały w środowiska GitHub Actions, podmieniały mechanizmy uruchamiania narzędzi i mogły zapewniać trwały dostęp przez SSH.
  • Nawet jeśli pakiety zostały już usunięte z rejestrów, samo ich pobranie mogło oznaczać incydent bezpieczeństwa.

Kontekst / historia

Ataki typu software supply chain z wykorzystaniem publicznych rejestrów pakietów nie są nowym zjawiskiem, jednak obserwowany poziom ich dojrzałości operacyjnej stale rośnie. Wcześniej dominowały kampanie oparte na typosquattingu, dependency confusion lub prostych bibliotekach kradnących zmienne środowiskowe.

W tym przypadku atakujący zastosowali bardziej zaawansowany model działania. Pakiety imitowały rozpoznawalne nazwy bibliotek używanych w codziennej pracy programistów i administratorów, a kampania była rozproszona pomiędzy dwa popularne ekosystemy: Ruby oraz Go. To zwiększało szansę na skuteczne trafienie zarówno w aplikacje backendowe, jak i w narzędzia infrastrukturalne oraz komponenty wykonywane automatycznie przez pipeline’y.

W praktyce oznacza to przejście od prostego wykradania danych do prób przejmowania kontroli nad procesem wytwarzania oprogramowania. To właśnie dlatego środowiska CI/CD stają się dziś jednym z najważniejszych celów nowoczesnych operacji supply chain.

Analiza techniczna

W przypadku złośliwych gemów Ruby kluczowym momentem była sama instalacja pakietu. Ładunek uruchamiał się jeszcze przed uruchomieniem aplikacji i wyszukiwał dane wrażliwe obecne na hostach deweloperskich lub runnerach CI. Celem były między innymi zmienne środowiskowe, klucze SSH, sekrety AWS, pliki konfiguracyjne takie jak .npmrc i .netrc, ustawienia GitHub CLI oraz poświadczenia RubyGems.

Po zebraniu informacji następowała ich eksfiltracja do infrastruktury kontrolowanej przez operatora kampanii. Taki model ataku jest wyjątkowo niebezpieczny, ponieważ nie wymaga uruchomienia aplikacji produkcyjnej. Wystarczy samo pobranie lub instalacja zależności, aby aktywować mechanizm kradzieży.

Złośliwe moduły Go działały bardziej wieloetapowo. Według opublikowanych analiz nie wszystkie zawierały identyczny payload, ale razem tworzyły funkcjonalny zestaw narzędzi do naruszenia integralności pipeline’u. Jednym z najgroźniejszych elementów była ingerencja w środowisko GitHub Actions. Moduł wykrywał mechanizmy związane z workflow, ustawiał zmienne proxy i zapisywał fałszywy wrapper dla polecenia go w katalogu cache.

Następnie atakujący doprowadzał do zmiany ścieżki wykonywania, aby podstawiony wrapper był uruchamiany przed prawdziwym binarium. Dzięki temu możliwe było przechwytywanie lub modyfikowanie kolejnych wywołań narzędzia go, przy jednoczesnym przekazaniu sterowania do legalnego pliku wykonywalnego. Taka technika utrudnia wykrycie, ponieważ build może zakończyć się pozornie prawidłowo.

Dodatkowo część modułów była zdolna do utrwalania dostępu przez dopisanie zakodowanego na stałe klucza publicznego do pliku ~/.ssh/authorized_keys. To klasyczny mechanizm persistence, umożliwiający powrót na przejęty host bez potrzeby ponownego używania skradzionych haseł lub tokenów.

Na uwagę zasługuje także użycie sleeper packages. Takie pakiety mogą przez dłuższy czas nie wykazywać jednoznacznie złośliwego zachowania, a ich właściwa funkcja ujawnia się dopiero w dalszej fazie kampanii. To znacząco utrudnia wykrywanie oparte wyłącznie na reputacji pakietu, nazwie lub szybkiej analizie metadanych.

Konsekwencje / ryzyko

Skala ryzyka wynikającego z tej kampanii jest wysoka, ponieważ zagrożone są jednocześnie trzy kluczowe obszary: poufność sekretów, integralność procesu buildów oraz kontrola nad hostami wykonawczymi.

Wyciek zmiennych środowiskowych i plików konfiguracyjnych może prowadzić do przejęcia kont chmurowych, repozytoriów kodu, rejestrów pakietów, systemów CI i innych usług zintegrowanych z cyklem wytwórczym. Manipulacja workflow oraz podmiana wrapperów binarnych tworzy z kolei ryzyko cichego skażenia artefaktów, wstrzyknięcia dodatkowego kodu lub naruszenia integralności całego procesu release management.

Najpoważniejszy scenariusz obejmuje trwałą kompromitację runnera, serwera buildowego lub stacji deweloperskiej. Jeśli na hoście pojawi się nieautoryzowany wpis w authorized_keys, incydent nie kończy się na jednorazowej eksfiltracji sekretów, lecz może przerodzić się w długotrwały dostęp atakującego i dalszy ruch boczny w infrastrukturze.

W organizacjach korzystających z self-hosted runnerów skutki mogą być jeszcze poważniejsze, ponieważ naruszenie takiego środowiska bywa trudniejsze do zauważenia niż kompromitacja efemerycznych instancji uruchamianych jednorazowo.

Rekomendacje

Organizacje, które mogły pobrać wskazane pakiety, powinny traktować sprawę jako potencjalny incydent bezpieczeństwa. Sama eliminacja podejrzanej zależności nie wystarczy, jeśli doszło już do kradzieży danych uwierzytelniających lub utrwalenia dostępu.

  • Zweryfikować, czy podejrzane pakiety występowały w plikach Gemfile, gemspec, go.mod, cache zależności, artefaktach buildów i logach pipeline’ów.
  • Usunąć złośliwe komponenty z projektów oraz środowisk wykonawczych.
  • Przeanalizować logi pod kątem nietypowych połączeń wychodzących HTTPS oraz dostępu do wrażliwych plików podczas instalacji pakietów.
  • Przeprowadzić pełną rotację narażonych sekretów, w tym kluczy SSH, tokenów GitHub, poświadczeń AWS i danych do rejestrów pakietów.
  • Skontrolować plik ~/.ssh/authorized_keys na hostach deweloperskich, runnerach i serwerach buildowych pod kątem nieautoryzowanych wpisów.
  • Ograniczyć zakres sekretów dostępnych w jobach CI zgodnie z zasadą najmniejszych uprawnień.
  • Stosować efemeryczne runnery wszędzie tam, gdzie jest to możliwe.
  • Wymuszać pinowanie wersji zależności i przegląd nowych pakietów przed dopuszczeniem ich do buildów.
  • Monitorować zmiany w PATH, pojawianie się wrapperów narzędzi w katalogach cache oraz modyfikacje plików SSH.
  • Blokować nieautoryzowane połączenia wychodzące z pipeline’ów i segmentować środowiska build od produkcji.

Warto również wdrożyć mechanizmy wykrywania anomalii w procesie budowania, obejmujące nietypowe operacje na konfiguracjach, tworzenie dodatkowych binariów pomocniczych i odwołania do rzadko obserwowanych domen lub webhooków.

Podsumowanie

Opisana kampania pokazuje, że nowoczesne ataki na łańcuch dostaw oprogramowania są projektowane z myślą o realnych workflow deweloperskich i środowiskach CI/CD. Złośliwa zależność nie musi już jedynie kraść pojedynczych zmiennych środowiskowych — może ingerować w pipeline, przejmować wykonanie narzędzi, utrwalać dostęp do hosta i wpływać na integralność finalnych artefaktów.

Dla zespołów bezpieczeństwa to wyraźny sygnał, że ochrona rejestrów zależności, runnerów CI oraz procesów budowania powinna być traktowana jako kluczowy element bezpieczeństwa całego cyklu życia oprogramowania.

Źródła

  1. Poisoned Ruby Gems and Go Modules Exploit CI Pipelines for Credential Theft — https://thehackernews.com/2026/05/poisoned-ruby-gems-and-go-modules.html
  2. Socket Ecosystem Support — https://docs.socket.dev/docs/language-support
  3. Introducing Ruby Support in Socket — https://socket.dev/blog/introducing-ruby
  4. Go Support Is Now Generally Available — https://socket.dev/blog/go-support-is-now-generally-available